Ignore:
Timestamp:
Nov 26, 2002, 10:24:54 PM (23 years ago)
Author:
bird
Message:

Import of RELENG_4_7_0_RELEASE

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/FREEBSD/src/kmk/util.c

    r10 r24  
    11/*
    2  * Copyright (c) 2002 Juli Mallett.  All rights reserved.
    3  * Copyright (c) 1988, 1989, 1990, 1993
    4  *      The Regents of the University of California.  All rights reserved.
    5  * Copyright (c) 1989 by Berkeley Softworks
    6  * All rights reserved.
     2 * Missing stuff from OS's
     3 */
     4
     5#ifndef lint
     6static char rcsid[] = "$FreeBSD: src/usr.bin/make/util.c,v 1.5.2.2 2001/02/13 03:13:58 will Exp $";
     7#endif
     8
     9#include <stdio.h>
     10#include <errno.h>
     11#include "make.h"
     12
     13#if !__STDC__
     14# ifndef const
     15#  define const
     16# endif
     17#endif
     18
     19#ifdef sun
     20extern int errno, sys_nerr;
     21extern char *sys_errlist[];
     22
     23char *
     24strerror(e)
     25    int e;
     26{
     27    static char buf[100];
     28    if (e < 0 || e >= sys_nerr) {
     29        sprintf(buf, "Unknown error %d", e);
     30        return buf;
     31    }
     32    else
     33        return sys_errlist[e];
     34}
     35#endif
     36
     37#ifdef ultrix
     38#include <string.h>
     39
     40/* strdup
    741 *
    8  * This code is derived from software contributed to Berkeley by
    9  * Adam de Boor.
    10  *
    11  * Redistribution and use in source and binary forms, with or without
    12  * modification, are permitted provided that the following conditions
    13  * are met:
    14  * 1. Redistributions of source code must retain the above copyright
    15  *    notice, this list of conditions and the following disclaimer.
    16  * 2. Redistributions in binary form must reproduce the above copyright
    17  *    notice, this list of conditions and the following disclaimer in the
    18  *    documentation and/or other materials provided with the distribution.
    19  * 3. All advertising materials mentioning features or use of this software
    20  *    must display the following acknowledgement:
    21  *      This product includes software developed by the University of
    22  *      California, Berkeley and its contributors.
    23  * 4. Neither the name of the University nor the names of its contributors
    24  *    may be used to endorse or promote products derived from this software
    25  *    without specific prior written permission.
    26  *
    27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    37  * SUCH DAMAGE.
    38  *
    39  * @(#)main.c      8.3 (Berkeley) 3/19/94
    40  */
    41 
    42 #include <sys/cdefs.h>
    43 __FBSDID("$FreeBSD: src/usr.bin/make/util.c,v 1.12 2002/10/10 19:27:48 jmallett Exp $");
    44 
    45 /*-
    46  * util.c --
    47  *      General utilitarian routines for make(1).
    48  */
    49 
    50 #include <sys/types.h>
    51 #include <sys/stat.h>
    52 #include <err.h>
    53 #include <stdlib.h>
    54 #include <errno.h>
    55 #include <fcntl.h>
    56 #include <stdio.h>
    57 #include <sysexits.h>
    58 #include <stdarg.h>
    59 #include <unistd.h>
    60 
    61 #include "make.h"
    62 #include "hash.h"
    63 #include "dir.h"
    64 #include "job.h"
    65 #include "pathnames.h"
    66 
    67 /*-
    68  * Debug --
    69  *      Print a debugging message given its format.
    70  *
    71  * Results:
    72  *      None.
    73  *
    74  * Side Effects:
    75  *      The message is printed.
    76  */
    77 /* VARARGS */
    78 void
    79 Debug(const char *fmt, ...)
    80 {
    81         va_list ap;
    82 
    83         va_start(ap, fmt);
    84         (void)vfprintf(stderr, fmt, ap);
    85         va_end(ap);
    86         (void)fflush(stderr);
    87 }
    88 
    89 /*-
    90  * Error --
    91  *      Print an error message given its format.
    92  *
    93  * Results:
    94  *      None.
    95  *
    96  * Side Effects:
    97  *      The message is printed.
    98  */
    99 /* VARARGS */
    100 void
    101 Error(const char *fmt, ...)
    102 {
    103         va_list ap;
    104 
    105         va_start(ap, fmt);
    106         (void)vfprintf(stderr, fmt, ap);
    107         va_end(ap);
    108         (void)fprintf(stderr, "\n");
    109         (void)fflush(stderr);
    110 }
    111 
    112 /*-
    113  * Fatal --
    114  *      Produce a Fatal error message. If jobs are running, waits for them
    115  *      to finish.
    116  *
    117  * Results:
    118  *      None
    119  *
    120  * Side Effects:
    121  *      The program exits
    122  */
    123 /* VARARGS */
    124 void
    125 Fatal(const char *fmt, ...)
    126 {
    127         va_list ap;
    128 
    129         va_start(ap, fmt);
    130         if (jobsRunning)
    131                 Job_Wait();
    132 
    133         (void)vfprintf(stderr, fmt, ap);
    134         va_end(ap);
    135         (void)fprintf(stderr, "\n");
    136         (void)fflush(stderr);
    137 
    138         if (DEBUG(GRAPH2))
    139                 Targ_PrintGraph(2);
    140         exit(2);                /* Not 1 so -q can distinguish error */
    141 }
    142 
    143 /*
    144  * Punt --
    145  *      Major exception once jobs are being created. Kills all jobs, prints
    146  *      a message and exits.
    147  *
    148  * Results:
    149  *      None
    150  *
    151  * Side Effects:
    152  *      All children are killed indiscriminately and the program Lib_Exits
    153  */
    154 /* VARARGS */
    155 void
    156 Punt(const char *fmt, ...)
    157 {
    158         va_list ap;
    159 
    160         va_start(ap, fmt);
    161         (void)fprintf(stderr, "make: ");
    162         (void)vfprintf(stderr, fmt, ap);
    163         va_end(ap);
    164         (void)fprintf(stderr, "\n");
    165         (void)fflush(stderr);
    166 
    167         DieHorribly();
    168 }
    169 
    170 /*-
    171  * DieHorribly --
    172  *      Exit without giving a message.
    173  *
    174  * Results:
    175  *      None
    176  *
    177  * Side Effects:
    178  *      A big one...
    179  */
    180 void
    181 DieHorribly(void)
    182 {
    183         if (jobsRunning)
    184                 Job_AbortAll();
    185         if (DEBUG(GRAPH2))
    186                 Targ_PrintGraph(2);
    187         exit(2);                /* Not 1, so -q can distinguish error */
    188 }
    189 
    190 /*
    191  * Finish --
    192  *      Called when aborting due to errors in child shell to signal
    193  *      abnormal exit, with the number of errors encountered in Make_Make.
    194  *
    195  * Results:
    196  *      None
    197  *
    198  * Side Effects:
    199  *      The program exits
    200  */
    201 void
    202 Finish(int errors)
    203 {
    204         Fatal("%d error%s", errors, errors == 1 ? "" : "s");
    205 }
    206 
    207 /*
    208  * emalloc --
    209  *      malloc, but die on error.
    210  */
    211 void *
    212 emalloc(size_t len)
    213 {
    214         void *p;
    215 
    216         if ((p = malloc(len)) == NULL)
    217                 enomem();
    218         return(p);
    219 }
    220 
    221 /*
    222  * estrdup --
    223  *      strdup, but die on error.
     42 * Make a duplicate of a string.
     43 * For systems which lack this function.
    22444 */
    22545char *
    226 estrdup(const char *str)
    227 {
    228         char *p;
    229 
    230         if ((p = strdup(str)) == NULL)
    231                 enomem();
    232         return(p);
    233 }
    234 
    235 /*
    236  * erealloc --
    237  *      realloc, but die on error.
     46strdup(str)
     47    const char *str;
     48{
     49    size_t len;
     50
     51    if (str == NULL)
     52        return NULL;
     53    len = strlen(str) + 1;
     54    if ((p = malloc(len)) == NULL)
     55        return NULL;
     56
     57    return memcpy(p, str, len);
     58}
     59
     60#endif
     61
     62#if defined(sun) || defined(__hpux) || defined(__sgi)
     63
     64int
     65setenv(name, value, dum)
     66    const char *name;
     67    const char *value;
     68    int dum;
     69{
     70    register char *p;
     71    int len = strlen(name) + strlen(value) + 2; /* = \0 */
     72    char *ptr = (char*) malloc(len);
     73
     74    (void) dum;
     75
     76    if (ptr == NULL)
     77        return -1;
     78
     79    p = ptr;
     80
     81    while (*name)
     82        *p++ = *name++;
     83
     84    *p++ = '=';
     85
     86    while (*value)
     87        *p++ = *value++;
     88
     89    *p = '\0';
     90
     91    len = putenv(ptr);
     92/*    free(ptr); */
     93    return len;
     94}
     95#endif
     96
     97#ifdef __hpux
     98#include <sys/types.h>
     99#include <sys/param.h>
     100#include <sys/syscall.h>
     101#include <sys/signal.h>
     102#include <sys/stat.h>
     103#include <stdio.h>
     104#include <dirent.h>
     105#include <sys/time.h>
     106#include <time.h>
     107#include <unistd.h>
     108
     109
     110int
     111killpg(pid, sig)
     112    int pid, sig;
     113{
     114    return kill(-pid, sig);
     115}
     116
     117void
     118srandom(seed)
     119    long seed;
     120{
     121    srand48(seed);
     122}
     123
     124long
     125random()
     126{
     127    return lrand48();
     128}
     129
     130/* turn into bsd signals */
     131void (*
     132signal(s, a)) ()
     133    int     s;
     134    void (*a)();
     135{
     136    struct sigvec osv, sv;
     137
     138    (void) sigvector(s, (struct sigvec *) 0, &osv);
     139    sv = osv;
     140    sv.sv_handler = a;
     141#ifdef SV_BSDSIG
     142    sv.sv_flags = SV_BSDSIG;
     143#endif
     144
     145    if (sigvector(s, &sv, (struct sigvec *) 0) == -1)
     146        return (BADSIG);
     147    return (osv.sv_handler);
     148}
     149
     150#if !defined(BSD) && !defined(d_fileno)
     151# define d_fileno d_ino
     152#endif
     153
     154#ifndef DEV_DEV_COMPARE
     155# define DEV_DEV_COMPARE(a, b) ((a) == (b))
     156#endif
     157
     158/* strrcpy():
     159 *      Like strcpy, going backwards and returning the new pointer
    238160 */
    239 void *
    240 erealloc(void *ptr, size_t size)
    241 {
    242         if ((ptr = realloc(ptr, size)) == NULL)
    243                 enomem();
    244         return(ptr);
    245 }
    246 
    247 /*
    248  * enomem --
    249  *      die when out of memory.
    250  */
    251 void
    252 enomem(void)
    253 {
    254         err(2, NULL);
    255 }
    256 
    257 /*
    258  * enunlink --
    259  *      Remove a file carefully, avoiding directories.
    260  */
     161static char *
     162strrcpy(ptr, str)
     163    register char *ptr, *str;
     164{
     165    register int len = strlen(str);
     166
     167    while (len)
     168        *--ptr = str[--len];
     169
     170    return (ptr);
     171} /* end strrcpy */
     172
     173
     174char   *
     175getwd(pathname)
     176    char   *pathname;
     177{
     178    DIR    *dp;
     179    struct dirent *d;
     180
     181    struct stat st_root, st_cur, st_next, st_dotdot;
     182    char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
     183    char   *pathptr, *nextpathptr, *cur_name_add;
     184
     185    /* find the inode of root */
     186    if (stat("/", &st_root) == -1) {
     187        (void) sprintf(pathname,
     188                        "getwd: Cannot stat \"/\" (%s)", strerror(errno));
     189        return (NULL);
     190    }
     191    pathbuf[MAXPATHLEN - 1] = '\0';
     192    pathptr = &pathbuf[MAXPATHLEN - 1];
     193    nextpathbuf[MAXPATHLEN - 1] = '\0';
     194    cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
     195
     196    /* find the inode of the current directory */
     197    if (lstat(".", &st_cur) == -1) {
     198        (void) sprintf(pathname,
     199                        "getwd: Cannot stat \".\" (%s)", strerror(errno));
     200        return (NULL);
     201    }
     202    nextpathptr = strrcpy(nextpathptr, "../");
     203
     204    /* Descend to root */
     205    for (;;) {
     206
     207        /* look if we found root yet */
     208        if (st_cur.st_ino == st_root.st_ino &&
     209            DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
     210            (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
     211            return (pathname);
     212        }
     213
     214        /* open the parent directory */
     215        if (stat(nextpathptr, &st_dotdot) == -1) {
     216            snprintf(pathname, sizeof(pathname),
     217                            "getwd: Cannot stat directory \"%s\" (%s)",
     218                            nextpathptr, strerror(errno));
     219            return (NULL);
     220        }
     221        if ((dp = opendir(nextpathptr)) == NULL) {
     222             snprintf(pathname, sizeof(pathname),
     223                            "getwd: Cannot open directory \"%s\" (%s)",
     224                            nextpathptr, strerror(errno));
     225            return (NULL);
     226        }
     227
     228        /* look in the parent for the entry with the same inode */
     229        if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
     230            /* Parent has same device. No need to stat every member */
     231            for (d = readdir(dp); d != NULL; d = readdir(dp))
     232                if (d->d_fileno == st_cur.st_ino)
     233                    break;
     234        }
     235        else {
     236            /*
     237             * Parent has a different device. This is a mount point so we
     238             * need to stat every member
     239             */
     240            for (d = readdir(dp); d != NULL; d = readdir(dp)) {
     241                if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
     242                    continue;
     243                (void) strcpy(cur_name_add, d->d_name);
     244                if (lstat(nextpathptr, &st_next) == -1) {
     245                    snprintf(pathname, sizeof(pathname), "getwd: Cannot stat \"%s\" (%s)",
     246                                    d->d_name, strerror(errno));
     247                    (void) closedir(dp);
     248                    return (NULL);
     249                }
     250                /* check if we found it yet */
     251                if (st_next.st_ino == st_cur.st_ino &&
     252                    DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
     253                    break;
     254            }
     255        }
     256        if (d == NULL) {
     257            (void) sprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
     258            (void) closedir(dp);
     259            return (NULL);
     260        }
     261        st_cur = st_dotdot;
     262        pathptr = strrcpy(pathptr, d->d_name);
     263        pathptr = strrcpy(pathptr, "/");
     264        nextpathptr = strrcpy(nextpathptr, "../");
     265        (void) closedir(dp);
     266        *cur_name_add = '\0';
     267    }
     268} /* end getwd */
     269
     270
     271char    *sys_siglist[] = {
     272        "Signal 0",
     273        "Hangup",                       /* SIGHUP    */
     274        "Interrupt",                    /* SIGINT    */
     275        "Quit",                         /* SIGQUIT   */
     276        "Illegal instruction",          /* SIGILL    */
     277        "Trace/BPT trap",               /* SIGTRAP   */
     278        "IOT trap",                     /* SIGIOT    */
     279        "EMT trap",                     /* SIGEMT    */
     280        "Floating point exception",     /* SIGFPE    */
     281        "Killed",                       /* SIGKILL   */
     282        "Bus error",                    /* SIGBUS    */
     283        "Segmentation fault",           /* SIGSEGV   */
     284        "Bad system call",              /* SIGSYS    */
     285        "Broken pipe",                  /* SIGPIPE   */
     286        "Alarm clock",                  /* SIGALRM   */
     287        "Terminated",                   /* SIGTERM   */
     288        "User defined signal 1",        /* SIGUSR1   */
     289        "User defined signal 2",        /* SIGUSR2   */
     290        "Child exited",                 /* SIGCLD    */
     291        "Power-fail restart",           /* SIGPWR    */
     292        "Virtual timer expired",        /* SIGVTALRM */
     293        "Profiling timer expired",      /* SIGPROF   */
     294        "I/O possible",                 /* SIGIO     */
     295        "Window size changes",          /* SIGWINDOW */
     296        "Stopped (signal)",             /* SIGSTOP   */
     297        "Stopped",                      /* SIGTSTP   */
     298        "Continued",                    /* SIGCONT   */
     299        "Stopped (tty input)",          /* SIGTTIN   */
     300        "Stopped (tty output)",         /* SIGTTOU   */
     301        "Urgent I/O condition",         /* SIGURG    */
     302        "Remote lock lost (NFS)",       /* SIGLOST   */
     303        "Signal 31",                    /* reserved  */
     304        "DIL signal"                    /* SIGDIL    */
     305};
     306
    261307int
    262 eunlink(const char *file)
    263 {
    264         struct stat st;
    265 
    266         if (lstat(file, &st) == -1)
    267                 return -1;
    268 
    269         if (S_ISDIR(st.st_mode)) {
    270                 errno = EISDIR;
    271                 return -1;
    272         }
    273         return unlink(file);
    274 }
    275 
    276 /*
    277  * Printaddr --
    278  *      Print the address of a node, used as an interative function.
    279  */
    280 int
    281 PrintAddr(void *a, void *b __unused)
    282 {
    283     printf("%p ", a);
    284     return 0;
    285 }
     308utimes(file, tvp)
     309    char *file;
     310    struct timeval tvp[2];
     311{
     312    struct utimbuf t;
     313
     314    t.actime  = tvp[0].tv_sec;
     315    t.modtime = tvp[1].tv_sec;
     316    return(utime(file, &t));
     317}
     318
     319
     320#endif /* __hpux */
     321
     322#if defined(sun) && defined(__svr4__)
     323#include <signal.h>
     324
     325/* turn into bsd signals */
     326void (*
     327signal(s, a)) ()
     328    int     s;
     329    void (*a)();
     330{
     331    struct sigaction sa, osa;
     332
     333    sa.sa_handler = a;
     334    sigemptyset(&sa.sa_mask);
     335    sa.sa_flags = SA_RESTART;
     336
     337    if (sigaction(s, &sa, &osa) == -1)
     338        return SIG_ERR;
     339    else
     340        return osa.sa_handler;
     341}
     342
     343#endif
Note: See TracChangeset for help on using the changeset viewer.