[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.26

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