Home | History | Annotate | Download | only in lib
      1 /* xwrap.c - wrappers around existing library functions.
      2  *
      3  * Functions with the x prefix are wrappers that either succeed or kill the
      4  * program with an error message, but never return failure. They usually have
      5  * the same arguments and return value as the function they wrap.
      6  *
      7  * Copyright 2006 Rob Landley <rob (at) landley.net>
      8  */
      9 
     10 #include "toys.h"
     11 
     12 // strcpy and strncat with size checking. Size is the total space in "dest",
     13 // including null terminator. Exit if there's not enough space for the string
     14 // (including space for the null terminator), because silently truncating is
     15 // still broken behavior. (And leaving the string unterminated is INSANE.)
     16 void xstrncpy(char *dest, char *src, size_t size)
     17 {
     18   if (strlen(src)+1 > size) error_exit("'%s' > %ld bytes", src, (long)size);
     19   strcpy(dest, src);
     20 }
     21 
     22 void xstrncat(char *dest, char *src, size_t size)
     23 {
     24   long len = strlen(dest);
     25 
     26   if (len+strlen(src)+1 > size)
     27     error_exit("'%s%s' > %ld bytes", dest, src, (long)size);
     28   strcpy(dest+len, src);
     29 }
     30 
     31 // We replaced exit(), _exit(), and atexit() with xexit(), _xexit(), and
     32 // sigatexit(). This gives _xexit() the option to siglongjmp(toys.rebound, 1)
     33 // instead of exiting, lets xexit() report stdout flush failures to stderr
     34 // and change the exit code to indicate error, lets our toys.exit function
     35 // change happen for signal exit paths and lets us remove the functions
     36 // after we've called them.
     37 
     38 void _xexit(void)
     39 {
     40   if (toys.rebound) siglongjmp(*toys.rebound, 1);
     41 
     42   _exit(toys.exitval);
     43 }
     44 
     45 void xexit(void)
     46 {
     47   // Call toys.xexit functions in reverse order added.
     48   while (toys.xexit) {
     49     struct arg_list *al = llist_pop(&toys.xexit);
     50 
     51     // typecast xexit->arg to a function pointer, then call it using invalid
     52     // signal 0 to let signal handlers tell actual signal from regular exit.
     53     ((void (*)(int))(al->arg))(0);
     54 
     55     free(al);
     56   }
     57   if (fflush(0) || ferror(stdout)) if (!toys.exitval) perror_msg("write");
     58   _xexit();
     59 }
     60 
     61 void *xmmap(void *addr, size_t length, int prot, int flags, int fd, off_t off)
     62 {
     63   void *ret = mmap(addr, length, prot, flags, fd, off);
     64   if (ret == MAP_FAILED) perror_exit("mmap");
     65   return ret;
     66 }
     67 
     68 // Die unless we can allocate memory.
     69 void *xmalloc(size_t size)
     70 {
     71   void *ret = malloc(size);
     72   if (!ret) error_exit("xmalloc(%ld)", (long)size);
     73 
     74   return ret;
     75 }
     76 
     77 // Die unless we can allocate prezeroed memory.
     78 void *xzalloc(size_t size)
     79 {
     80   void *ret = xmalloc(size);
     81   memset(ret, 0, size);
     82   return ret;
     83 }
     84 
     85 // Die unless we can change the size of an existing allocation, possibly
     86 // moving it.  (Notice different arguments from libc function.)
     87 void *xrealloc(void *ptr, size_t size)
     88 {
     89   ptr = realloc(ptr, size);
     90   if (!ptr) error_exit("xrealloc");
     91 
     92   return ptr;
     93 }
     94 
     95 // Die unless we can allocate a copy of this many bytes of string.
     96 char *xstrndup(char *s, size_t n)
     97 {
     98   char *ret = strndup(s, n);
     99 
    100   if (!ret) error_exit("xstrndup");
    101 
    102   return ret;
    103 }
    104 
    105 // Die unless we can allocate a copy of this string.
    106 char *xstrdup(char *s)
    107 {
    108   return xstrndup(s, strlen(s));
    109 }
    110 
    111 void *xmemdup(void *s, long len)
    112 {
    113   void *ret = xmalloc(len);
    114   memcpy(ret, s, len);
    115 
    116   return ret;
    117 }
    118 
    119 // Die unless we can allocate enough space to sprintf() into.
    120 char *xmprintf(char *format, ...)
    121 {
    122   va_list va, va2;
    123   int len;
    124   char *ret;
    125 
    126   va_start(va, format);
    127   va_copy(va2, va);
    128 
    129   // How long is it?
    130   len = vsnprintf(0, 0, format, va);
    131   len++;
    132   va_end(va);
    133 
    134   // Allocate and do the sprintf()
    135   ret = xmalloc(len);
    136   vsnprintf(ret, len, format, va2);
    137   va_end(va2);
    138 
    139   return ret;
    140 }
    141 
    142 void xflush(void)
    143 {
    144   if (fflush(stdout) || ferror(stdout)) perror_exit("write");
    145 }
    146 
    147 void xprintf(char *format, ...)
    148 {
    149   va_list va;
    150   va_start(va, format);
    151 
    152   vprintf(format, va);
    153   va_end(va);
    154   xflush();
    155 }
    156 
    157 // Put string with length (does not append newline)
    158 void xputsl(char *s, int len)
    159 {
    160   int out;
    161 
    162   while (len != (out = fwrite(s, 1, len, stdout))) {
    163     if (out<1) perror_exit("write");
    164     len -= out;
    165     s += out;
    166   }
    167   xflush();
    168 }
    169 
    170 // xputs with no newline
    171 void xputsn(char *s)
    172 {
    173   xputsl(s, strlen(s));
    174 }
    175 
    176 // Write string to stdout with newline, flushing and checking for errors
    177 void xputs(char *s)
    178 {
    179   puts(s);
    180   xflush();
    181 }
    182 
    183 void xputc(char c)
    184 {
    185   if (EOF == fputc(c, stdout)) perror_exit("write");
    186   xflush();
    187 }
    188 
    189 // This is called through the XVFORK macro because parent/child of vfork
    190 // share a stack, so child returning from a function would stomp the return
    191 // address parent would need. Solution: make vfork() an argument so processes
    192 // diverge before function gets called.
    193 pid_t __attribute__((returns_twice)) xvforkwrap(pid_t pid)
    194 {
    195   if (pid == -1) perror_exit("vfork");
    196 
    197   // Signal to xexec() and friends that we vforked so can't recurse
    198   toys.stacktop = 0;
    199 
    200   return pid;
    201 }
    202 
    203 // Die unless we can exec argv[] (or run builtin command).  Note that anything
    204 // with a path isn't a builtin, so /bin/sh won't match the builtin sh.
    205 void xexec(char **argv)
    206 {
    207   // Only recurse to builtin when we have multiplexer and !vfork context.
    208   if (CFG_TOYBOX && !CFG_TOYBOX_NORECURSE && toys.stacktop && **argv != '/')
    209     toy_exec(argv);
    210   execvp(argv[0], argv);
    211 
    212   toys.exitval = 126+(errno == ENOENT);
    213   perror_msg("exec %s", argv[0]);
    214   if (!toys.stacktop) _exit(toys.exitval);
    215   xexit();
    216 }
    217 
    218 // Spawn child process, capturing stdin/stdout.
    219 // argv[]: command to exec. If null, child re-runs original program with
    220 //         toys.stacktop zeroed.
    221 // pipes[2]: Filehandle to move to stdin/stdout of new process.
    222 //           If -1, replace with pipe handle connected to stdin/stdout.
    223 //           NULL treated as {0, 1}, I.E. leave stdin/stdout as is
    224 // return: pid of child process
    225 pid_t xpopen_both(char **argv, int *pipes)
    226 {
    227   int cestnepasun[4], pid;
    228 
    229   // Make the pipes?
    230   memset(cestnepasun, 0, sizeof(cestnepasun));
    231   if (pipes) for (pid = 0; pid < 2; pid++) {
    232     if (pipes[pid] != -1) continue;
    233     if (pipe(cestnepasun+(2*pid))) perror_exit("pipe");
    234   }
    235 
    236   if (!(pid = CFG_TOYBOX_FORK ? xfork() : XVFORK())) {
    237     // Child process: Dance of the stdin/stdout redirection.
    238     if (pipes) {
    239       // if we had no stdin/out, pipe handles could overlap, so test for it
    240       // and free up potentially overlapping pipe handles before reuse
    241       if (cestnepasun[2]) {
    242         close(cestnepasun[2]);
    243         pipes[1] = cestnepasun[3];
    244       }
    245       if (cestnepasun[1]) {
    246         close(cestnepasun[1]);
    247         pipes[0] = cestnepasun[0];
    248       }
    249 
    250       // If swapping stdin/stdout
    251       if (!pipes[1]) pipes[1] = dup(pipes[1]);
    252 
    253       // Are we redirecting stdin?
    254       if (pipes[0]) {
    255         dup2(pipes[0], 0);
    256         close(pipes[0]);
    257       }
    258 
    259       // Are we redirecting stdout?
    260       if (pipes[1] != 1) {
    261         dup2(pipes[1], 1);
    262         if (cestnepasun[2]) close(cestnepasun[2]);
    263       }
    264     }
    265     if (argv) xexec(argv);
    266 
    267     // In fork() case, force recursion because we know it's us.
    268     if (CFG_TOYBOX_FORK) {
    269       toy_init(toys.which, toys.argv);
    270       toys.stacktop = 0;
    271       toys.which->toy_main();
    272       xexit();
    273     // In vfork() case, exec /proc/self/exe with high bit of first letter set
    274     // to tell main() we reentered.
    275     } else {
    276       char *s = "/proc/self/exe";
    277 
    278       // We did a nommu-friendly vfork but must exec to continue.
    279       // setting high bit of argv[0][0] to let new process know
    280       **toys.argv |= 0x80;
    281       execv(s, toys.argv);
    282       perror_msg_raw(s);
    283 
    284       _exit(127);
    285     }
    286   }
    287 
    288   // Parent process: vfork had a shared environment, clean up.
    289   if (!CFG_TOYBOX_FORK) **toys.argv &= 0x7f;
    290 
    291   if (pipes) {
    292     if (cestnepasun[1]) {
    293       pipes[0] = cestnepasun[1];
    294       close(cestnepasun[0]);
    295     }
    296     if (cestnepasun[2]) {
    297       pipes[1] = cestnepasun[2];
    298       close(cestnepasun[3]);
    299     }
    300   }
    301 
    302   return pid;
    303 }
    304 
    305 // Wait for child process to exit, then return adjusted exit code.
    306 int xwaitpid(pid_t pid)
    307 {
    308   int status;
    309 
    310   while (-1 == waitpid(pid, &status, 0) && errno == EINTR);
    311 
    312   return WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+127;
    313 }
    314 
    315 int xpclose_both(pid_t pid, int *pipes)
    316 {
    317   if (pipes) {
    318     close(pipes[0]);
    319     close(pipes[1]);
    320   }
    321 
    322   return xwaitpid(pid);
    323 }
    324 
    325 // Wrapper to xpopen with a pipe for just one of stdin/stdout
    326 pid_t xpopen(char **argv, int *pipe, int isstdout)
    327 {
    328   int pipes[2], pid;
    329 
    330   pipes[0] = isstdout ? 0 : -1;
    331   pipes[1] = isstdout ? -1 : 1;
    332   pid = xpopen_both(argv, pipes);
    333   *pipe = pid ? pipes[!!isstdout] : -1;
    334 
    335   return pid;
    336 }
    337 
    338 int xpclose(pid_t pid, int pipe)
    339 {
    340   close(pipe);
    341 
    342   return xpclose_both(pid, 0);
    343 }
    344 
    345 // Call xpopen and wait for it to finish, keeping existing stdin/stdout.
    346 int xrun(char **argv)
    347 {
    348   return xpclose_both(xpopen_both(argv, 0), 0);
    349 }
    350 
    351 void xaccess(char *path, int flags)
    352 {
    353   if (access(path, flags)) perror_exit("Can't access '%s'", path);
    354 }
    355 
    356 // Die unless we can delete a file.  (File must exist to be deleted.)
    357 void xunlink(char *path)
    358 {
    359   if (unlink(path)) perror_exit("unlink '%s'", path);
    360 }
    361 
    362 // Die unless we can open/create a file, returning file descriptor.
    363 // The meaning of O_CLOEXEC is reversed (it defaults on, pass it to disable)
    364 // and WARN_ONLY tells us not to exit.
    365 int xcreate_stdio(char *path, int flags, int mode)
    366 {
    367   int fd = open(path, (flags^O_CLOEXEC)&~WARN_ONLY, mode);
    368 
    369   if (fd == -1) ((mode&WARN_ONLY) ? perror_msg_raw : perror_exit_raw)(path);
    370   return fd;
    371 }
    372 
    373 // Die unless we can open a file, returning file descriptor.
    374 int xopen_stdio(char *path, int flags)
    375 {
    376   return xcreate_stdio(path, flags, 0);
    377 }
    378 
    379 void xpipe(int *pp)
    380 {
    381   if (pipe(pp)) perror_exit("xpipe");
    382 }
    383 
    384 void xclose(int fd)
    385 {
    386   if (close(fd)) perror_exit("xclose");
    387 }
    388 
    389 int xdup(int fd)
    390 {
    391   if (fd != -1) {
    392     fd = dup(fd);
    393     if (fd == -1) perror_exit("xdup");
    394   }
    395   return fd;
    396 }
    397 
    398 // Move file descriptor above stdin/stdout/stderr, using /dev/null to consume
    399 // old one. (We should never be called with stdin/stdout/stderr closed, but...)
    400 int notstdio(int fd)
    401 {
    402   if (fd<0) return fd;
    403 
    404   while (fd<3) {
    405     int fd2 = xdup(fd);
    406 
    407     close(fd);
    408     xopen_stdio("/dev/null", O_RDWR);
    409     fd = fd2;
    410   }
    411 
    412   return fd;
    413 }
    414 
    415 void xrename(char *from, char *to)
    416 {
    417   if (rename(from, to)) perror_exit("rename %s -> %s", from, to);
    418 }
    419 
    420 int xtempfile(char *name, char **tempname)
    421 {
    422   int fd;
    423 
    424    *tempname = xmprintf("%s%s", name, "XXXXXX");
    425   if(-1 == (fd = mkstemp(*tempname))) error_exit("no temp file");
    426 
    427   return fd;
    428 }
    429 
    430 // Create a file but don't return stdin/stdout/stderr
    431 int xcreate(char *path, int flags, int mode)
    432 {
    433   return notstdio(xcreate_stdio(path, flags, mode));
    434 }
    435 
    436 // Open a file descriptor NOT in stdin/stdout/stderr
    437 int xopen(char *path, int flags)
    438 {
    439   return notstdio(xopen_stdio(path, flags));
    440 }
    441 
    442 // Open read only, treating "-" as a synonym for stdin, defaulting to warn only
    443 int openro(char *path, int flags)
    444 {
    445   if (!strcmp(path, "-")) return 0;
    446 
    447   return xopen(path, flags^WARN_ONLY);
    448 }
    449 
    450 // Open read only, treating "-" as a synonym for stdin.
    451 int xopenro(char *path)
    452 {
    453   return openro(path, O_RDONLY|WARN_ONLY);
    454 }
    455 
    456 FILE *xfdopen(int fd, char *mode)
    457 {
    458   FILE *f = fdopen(fd, mode);
    459 
    460   if (!f) perror_exit("xfdopen");
    461 
    462   return f;
    463 }
    464 
    465 // Die unless we can open/create a file, returning FILE *.
    466 FILE *xfopen(char *path, char *mode)
    467 {
    468   FILE *f = fopen(path, mode);
    469   if (!f) perror_exit("No file %s", path);
    470   return f;
    471 }
    472 
    473 // Die if there's an error other than EOF.
    474 size_t xread(int fd, void *buf, size_t len)
    475 {
    476   ssize_t ret = read(fd, buf, len);
    477   if (ret < 0) perror_exit("xread");
    478 
    479   return ret;
    480 }
    481 
    482 void xreadall(int fd, void *buf, size_t len)
    483 {
    484   if (len != readall(fd, buf, len)) perror_exit("xreadall");
    485 }
    486 
    487 // There's no xwriteall(), just xwrite().  When we read, there may or may not
    488 // be more data waiting.  When we write, there is data and it had better go
    489 // somewhere.
    490 
    491 void xwrite(int fd, void *buf, size_t len)
    492 {
    493   if (len != writeall(fd, buf, len)) perror_exit("xwrite");
    494 }
    495 
    496 // Die if lseek fails, probably due to being called on a pipe.
    497 
    498 off_t xlseek(int fd, off_t offset, int whence)
    499 {
    500   offset = lseek(fd, offset, whence);
    501   if (offset<0) perror_exit("lseek");
    502 
    503   return offset;
    504 }
    505 
    506 char *xgetcwd(void)
    507 {
    508   char *buf = getcwd(NULL, 0);
    509   if (!buf) perror_exit("xgetcwd");
    510 
    511   return buf;
    512 }
    513 
    514 void xstat(char *path, struct stat *st)
    515 {
    516   if(stat(path, st)) perror_exit("Can't stat %s", path);
    517 }
    518 
    519 // Canonicalize path, even to file with one or more missing components at end.
    520 // Returns allocated string for pathname or NULL if doesn't exist
    521 // exact = 1 file must exist, 0 dir must exist, -1 show theoretical location
    522 char *xabspath(char *path, int exact)
    523 {
    524   struct string_list *todo, *done = 0;
    525   int try = 9999, dirfd = open("/", O_PATH), missing = 0;
    526   char *ret;
    527 
    528   // If this isn't an absolute path, start with cwd.
    529   if (*path != '/') {
    530     char *temp = xgetcwd();
    531 
    532     splitpath(path, splitpath(temp, &todo));
    533     free(temp);
    534   } else splitpath(path, &todo);
    535 
    536   // Iterate through path components in todo, prepend processed ones to done.
    537   while (todo) {
    538     struct string_list *new = llist_pop(&todo), **tail;
    539     ssize_t len;
    540 
    541     // Eventually break out of endless loops
    542     if (!try--) {
    543       errno = ELOOP;
    544       goto error;
    545     }
    546 
    547     // Removable path componenents.
    548     if (!strcmp(new->str, ".") || !strcmp(new->str, "..")) {
    549       int x = new->str[1];
    550 
    551       free(new);
    552       if (!x) continue;
    553       if (done) free(llist_pop(&done));
    554       len = 0;
    555 
    556       if (missing) missing--;
    557       else {
    558         if (-1 == (x = openat(dirfd, "..", O_PATH))) goto error;
    559         close(dirfd);
    560         dirfd = x;
    561       }
    562       continue;
    563     }
    564 
    565     // Is this a symlink?
    566     len = readlinkat(dirfd, new->str, libbuf, sizeof(libbuf));
    567     if (len>4095) goto error;
    568 
    569     // Not a symlink: add to linked list, move dirfd, fail if error
    570     if (len<1) {
    571       int fd;
    572 
    573       new->next = done;
    574       done = new;
    575       if (errno == EINVAL && !todo) break;
    576       if (errno == ENOENT && exact<0) {
    577         missing++;
    578         continue;
    579       }
    580       if (errno != EINVAL && (exact || todo)) goto error;
    581 
    582       fd = openat(dirfd, new->str, O_PATH);
    583       if (fd == -1 && (exact || todo || errno != ENOENT)) goto error;
    584       close(dirfd);
    585       dirfd = fd;
    586       continue;
    587     }
    588 
    589     // If this symlink is to an absolute path, discard existing resolved path
    590     libbuf[len] = 0;
    591     if (*libbuf == '/') {
    592       llist_traverse(done, free);
    593       done=0;
    594       close(dirfd);
    595       dirfd = open("/", O_PATH);
    596     }
    597     free(new);
    598 
    599     // prepend components of new path. Note symlink to "/" will leave new NULL
    600     tail = splitpath(libbuf, &new);
    601 
    602     // symlink to "/" will return null and leave tail alone
    603     if (new) {
    604       *tail = todo;
    605       todo = new;
    606     }
    607   }
    608   close(dirfd);
    609 
    610   // At this point done has the path, in reverse order. Reverse list while
    611   // calculating buffer length.
    612 
    613   try = 2;
    614   while (done) {
    615     struct string_list *temp = llist_pop(&done);
    616 
    617     if (todo) try++;
    618     try += strlen(temp->str);
    619     temp->next = todo;
    620     todo = temp;
    621   }
    622 
    623   // Assemble return buffer
    624 
    625   ret = xmalloc(try);
    626   *ret = '/';
    627   ret [try = 1] = 0;
    628   while (todo) {
    629     if (try>1) ret[try++] = '/';
    630     try = stpcpy(ret+try, todo->str) - ret;
    631     free(llist_pop(&todo));
    632   }
    633 
    634   return ret;
    635 
    636 error:
    637   close(dirfd);
    638   llist_traverse(todo, free);
    639   llist_traverse(done, free);
    640 
    641   return 0;
    642 }
    643 
    644 void xchdir(char *path)
    645 {
    646   if (chdir(path)) perror_exit("chdir '%s'", path);
    647 }
    648 
    649 void xchroot(char *path)
    650 {
    651   if (chroot(path)) error_exit("chroot '%s'", path);
    652   xchdir("/");
    653 }
    654 
    655 struct passwd *xgetpwuid(uid_t uid)
    656 {
    657   struct passwd *pwd = getpwuid(uid);
    658   if (!pwd) error_exit("bad uid %ld", (long)uid);
    659   return pwd;
    660 }
    661 
    662 struct group *xgetgrgid(gid_t gid)
    663 {
    664   struct group *group = getgrgid(gid);
    665 
    666   if (!group) perror_exit("gid %ld", (long)gid);
    667   return group;
    668 }
    669 
    670 unsigned xgetuid(char *name)
    671 {
    672   struct passwd *up = getpwnam(name);
    673   char *s = 0;
    674   long uid;
    675 
    676   if (up) return up->pw_uid;
    677 
    678   uid = estrtol(name, &s, 10);
    679   if (!errno && s && !*s && uid>=0 && uid<=UINT_MAX) return uid;
    680 
    681   error_exit("bad user '%s'", name);
    682 }
    683 
    684 unsigned xgetgid(char *name)
    685 {
    686   struct group *gr = getgrnam(name);
    687   char *s = 0;
    688   long gid;
    689 
    690   if (gr) return gr->gr_gid;
    691 
    692   gid = estrtol(name, &s, 10);
    693   if (!errno && s && !*s && gid>=0 && gid<=UINT_MAX) return gid;
    694 
    695   error_exit("bad group '%s'", name);
    696 }
    697 
    698 struct passwd *xgetpwnam(char *name)
    699 {
    700   struct passwd *up = getpwnam(name);
    701 
    702   if (!up) perror_exit("user '%s'", name);
    703   return up;
    704 }
    705 
    706 struct group *xgetgrnam(char *name)
    707 {
    708   struct group *gr = getgrnam(name);
    709 
    710   if (!gr) perror_exit("group '%s'", name);
    711   return gr;
    712 }
    713 
    714 // setuid() can fail (for example, too many processes belonging to that user),
    715 // which opens a security hole if the process continues as the original user.
    716 
    717 void xsetuser(struct passwd *pwd)
    718 {
    719   if (initgroups(pwd->pw_name, pwd->pw_gid) || setgid(pwd->pw_uid)
    720       || setuid(pwd->pw_uid)) perror_exit("xsetuser '%s'", pwd->pw_name);
    721 }
    722 
    723 // This can return null (meaning file not found).  It just won't return null
    724 // for memory allocation reasons.
    725 char *xreadlink(char *name)
    726 {
    727   int len, size = 0;
    728   char *buf = 0;
    729 
    730   // Grow by 64 byte chunks until it's big enough.
    731   for(;;) {
    732     size +=64;
    733     buf = xrealloc(buf, size);
    734     len = readlink(name, buf, size);
    735 
    736     if (len<0) {
    737       free(buf);
    738       return 0;
    739     }
    740     if (len<size) {
    741       buf[len]=0;
    742       return buf;
    743     }
    744   }
    745 }
    746 
    747 char *xreadfile(char *name, char *buf, off_t len)
    748 {
    749   if (!(buf = readfile(name, buf, len))) perror_exit("Bad '%s'", name);
    750 
    751   return buf;
    752 }
    753 
    754 // The data argument to ioctl() is actually long, but it's usually used as
    755 // a pointer. If you need to feed in a number, do (void *)(long) typecast.
    756 int xioctl(int fd, int request, void *data)
    757 {
    758   int rc;
    759 
    760   errno = 0;
    761   rc = ioctl(fd, request, data);
    762   if (rc == -1 && errno) perror_exit("ioctl %x", request);
    763 
    764   return rc;
    765 }
    766 
    767 // Open a /var/run/NAME.pid file, dying if we can't write it or if it currently
    768 // exists and is this executable.
    769 void xpidfile(char *name)
    770 {
    771   char pidfile[256], spid[32];
    772   int i, fd;
    773   pid_t pid;
    774 
    775   sprintf(pidfile, "/var/run/%s.pid", name);
    776   // Try three times to open the sucker.
    777   for (i=0; i<3; i++) {
    778     fd = open(pidfile, O_CREAT|O_EXCL|O_WRONLY, 0644);
    779     if (fd != -1) break;
    780 
    781     // If it already existed, read it.  Loop for race condition.
    782     fd = open(pidfile, O_RDONLY);
    783     if (fd == -1) continue;
    784 
    785     // Is the old program still there?
    786     spid[xread(fd, spid, sizeof(spid)-1)] = 0;
    787     close(fd);
    788     pid = atoi(spid);
    789     if (pid < 1 || (kill(pid, 0) && errno == ESRCH)) unlink(pidfile);
    790 
    791     // An else with more sanity checking might be nice here.
    792   }
    793 
    794   if (i == 3) error_exit("xpidfile %s", name);
    795 
    796   xwrite(fd, spid, sprintf(spid, "%ld\n", (long)getpid()));
    797   close(fd);
    798 }
    799 
    800 // Return bytes copied from in to out. If bytes <0 copy all of in to out.
    801 long long sendfile_len(int in, int out, long long bytes)
    802 {
    803   long long total = 0;
    804   long len;
    805 
    806   if (in<0) return 0;
    807   for (;;) {
    808     if (bytes == total) break;
    809     len = bytes-total;
    810     if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf);
    811 
    812     len = xread(in, libbuf, len);
    813     if (len<1) break;
    814     xwrite(out, libbuf, len);
    815     total += len;
    816   }
    817 
    818   return total;
    819 }
    820 
    821 // error_exit if we couldn't copy all bytes
    822 long long xsendfile_len(int in, int out, long long bytes)
    823 {
    824   long long len = sendfile_len(in, out, bytes);
    825 
    826   if (bytes != -1 && bytes != len) error_exit("short file");
    827 
    828   return len;
    829 }
    830 
    831 // warn and pad with zeroes if we couldn't copy all bytes
    832 void xsendfile_pad(int in, int out, long long len)
    833 {
    834   len -= xsendfile_len(in, out, len);
    835   if (len) {
    836     perror_msg("short read");
    837     memset(libbuf, 0, sizeof(libbuf));
    838     while (len) {
    839       int i = len>sizeof(libbuf) ? sizeof(libbuf) : len;
    840 
    841       xwrite(out, libbuf, i);
    842       len -= i;
    843     }
    844   }
    845 }
    846 
    847 // copy all of in to out
    848 long long xsendfile(int in, int out)
    849 {
    850   return xsendfile_len(in, out, -1);
    851 }
    852 
    853 double xstrtod(char *s)
    854 {
    855   char *end;
    856   double d;
    857 
    858   errno = 0;
    859   d = strtod(s, &end);
    860   if (!errno && *end) errno = E2BIG;
    861   if (errno) perror_exit("strtod %s", s);
    862 
    863   return d;
    864 }
    865 
    866 // parse fractional seconds with optional s/m/h/d suffix
    867 long xparsetime(char *arg, long zeroes, long *fraction)
    868 {
    869   long l, fr = 0, mask = 1;
    870   char *end;
    871 
    872   if (*arg != '.' && !isdigit(*arg)) error_exit("Not a number '%s'", arg);
    873   l = strtoul(arg, &end, 10);
    874   if (*end == '.') {
    875     end++;
    876     while (zeroes--) {
    877       fr *= 10;
    878       mask *= 10;
    879       if (isdigit(*end)) fr += *end++-'0';
    880     }
    881     while (isdigit(*end)) end++;
    882   }
    883 
    884   // Parse suffix
    885   if (*end) {
    886     int ismhd[]={1,60,3600,86400}, i = stridx("smhd", *end);
    887 
    888     if (i == -1 || *(end+1)) error_exit("Unknown suffix '%s'", end);
    889     l *= ismhd[i];
    890     fr *= ismhd[i];
    891     l += fr/mask;
    892     fr %= mask;
    893   }
    894   if (fraction) *fraction = fr;
    895 
    896   return l;
    897 }
    898 
    899 long long xparsemillitime(char *arg)
    900 {
    901   long l, ll;
    902 
    903   l = xparsetime(arg, 3, &ll);
    904 
    905   return (l*1000LL)+ll;
    906 }
    907 
    908 
    909 
    910 // Compile a regular expression into a regex_t
    911 void xregcomp(regex_t *preg, char *regex, int cflags)
    912 {
    913   int rc = regcomp(preg, regex, cflags);
    914 
    915   if (rc) {
    916     regerror(rc, preg, libbuf, sizeof(libbuf));
    917     error_exit("xregcomp: %s", libbuf);
    918   }
    919 }
    920 
    921 char *xtzset(char *new)
    922 {
    923   char *old = getenv("TZ");
    924 
    925   if (old) old = xstrdup(old);
    926   if (new ? setenv("TZ", new, 1) : unsetenv("TZ")) perror_exit("setenv");
    927   tzset();
    928 
    929   return old;
    930 }
    931 
    932 // Set a signal handler
    933 void xsignal_flags(int signal, void *handler, int flags)
    934 {
    935   struct sigaction *sa = (void *)libbuf;
    936 
    937   memset(sa, 0, sizeof(struct sigaction));
    938   sa->sa_handler = handler;
    939   sa->sa_flags = flags;
    940 
    941   if (sigaction(signal, sa, 0)) perror_exit("xsignal %d", signal);
    942 }
    943 
    944 void xsignal(int signal, void *handler)
    945 {
    946   xsignal_flags(signal, handler, 0);
    947 }
    948 
    949 
    950 time_t xvali_date(struct tm *tm, char *str)
    951 {
    952   time_t t;
    953 
    954   if (tm && (unsigned)tm->tm_sec<=60 && (unsigned)tm->tm_min<=59
    955      && (unsigned)tm->tm_hour<=23 && tm->tm_mday && (unsigned)tm->tm_mday<=31
    956      && (unsigned)tm->tm_mon<=11 && (t = mktime(tm)) != -1) return t;
    957 
    958   error_exit("bad date %s", str);
    959 }
    960 
    961 // Parse date string (relative to current *t). Sets time_t and nanoseconds.
    962 void xparsedate(char *str, time_t *t, unsigned *nano, int endian)
    963 {
    964   struct tm tm;
    965   time_t now = *t;
    966   int len = 0, i = 0;
    967   // Formats with seconds come first. Posix can't agree on whether 12 digits
    968   // has year before (touch -t) or year after (date), so support both.
    969   char *s = str, *p, *oldtz = 0, *formats[] = {"%Y-%m-%d %T", "%Y-%m-%dT%T",
    970     "%H:%M:%S", "%Y-%m-%d %H:%M", "%Y-%m-%d", "%H:%M", "%m%d%H%M",
    971     endian ? "%m%d%H%M%y" : "%y%m%d%H%M",
    972     endian ? "%m%d%H%M%C%y" : "%C%y%m%d%H%M"};
    973 
    974   *nano = 0;
    975 
    976   // Parse @UNIXTIME[.FRACTION]
    977   if (*str == '@') {
    978     long long ll;
    979 
    980     // Collect seconds and nanoseconds.
    981     // &ll is not just t because we can't guarantee time_t is 64 bit (yet).
    982     sscanf(s, "@%lld%n", &ll, &len);
    983     if (s[len]=='.') {
    984       s += len+1;
    985       for (len = 0; len<9; len++) {
    986         *nano *= 10;
    987         if (isdigit(*s)) *nano += *s++-'0';
    988       }
    989     }
    990     *t = ll;
    991     if (!s[len]) return;
    992     xvali_date(0, str);
    993   }
    994 
    995   // Trailing Z means UTC timezone, don't expect libc to know this.
    996   // (Trimming it off here means it won't show up in error messages.)
    997   if ((i = strlen(str)) && toupper(str[i-1])=='Z') {
    998     str[--i] = 0;
    999     oldtz = getenv("TZ");
   1000     if (oldtz) oldtz = xstrdup(oldtz);
   1001     setenv("TZ", "UTC0", 1);
   1002   }
   1003 
   1004   // Try each format
   1005   for (i = 0; i<ARRAY_LEN(formats); i++) {
   1006     localtime_r(&now, &tm);
   1007     tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
   1008     tm.tm_isdst = -endian;
   1009 
   1010     if ((p = strptime(s, formats[i], &tm))) {
   1011       if (*p == '.') {
   1012         p++;
   1013         // If format didn't already specify seconds, grab seconds
   1014         if (i>2) {
   1015           len = 0;
   1016           sscanf(p, "%2u%n", &tm.tm_sec, &len);
   1017           p += len;
   1018         }
   1019         // nanoseconds
   1020         for (len = 0; len<9; len++) {
   1021           *nano *= 10;
   1022           if (isdigit(*p)) *nano += *p++-'0';
   1023         }
   1024       }
   1025 
   1026       if (!*p) break;
   1027     }
   1028   }
   1029 
   1030   // Sanity check field ranges
   1031   *t = xvali_date((i!=ARRAY_LEN(formats)) ? &tm : 0, str);
   1032 
   1033   if (oldtz) setenv("TZ", oldtz, 1);
   1034   free(oldtz);
   1035 }
   1036