diff options
| -rw-r--r-- | lib/lib.h | 8 | ||||
| -rw-r--r-- | lib/xwrap.c | 78 | ||||
| -rw-r--r-- | toys/lsb/mount.c | 19 | ||||
| -rw-r--r-- | toys/other/inotifyd.c | 2 | ||||
| -rw-r--r-- | toys/posix/cp.c | 3 | ||||
| -rw-r--r-- | toys/posix/find.c | 2 | 
6 files changed, 78 insertions, 34 deletions
| @@ -95,8 +95,12 @@ void xflush(void);  pid_t xfork(void);  void xexec_optargs(int skip);  void xexec(char **argv); -pid_t xpopen(char **argv, int *pipes); -int xpclose(pid_t pid, int *pipes); +pid_t xpopen_both(char **argv, int *pipes); +int xpclose_both(pid_t pid, int *pipes); +pid_t xpopen(char **argv, int *pipe, int stdout); +pid_t xpclose(pid_t pid, int pipe); +int xrun(char **argv); +int xpspawn(char **argv, int*pipes);  void xaccess(char *path, int flags);  void xunlink(char *path);  int xcreate(char *path, int flags, int mode); diff --git a/lib/xwrap.c b/lib/xwrap.c index c9d1876f..64b183ff 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -145,33 +145,41 @@ void xexec(char **argv)  // Spawn child process, capturing stdin/stdout.  // argv[]: command to exec. If null, child returns to original program. -// pipes[]: stdin, stdout of new process. If null, block and wait for child. +// pipes[2]: stdin, stdout of new process. If -1 will not have pipe allocated.  // return: pid of child process -pid_t xpopen(char **argv, int *pipes) +pid_t xpopen_both(char **argv, int *pipes)  {    int cestnepasun[4], pid; -  // Make the pipes? +  // Make the pipes? Not this won't set either pipe to 0 because if fds are +  // allocated in order and if fd0 was free it would go to cestnepasun[0]    if (pipes) { -    if (pipe(cestnepasun) || pipe(cestnepasun+2)) perror_exit("pipe"); -    pipes[0] = cestnepasun[1]; -    pipes[1] = cestnepasun[2]; +    for (pid = 0; pid < 2; pid++) { +      if (pipes[pid] == -1) continue; +      if (pipe(cestnepasun+(2*pid))) perror_exit("pipe"); +      pipes[pid] = cestnepasun[pid+1]; +    }    }    // Child process    if (!(pid = xfork())) {      // Dance of the stdin/stdout redirection.      if (pipes) { -      close(cestnepasun[1]); -      close(cestnepasun[2]); -      // if we had no stdin/out, pipe handles could overlap, so test for that -      if (cestnepasun[0]) { -        dup2(cestnepasun[0], 0); -        close(cestnepasun[0]); +      // if we had no stdin/out, pipe handles could overlap, so test for it +      // and free up potentially overlapping pipe handles before reuse +      if (pipes[1] != -1) close(cestnepasun[2]); +      if (pipes[0] != -1) { +        close(cestnepasun[1]); +        if (cestnepasun[0]) { +          dup2(cestnepasun[0], 0); +          close(cestnepasun[0]); +        } +      } +      if (pipes[1] != -1) { +        dup2(cestnepasun[3], 1); +        dup2(cestnepasun[3], 2); +        if (cestnepasun[3] > 2 || !cestnepasun[3]) close(cestnepasun[3]);        } -      dup2(cestnepasun[3], 1); -      dup2(cestnepasun[3], 2); -      if (cestnepasun[3] > 2) close(cestnepasun[3]);      }      if (argv) {        if (CFG_TOYBOX) toy_exec(argv); @@ -180,18 +188,18 @@ pid_t xpopen(char **argv, int *pipes)      }      return 0; -  // Parent process -  } else { -    if (pipes) { -      close(cestnepasun[0]); -      close(cestnepasun[3]); -    } +  } -    return pid; +  // Parent process +  if (pipes) { +    if (pipes[0] != -1) close(cestnepasun[0]); +    if (pipes[1] != -1) close(cestnepasun[3]);    } + +  return pid;  } -int xpclose(pid_t pid, int *pipes) +int xpclose_both(pid_t pid, int *pipes)  {    int rc = 127; @@ -204,6 +212,30 @@ int xpclose(pid_t pid, int *pipes)    return WIFEXITED(rc) ? WEXITSTATUS(rc) : WTERMSIG(rc) + 127;  } +// Wrapper to xpopen with a pipe for just one of stdin/stdout +pid_t xpopen(char **argv, int *pipe, int stdout) +{ +  int pipes[2]; + +  pipe[!stdout] = -1; +  pipe[!!stdout] = 0; + +  return xpopen_both(argv, pipes); +} + +int xpclose(pid_t pid, int pipe) +{ +  close(pipe); + +  return xpclose_both(pid, 0); +} + +// Call xpopen and wait for it to finish, keeping existing stdin/stdout. +int xrun(char **argv) +{ +  return xpclose_both(xpopen_both(argv, 0), 0); +} +  void xaccess(char *path, int flags)  {    if (access(path, flags)) perror_exit("Can't access '%s'", path); diff --git a/toys/lsb/mount.c b/toys/lsb/mount.c index 949fb05d..39d98caf 100644 --- a/toys/lsb/mount.c +++ b/toys/lsb/mount.c @@ -7,6 +7,7 @@   * no mtab (/proc/mounts does it) so -n is NOP.  USE_MOUNT(NEWTOY(mount, "?O:afnrvwt:o*[-rw]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT)) +USE_NFSMOUNT(NEWTOY(nfsmount, "?<2>2", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))  config MOUNT    bool "mount" @@ -32,6 +33,14 @@ config MOUNT      bind mounts (file on file, directory on directory), so you don't need      to say --bind or --loop. You can also "mount -a /path" to mount everything      in /etc/fstab under /path, even if it's noauto. + +config NFSMOUNT +  bool "nfsmount" +  default n +  help +    usage: nfsmount SHARE DIR + +    Invoke an eldrich horror from the dawn of time.  */  #define FOR_mount @@ -155,7 +164,7 @@ static void mount_filesystem(char *dev, char *dir, char *type,      } else fp = xfopen("/proc/filesystems", "r");    } else if (!strcmp(type, "ignore")) return;    else if (!strcmp(type, "swap")) -    toys.exitval |= xpclose(xpopen((char *[]){"swapon", "--", dev, 0}, 0), 0); +    toys.exitval |= xrun((char *[]){"swapon", "--", dev, 0});    for (;;) {      char *buf = 0; @@ -204,13 +213,13 @@ static void mount_filesystem(char *dev, char *dir, char *type,      if (errno == ENOTBLK) {        char *losetup[] = {"losetup", "-fs", dev, 0}; -      int pipes[2], len; +      int pipe, len;        pid_t pid;        if (flags & MS_RDONLY) losetup[1] = "-fsr"; -      pid = xpopen(losetup, pipes); -      len = readall(pipes[1], toybuf, sizeof(toybuf)-1); -      rc = xpclose(pid, pipes); +      pid = xpopen(losetup, &pipe, 1); +      len = readall(pipe, toybuf, sizeof(toybuf)-1); +      rc = xpclose(pid, pipe);        if (!rc && len > 1) {          if (toybuf[len-1] == '\n') --len;          toybuf[len] = 0; diff --git a/toys/other/inotifyd.c b/toys/other/inotifyd.c index 59c9a50c..f2e11ca4 100644 --- a/toys/other/inotifyd.c +++ b/toys/other/inotifyd.c @@ -104,7 +104,7 @@ void inotifyd_main(void)            prog_args[1] = toybuf;            prog_args[2] = toys.optargs[event->wd];            prog_args[3] = event->len ? event->name : 0; -          xpclose(xpopen(prog_args, 0), 0); +          xrun(prog_args);          }          if (event->mask & IN_IGNORED) { diff --git a/toys/posix/cp.c b/toys/posix/cp.c index d79819b2..d73b7229 100644 --- a/toys/posix/cp.c +++ b/toys/posix/cp.c @@ -341,8 +341,7 @@ static int install_node(struct dirtree *try)    // No -r so always one level deep, so destname as set by cp_node() is correct    if (toys.optflags & FLAG_s) -    if (xpclose(xpopen((char *[]){"strip", "-p", TT.destname, 0}, 0), 0)) -      toys.exitval = 1; +    if (xrun((char *[]){"strip", "-p", TT.destname, 0})) toys.exitval = 1;    return 0;  } diff --git a/toys/posix/find.c b/toys/posix/find.c index b74cb88e..9f679a02 100644 --- a/toys/posix/find.c +++ b/toys/posix/find.c @@ -102,7 +102,7 @@ static int flush_exec(struct dirtree *new, struct exec_range *aa)      newargs[pos+rest] = 0;    } -  rc = xpclose(xpopen(newargs, 0), 0); +  rc = xrun(newargs);    llist_traverse(*dl, llist_free_double);    *dl = 0; | 
