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

1.14      espie       1: /*     $OpenPackages$ */
1.19    ! espie       2: /*     $OpenBSD: util.c,v 1.18 2002/05/29 09:23:25 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.1       deraadt    38: #ifdef sun
                     39:
                     40: extern int errno, sys_nerr;
                     41: extern char *sys_errlist[];
                     42:
                     43: char *
1.5       millert    44: strerror(e)
                     45:     int e;
1.1       deraadt    46: {
                     47:     static char buf[100];
                     48:     if (e < 0 || e >= sys_nerr) {
1.18      deraadt    49:        snprintf(buf, sizeof buf, "Unknown error %d", e);
1.1       deraadt    50:        return buf;
                     51:     }
                     52:     else
                     53:        return sys_errlist[e];
                     54: }
                     55: #endif
                     56:
1.4       briggs     57: #ifdef ultrix
                     58: #include <string.h>
                     59:
                     60: /* strdup
                     61:  *
                     62:  * Make a duplicate of a string.
                     63:  * For systems which lack this function.
                     64:  */
                     65: char *
                     66: strdup(str)
                     67:     const char *str;
                     68: {
                     69:     size_t len;
1.5       millert    70:     char *p;
1.4       briggs     71:
                     72:     if (str == NULL)
                     73:        return NULL;
                     74:     len = strlen(str) + 1;
                     75:     if ((p = malloc(len)) == NULL)
                     76:        return NULL;
                     77:
                     78:     return memcpy(p, str, len);
                     79: }
                     80:
                     81: #endif
                     82:
                     83: #if defined(sun) || defined(__hpux) || defined(__sgi)
1.1       deraadt    84:
                     85: int
                     86: setenv(name, value, dum)
1.5       millert    87:     const char *name;
1.1       deraadt    88:     const char *value;
                     89:     int dum;
                     90: {
1.14      espie      91:     char *p;
1.1       deraadt    92:     int len = strlen(name) + strlen(value) + 2; /* = \0 */
1.14      espie      93:     char *ptr = (char*)malloc(len);
1.1       deraadt    94:
                     95:     if (ptr == NULL)
                     96:        return -1;
1.5       millert    97:
1.1       deraadt    98:     p = ptr;
                     99:
1.5       millert   100:     while (*name)
1.1       deraadt   101:        *p++ = *name++;
                    102:
                    103:     *p++ = '=';
                    104:
1.5       millert   105:     while (*value)
1.1       deraadt   106:        *p++ = *value++;
                    107:
                    108:     *p = '\0';
                    109:
                    110:     len = putenv(ptr);
                    111: /*    free(ptr); */
                    112:     return len;
                    113: }
                    114: #endif
                    115:
                    116: #ifdef __hpux
                    117: #include <sys/types.h>
                    118: #include <sys/param.h>
                    119: #include <sys/syscall.h>
                    120: #include <sys/signal.h>
                    121: #include <sys/stat.h>
                    122: #include <stdio.h>
                    123: #include <dirent.h>
                    124: #include <sys/time.h>
                    125: #include <time.h>
                    126: #include <unistd.h>
                    127:
                    128:
                    129: int
                    130: killpg(pid, sig)
                    131:     int pid, sig;
                    132: {
                    133:     return kill(-pid, sig);
                    134: }
                    135:
                    136: void
                    137: srandom(seed)
                    138:     long seed;
                    139: {
                    140:     srand48(seed);
                    141: }
                    142:
                    143: long
                    144: random()
                    145: {
                    146:     return lrand48();
                    147: }
                    148:
                    149: /* turn into bsd signals */
                    150: void (*
1.14      espie     151: signal(s, a))()
1.1       deraadt   152:     int     s;
                    153:     void (*a)();
                    154: {
                    155:     struct sigvec osv, sv;
                    156:
1.14      espie     157:     (void)sigvector(s, (struct sigvec *)0, &osv);
1.1       deraadt   158:     sv = osv;
                    159:     sv.sv_handler = a;
                    160: #ifdef SV_BSDSIG
                    161:     sv.sv_flags = SV_BSDSIG;
                    162: #endif
                    163:
1.14      espie     164:     if (sigvector(s, &sv, (struct sigvec *)0) == -1)
                    165:        return SIG_ERR;
                    166:     return osv.sv_handler;
1.1       deraadt   167: }
                    168:
                    169: #if !defined(BSD) && !defined(d_fileno)
                    170: # define d_fileno d_ino
                    171: #endif
                    172:
                    173: #ifndef DEV_DEV_COMPARE
                    174: # define DEV_DEV_COMPARE(a, b) ((a) == (b))
                    175: #endif
1.14      espie     176: #define ISDOT(c) ((c)[0] == '.' && ((c)[1] == '\0' || (c)[1] == '/'))
1.1       deraadt   177: #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
                    178:
                    179:
                    180: /* strrcpy():
                    181:  *     Like strcpy, going backwards and returning the new pointer
                    182:  */
                    183: static char *
                    184: strrcpy(ptr, str)
1.14      espie     185:     char *ptr, *str;
1.1       deraadt   186: {
1.14      espie     187:     size_t len = strlen(str);
1.1       deraadt   188:
                    189:     while (len)
                    190:        *--ptr = str[--len];
                    191:
1.14      espie     192:     return ptr;
1.1       deraadt   193: } /* end strrcpy */
                    194:
                    195:
                    196: char   *
                    197: getwd(pathname)
                    198:     char   *pathname;
                    199: {
                    200:     DIR    *dp;
                    201:     struct dirent *d;
                    202:     extern int errno;
                    203:
                    204:     struct stat st_root, st_cur, st_next, st_dotdot;
                    205:     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
                    206:     char   *pathptr, *nextpathptr, *cur_name_add;
                    207:
                    208:     /* find the inode of root */
                    209:     if (stat("/", &st_root) == -1) {
1.19    ! espie     210:        (void)snprintf(pathname, MAXPATHLEN,
1.18      deraadt   211:            "getwd: Cannot stat \"/\" (%s)", strerror(errno));
1.14      espie     212:        return NULL;
1.1       deraadt   213:     }
                    214:     pathbuf[MAXPATHLEN - 1] = '\0';
                    215:     pathptr = &pathbuf[MAXPATHLEN - 1];
                    216:     nextpathbuf[MAXPATHLEN - 1] = '\0';
                    217:     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
                    218:
                    219:     /* find the inode of the current directory */
                    220:     if (lstat(".", &st_cur) == -1) {
1.19    ! espie     221:        (void)snprintf(pathname, MAXPATHLEN,
1.18      deraadt   222:            "getwd: Cannot stat \".\" (%s)", strerror(errno));
1.14      espie     223:        return NULL;
1.1       deraadt   224:     }
                    225:     nextpathptr = strrcpy(nextpathptr, "../");
                    226:
                    227:     /* Descend to root */
                    228:     for (;;) {
                    229:
                    230:        /* look if we found root yet */
                    231:        if (st_cur.st_ino == st_root.st_ino &&
                    232:            DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
1.19    ! espie     233:            (void)strlcpy(pathname, *pathptr != '/' ? "/" : pathptr, MAXPATHLEN);
1.14      espie     234:            return pathname;
1.1       deraadt   235:        }
                    236:
                    237:        /* open the parent directory */
                    238:        if (stat(nextpathptr, &st_dotdot) == -1) {
1.19    ! espie     239:            (void)snprintf(pathname, MAXPATHLEN,
1.18      deraadt   240:                "getwd: Cannot stat directory \"%s\" (%s)",
                    241:                nextpathptr, strerror(errno));
1.14      espie     242:            return NULL;
1.1       deraadt   243:        }
                    244:        if ((dp = opendir(nextpathptr)) == NULL) {
1.19    ! espie     245:            (void)snprintf(pathname, MAXPATHLEN,
1.18      deraadt   246:                "getwd: Cannot open directory \"%s\" (%s)",
                    247:                nextpathptr, strerror(errno));
1.14      espie     248:            return NULL;
1.1       deraadt   249:        }
                    250:
                    251:        /* look in the parent for the entry with the same inode */
                    252:        if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
                    253:            /* Parent has same device. No need to stat every member */
1.5       millert   254:            for (d = readdir(dp); d != NULL; d = readdir(dp))
1.1       deraadt   255:                if (d->d_fileno == st_cur.st_ino)
                    256:                    break;
                    257:        }
                    258:        else {
1.5       millert   259:            /*
                    260:             * Parent has a different device. This is a mount point so we
                    261:             * need to stat every member
1.1       deraadt   262:             */
                    263:            for (d = readdir(dp); d != NULL; d = readdir(dp)) {
                    264:                if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
                    265:                    continue;
1.14      espie     266:                (void)strcpy(cur_name_add, d->d_name);
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;
                    335:     struct timeval tvp[2];
                    336: {
                    337:     struct utimbuf t;
                    338:
                    339:     t.actime  = tvp[0].tv_sec;
                    340:     t.modtime = tvp[1].tv_sec;
1.14      espie     341:     return utime(file, &t);
1.1       deraadt   342: }
                    343:
                    344:
                    345: #endif /* __hpux */
1.2       deraadt   346:
                    347: #if defined(sun) && defined(__svr4__)
                    348: #include <signal.h>
                    349:
                    350: /* turn into bsd signals */
                    351: void (*
1.14      espie     352: signal(s, a))()
1.2       deraadt   353:     int     s;
                    354:     void (*a)();
                    355: {
                    356:     struct sigaction sa, osa;
                    357:
1.8       deraadt   358:     memset(&sa, 0, sizeof sa);
1.2       deraadt   359:     sa.sa_handler = a;
                    360:     sigemptyset(&sa.sa_mask);
                    361:     sa.sa_flags = SA_RESTART;
                    362:
                    363:     if (sigaction(s, &sa, &osa) == -1)
                    364:        return SIG_ERR;
                    365:     else
                    366:        return osa.sa_handler;
                    367: }
                    368:
1.6       millert   369: #endif
                    370:
1.16      espie     371: #ifndef BSD4_4
1.6       millert   372: #include <stdarg.h>
                    373:
                    374: #ifdef _IOSTRG
1.14      espie     375: #define STRFLAG (_IOSTRG|_IOWRT)       /* no _IOWRT: avoid stdio bug */
1.6       millert   376: #else
1.14      espie     377: #define STRFLAG (_IOREAD)              /* XXX: Assume svr4 stdio */
1.6       millert   378: #endif
                    379:
                    380: int
                    381: vsnprintf(s, n, fmt, args)
                    382:        char *s;
                    383:        size_t n;
                    384:        const char *fmt;
                    385:        va_list args;
                    386: {
                    387:        FILE fakebuf;
                    388:
                    389:        fakebuf._flag = STRFLAG;
                    390:        /*
                    391:         * Some os's are char * _ptr, others are unsigned char *_ptr...
                    392:         * We cast to void * to make everyone happy.
                    393:         */
1.14      espie     394:        fakebuf._ptr = (void *)s;
1.6       millert   395:        fakebuf._cnt = n-1;
                    396:        fakebuf._file = -1;
                    397:        _doprnt(fmt, args, &fakebuf);
                    398:        fakebuf._cnt++;
                    399:        putc('\0', &fakebuf);
                    400:        if (fakebuf._cnt<0)
                    401:            fakebuf._cnt = 0;
1.14      espie     402:        return n-fakebuf._cnt-1;
1.6       millert   403: }
                    404:
                    405: int
                    406: snprintf(char *s, size_t n, const char *fmt, ...)
                    407: {
                    408:        va_list ap;
                    409:        int rv;
1.17      millert   410:
1.6       millert   411:        va_start(ap, fmt);
                    412:        rv = vsnprintf(s, n, fmt, ap);
                    413:        va_end(ap);
                    414:        return rv;
1.11      espie     415: }
                    416: #endif
                    417: #ifdef NEED_STRSTR
                    418: char *
                    419: strstr(string, substring)
                    420:        const char *string;             /* String to search. */
                    421:        const char *substring;          /* Substring to find in string */
                    422: {
                    423:        const char *a, *b;
                    424:
                    425:        /*
                    426:         * First scan quickly through the two strings looking for a single-
                    427:         * character match.  When it's found, then compare the rest of the
                    428:         * substring.
                    429:         */
                    430:
                    431:        for (b = substring; *string != 0; string += 1) {
                    432:                if (*string != *b)
                    433:                        continue;
                    434:                a = string;
                    435:                for (;;) {
                    436:                        if (*b == 0)
                    437:                                return (char *)string;
                    438:                        if (*a++ != *b++)
                    439:                                break;
                    440:                }
                    441:                b = substring;
                    442:        }
                    443:        return NULL;
1.12      espie     444: }
                    445: #endif
                    446:
                    447: #ifdef NEED_FGETLN
                    448: char *
                    449: fgetln(stream, len)
                    450:     FILE *stream;
                    451:     size_t *len;
                    452: {
                    453:     static char *buffer = NULL;
                    454:     static size_t buflen = 0;
                    455:
                    456:     if (buflen == 0) {
1.14      espie     457:        buflen = 512;
1.12      espie     458:        buffer = emalloc(buflen+1);
                    459:     }
                    460:     if (fgets(buffer, buflen+1, stream) == NULL)
                    461:        return NULL;
                    462:     *len = strlen(buffer);
                    463:     while (*len == buflen && buffer[*len-1] != '\n') {
                    464:        buffer = erealloc(buffer, 2*buflen + 1);
                    465:        if (fgets(buffer + buflen, buflen + 1, stream) == NULL)
                    466:            return NULL;
                    467:        *len += strlen(buffer + buflen);
                    468:        buflen *= 2;
                    469:     }
                    470:     return buffer;
1.6       millert   471: }
1.2       deraadt   472: #endif