[BACK]Return to util.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Annotation of src/usr.bin/make/util.c, Revision 1.16

1.14      espie       1: /*     $OpenPackages$ */
1.16    ! espie       2: /*     $OpenBSD: util.c,v 1.10 1998/12/20 23:38:11 deraadt Exp $       */
1.6       millert     3: /*     $NetBSD: util.c,v 1.10 1996/12/31 17:56:04 christos Exp $       */
1.1       deraadt     4:
                      5: /*
1.16    ! espie       6:  * Copyright (c) 2001 Marc Espie.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
        !            18:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        !            19:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        !            20:  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
        !            21:  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        !            22:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        !            23:  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            27:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            28:  */
        !            29: /*
1.1       deraadt    30:  * Missing stuff from OS's
                     31:  */
                     32:
1.16    ! espie      33: #include <sys/param.h>
1.1       deraadt    34: #include <stdio.h>
1.16    ! espie      35: #include "config.h"
        !            36: #include "defines.h"
1.13      espie      37:
1.7       mickey     38: #ifndef __STDC__
1.1       deraadt    39: # ifndef const
                     40: #  define const
                     41: # endif
                     42: #endif
                     43:
                     44: #ifdef sun
                     45:
                     46:
                     47:
                     48: extern int errno, sys_nerr;
                     49: extern char *sys_errlist[];
                     50:
                     51: char *
1.5       millert    52: strerror(e)
                     53:     int e;
1.1       deraadt    54: {
                     55:     static char buf[100];
                     56:     if (e < 0 || e >= sys_nerr) {
                     57:        sprintf(buf, "Unknown error %d", e);
                     58:        return buf;
                     59:     }
                     60:     else
                     61:        return sys_errlist[e];
                     62: }
                     63: #endif
                     64:
1.4       briggs     65: #ifdef ultrix
                     66: #include <string.h>
                     67:
                     68: /* strdup
                     69:  *
                     70:  * Make a duplicate of a string.
                     71:  * For systems which lack this function.
                     72:  */
                     73: char *
                     74: strdup(str)
                     75:     const char *str;
                     76: {
                     77:     size_t len;
1.5       millert    78:     char *p;
1.4       briggs     79:
                     80:     if (str == NULL)
                     81:        return NULL;
                     82:     len = strlen(str) + 1;
                     83:     if ((p = malloc(len)) == NULL)
                     84:        return NULL;
                     85:
                     86:     return memcpy(p, str, len);
                     87: }
                     88:
                     89: #endif
                     90:
                     91: #if defined(sun) || defined(__hpux) || defined(__sgi)
1.1       deraadt    92:
                     93: int
                     94: setenv(name, value, dum)
1.5       millert    95:     const char *name;
1.1       deraadt    96:     const char *value;
                     97:     int dum;
                     98: {
1.14      espie      99:     char *p;
1.1       deraadt   100:     int len = strlen(name) + strlen(value) + 2; /* = \0 */
1.14      espie     101:     char *ptr = (char*)malloc(len);
1.1       deraadt   102:
                    103:     if (ptr == NULL)
                    104:        return -1;
1.5       millert   105:
1.1       deraadt   106:     p = ptr;
                    107:
1.5       millert   108:     while (*name)
1.1       deraadt   109:        *p++ = *name++;
                    110:
                    111:     *p++ = '=';
                    112:
1.5       millert   113:     while (*value)
1.1       deraadt   114:        *p++ = *value++;
                    115:
                    116:     *p = '\0';
                    117:
                    118:     len = putenv(ptr);
                    119: /*    free(ptr); */
                    120:     return len;
                    121: }
                    122: #endif
                    123:
                    124: #ifdef __hpux
                    125: #include <sys/types.h>
                    126: #include <sys/param.h>
                    127: #include <sys/syscall.h>
                    128: #include <sys/signal.h>
                    129: #include <sys/stat.h>
                    130: #include <stdio.h>
                    131: #include <dirent.h>
                    132: #include <sys/time.h>
                    133: #include <time.h>
                    134: #include <unistd.h>
                    135:
                    136:
                    137: int
                    138: killpg(pid, sig)
                    139:     int pid, sig;
                    140: {
                    141:     return kill(-pid, sig);
                    142: }
                    143:
                    144: void
                    145: srandom(seed)
                    146:     long seed;
                    147: {
                    148:     srand48(seed);
                    149: }
                    150:
                    151: long
                    152: random()
                    153: {
                    154:     return lrand48();
                    155: }
                    156:
                    157: /* turn into bsd signals */
                    158: void (*
1.14      espie     159: signal(s, a))()
1.1       deraadt   160:     int     s;
                    161:     void (*a)();
                    162: {
                    163:     struct sigvec osv, sv;
                    164:
1.14      espie     165:     (void)sigvector(s, (struct sigvec *)0, &osv);
1.1       deraadt   166:     sv = osv;
                    167:     sv.sv_handler = a;
                    168: #ifdef SV_BSDSIG
                    169:     sv.sv_flags = SV_BSDSIG;
                    170: #endif
                    171:
1.14      espie     172:     if (sigvector(s, &sv, (struct sigvec *)0) == -1)
                    173:        return SIG_ERR;
                    174:     return osv.sv_handler;
1.1       deraadt   175: }
                    176:
                    177: #if !defined(BSD) && !defined(d_fileno)
                    178: # define d_fileno d_ino
                    179: #endif
                    180:
                    181: #ifndef DEV_DEV_COMPARE
                    182: # define DEV_DEV_COMPARE(a, b) ((a) == (b))
                    183: #endif
1.14      espie     184: #define ISDOT(c) ((c)[0] == '.' && ((c)[1] == '\0' || (c)[1] == '/'))
1.1       deraadt   185: #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
                    186:
                    187:
                    188: /* strrcpy():
                    189:  *     Like strcpy, going backwards and returning the new pointer
                    190:  */
                    191: static char *
                    192: strrcpy(ptr, str)
1.14      espie     193:     char *ptr, *str;
1.1       deraadt   194: {
1.14      espie     195:     size_t len = strlen(str);
1.1       deraadt   196:
                    197:     while (len)
                    198:        *--ptr = str[--len];
                    199:
1.14      espie     200:     return ptr;
1.1       deraadt   201: } /* end strrcpy */
                    202:
                    203:
                    204: char   *
                    205: getwd(pathname)
                    206:     char   *pathname;
                    207: {
                    208:     DIR    *dp;
                    209:     struct dirent *d;
                    210:     extern int errno;
                    211:
                    212:     struct stat st_root, st_cur, st_next, st_dotdot;
                    213:     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
                    214:     char   *pathptr, *nextpathptr, *cur_name_add;
                    215:
                    216:     /* find the inode of root */
                    217:     if (stat("/", &st_root) == -1) {
1.14      espie     218:        (void)sprintf(pathname,
1.1       deraadt   219:                        "getwd: Cannot stat \"/\" (%s)", strerror(errno));
1.14      espie     220:        return NULL;
1.1       deraadt   221:     }
                    222:     pathbuf[MAXPATHLEN - 1] = '\0';
                    223:     pathptr = &pathbuf[MAXPATHLEN - 1];
                    224:     nextpathbuf[MAXPATHLEN - 1] = '\0';
                    225:     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
                    226:
                    227:     /* find the inode of the current directory */
                    228:     if (lstat(".", &st_cur) == -1) {
1.14      espie     229:        (void)sprintf(pathname,
1.1       deraadt   230:                        "getwd: Cannot stat \".\" (%s)", strerror(errno));
1.14      espie     231:        return NULL;
1.1       deraadt   232:     }
                    233:     nextpathptr = strrcpy(nextpathptr, "../");
                    234:
                    235:     /* Descend to root */
                    236:     for (;;) {
                    237:
                    238:        /* look if we found root yet */
                    239:        if (st_cur.st_ino == st_root.st_ino &&
                    240:            DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
1.14      espie     241:            (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
                    242:            return pathname;
1.1       deraadt   243:        }
                    244:
                    245:        /* open the parent directory */
                    246:        if (stat(nextpathptr, &st_dotdot) == -1) {
1.14      espie     247:            (void)sprintf(pathname,
1.1       deraadt   248:                            "getwd: Cannot stat directory \"%s\" (%s)",
                    249:                            nextpathptr, strerror(errno));
1.14      espie     250:            return NULL;
1.1       deraadt   251:        }
                    252:        if ((dp = opendir(nextpathptr)) == NULL) {
1.14      espie     253:            (void)sprintf(pathname,
1.1       deraadt   254:                            "getwd: Cannot open directory \"%s\" (%s)",
                    255:                            nextpathptr, strerror(errno));
1.14      espie     256:            return NULL;
1.1       deraadt   257:        }
                    258:
                    259:        /* look in the parent for the entry with the same inode */
                    260:        if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
                    261:            /* Parent has same device. No need to stat every member */
1.5       millert   262:            for (d = readdir(dp); d != NULL; d = readdir(dp))
1.1       deraadt   263:                if (d->d_fileno == st_cur.st_ino)
                    264:                    break;
                    265:        }
                    266:        else {
1.5       millert   267:            /*
                    268:             * Parent has a different device. This is a mount point so we
                    269:             * need to stat every member
1.1       deraadt   270:             */
                    271:            for (d = readdir(dp); d != NULL; d = readdir(dp)) {
                    272:                if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
                    273:                    continue;
1.14      espie     274:                (void)strcpy(cur_name_add, d->d_name);
1.1       deraadt   275:                if (lstat(nextpathptr, &st_next) == -1) {
1.14      espie     276:                    (void)sprintf(pathname, "getwd: Cannot stat \"%s\" (%s)",
1.1       deraadt   277:                                    d->d_name, strerror(errno));
1.14      espie     278:                    (void)closedir(dp);
                    279:                    return NULL;
1.1       deraadt   280:                }
                    281:                /* check if we found it yet */
                    282:                if (st_next.st_ino == st_cur.st_ino &&
1.5       millert   283:                    DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
1.1       deraadt   284:                    break;
                    285:            }
                    286:        }
                    287:        if (d == NULL) {
1.14      espie     288:            (void)sprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
                    289:            (void)closedir(dp);
                    290:            return NULL;
1.1       deraadt   291:        }
                    292:        st_cur = st_dotdot;
                    293:        pathptr = strrcpy(pathptr, d->d_name);
                    294:        pathptr = strrcpy(pathptr, "/");
                    295:        nextpathptr = strrcpy(nextpathptr, "../");
1.14      espie     296:        (void)closedir(dp);
1.1       deraadt   297:        *cur_name_add = '\0';
                    298:     }
                    299: } /* end getwd */
                    300:
                    301:
1.14      espie     302: char   *sys_siglist[] = {
                    303:        "Signal 0",
                    304:        "Hangup",                       /* SIGHUP    */
                    305:        "Interrupt",                    /* SIGINT    */
                    306:        "Quit",                         /* SIGQUIT   */
                    307:        "Illegal instruction",          /* SIGILL    */
                    308:        "Trace/BPT trap",               /* SIGTRAP   */
                    309:        "IOT trap",                     /* SIGIOT    */
                    310:        "EMT trap",                     /* SIGEMT    */
                    311:        "Floating point exception",     /* SIGFPE    */
                    312:        "Killed",                       /* SIGKILL   */
                    313:        "Bus error",                    /* SIGBUS    */
                    314:        "Segmentation fault",           /* SIGSEGV   */
                    315:        "Bad system call",              /* SIGSYS    */
                    316:        "Broken pipe",                  /* SIGPIPE   */
                    317:        "Alarm clock",                  /* SIGALRM   */
                    318:        "Terminated",                   /* SIGTERM   */
                    319:        "User defined signal 1",        /* SIGUSR1   */
                    320:        "User defined signal 2",        /* SIGUSR2   */
                    321:        "Child exited",                 /* SIGCLD    */
                    322:        "Power-fail restart",           /* SIGPWR    */
                    323:        "Virtual timer expired",        /* SIGVTALRM */
                    324:        "Profiling timer expired",      /* SIGPROF   */
                    325:        "I/O possible",                 /* SIGIO     */
                    326:        "Window size changes",          /* SIGWINDOW */
                    327:        "Stopped (signal)",             /* SIGSTOP   */
                    328:        "Stopped",                      /* SIGTSTP   */
                    329:        "Continued",                    /* SIGCONT   */
                    330:        "Stopped (tty input)",          /* SIGTTIN   */
                    331:        "Stopped (tty output)",         /* SIGTTOU   */
                    332:        "Urgent I/O condition",         /* SIGURG    */
                    333:        "Remote lock lost (NFS)",       /* SIGLOST   */
                    334:        "Signal 31",                    /* reserved  */
                    335:        "DIL signal"                    /* SIGDIL    */
1.1       deraadt   336: };
                    337:
                    338: int
                    339: utimes(file, tvp)
                    340:     char *file;
                    341:     struct timeval tvp[2];
                    342: {
                    343:     struct utimbuf t;
                    344:
                    345:     t.actime  = tvp[0].tv_sec;
                    346:     t.modtime = tvp[1].tv_sec;
1.14      espie     347:     return utime(file, &t);
1.1       deraadt   348: }
                    349:
                    350:
                    351: #endif /* __hpux */
1.2       deraadt   352:
                    353: #if defined(sun) && defined(__svr4__)
                    354: #include <signal.h>
                    355:
                    356: /* turn into bsd signals */
                    357: void (*
1.14      espie     358: signal(s, a))()
1.2       deraadt   359:     int     s;
                    360:     void (*a)();
                    361: {
                    362:     struct sigaction sa, osa;
                    363:
1.8       deraadt   364:     memset(&sa, 0, sizeof sa);
1.2       deraadt   365:     sa.sa_handler = a;
                    366:     sigemptyset(&sa.sa_mask);
                    367:     sa.sa_flags = SA_RESTART;
                    368:
                    369:     if (sigaction(s, &sa, &osa) == -1)
                    370:        return SIG_ERR;
                    371:     else
                    372:        return osa.sa_handler;
                    373: }
                    374:
1.6       millert   375: #endif
                    376:
1.16    ! espie     377: #ifndef BSD4_4
1.6       millert   378: #ifdef __STDC__
                    379: #include <stdarg.h>
                    380: #else
                    381: #include <varargs.h>
                    382: #endif
                    383:
                    384: #ifdef _IOSTRG
1.14      espie     385: #define STRFLAG (_IOSTRG|_IOWRT)       /* no _IOWRT: avoid stdio bug */
1.6       millert   386: #else
1.14      espie     387: #define STRFLAG (_IOREAD)              /* XXX: Assume svr4 stdio */
1.6       millert   388: #endif
                    389:
                    390: int
                    391: vsnprintf(s, n, fmt, args)
                    392:        char *s;
                    393:        size_t n;
                    394:        const char *fmt;
                    395:        va_list args;
                    396: {
                    397:        FILE fakebuf;
                    398:
                    399:        fakebuf._flag = STRFLAG;
                    400:        /*
                    401:         * Some os's are char * _ptr, others are unsigned char *_ptr...
                    402:         * We cast to void * to make everyone happy.
                    403:         */
1.14      espie     404:        fakebuf._ptr = (void *)s;
1.6       millert   405:        fakebuf._cnt = n-1;
                    406:        fakebuf._file = -1;
                    407:        _doprnt(fmt, args, &fakebuf);
                    408:        fakebuf._cnt++;
                    409:        putc('\0', &fakebuf);
                    410:        if (fakebuf._cnt<0)
                    411:            fakebuf._cnt = 0;
1.14      espie     412:        return n-fakebuf._cnt-1;
1.6       millert   413: }
                    414:
                    415: int
                    416: #ifdef __STDC__
                    417: snprintf(char *s, size_t n, const char *fmt, ...)
                    418: #else
                    419: snprintf(va_alist)
                    420:        va_dcl
                    421: #endif
                    422: {
                    423:        va_list ap;
                    424:        int rv;
                    425: #ifdef __STDC__
                    426:        va_start(ap, fmt);
                    427: #else
                    428:        char *s;
                    429:        size_t n;
                    430:        const char *fmt;
                    431:
                    432:        va_start(ap);
                    433:
                    434:        s = va_arg(ap, char *);
                    435:        n = va_arg(ap, size_t);
                    436:        fmt = va_arg(ap, const char *);
                    437: #endif
                    438:        rv = vsnprintf(s, n, fmt, ap);
                    439:        va_end(ap);
                    440:        return rv;
1.11      espie     441: }
                    442: #endif
                    443: #ifdef NEED_STRSTR
                    444: char *
                    445: strstr(string, substring)
                    446:        const char *string;             /* String to search. */
                    447:        const char *substring;          /* Substring to find in string */
                    448: {
                    449:        const char *a, *b;
                    450:
                    451:        /*
                    452:         * First scan quickly through the two strings looking for a single-
                    453:         * character match.  When it's found, then compare the rest of the
                    454:         * substring.
                    455:         */
                    456:
                    457:        for (b = substring; *string != 0; string += 1) {
                    458:                if (*string != *b)
                    459:                        continue;
                    460:                a = string;
                    461:                for (;;) {
                    462:                        if (*b == 0)
                    463:                                return (char *)string;
                    464:                        if (*a++ != *b++)
                    465:                                break;
                    466:                }
                    467:                b = substring;
                    468:        }
                    469:        return NULL;
1.12      espie     470: }
                    471: #endif
                    472:
                    473: #ifdef NEED_FGETLN
                    474: char *
                    475: fgetln(stream, len)
                    476:     FILE *stream;
                    477:     size_t *len;
                    478: {
                    479:     static char *buffer = NULL;
                    480:     static size_t buflen = 0;
                    481:
                    482:     if (buflen == 0) {
1.14      espie     483:        buflen = 512;
1.12      espie     484:        buffer = emalloc(buflen+1);
                    485:     }
                    486:     if (fgets(buffer, buflen+1, stream) == NULL)
                    487:        return NULL;
                    488:     *len = strlen(buffer);
                    489:     while (*len == buflen && buffer[*len-1] != '\n') {
                    490:        buffer = erealloc(buffer, 2*buflen + 1);
                    491:        if (fgets(buffer + buflen, buflen + 1, stream) == NULL)
                    492:            return NULL;
                    493:        *len += strlen(buffer + buflen);
                    494:        buflen *= 2;
                    495:     }
                    496:     return buffer;
1.6       millert   497: }
1.2       deraadt   498: #endif