# HG changeset patch # User Rob Landley # Date 1410715784 18000 # Node ID 2f9bc9495144f8c22d4ef5ea6cdb56ff7d9efcf9 # Parent b748127e092ee2530a67ce6f77e3285e2178eaec Split xpopen() into xpopen_both(), xpopen(), and xrun() depending on whether we want to redirect both, one, or neither of stdin/stdout. diff -r b748127e092e -r 2f9bc9495144 lib/lib.h --- a/lib/lib.h Sat Sep 13 14:48:37 2014 -0500 +++ b/lib/lib.h Sun Sep 14 12:29:44 2014 -0500 @@ -95,8 +95,12 @@ 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 -r b748127e092e -r 2f9bc9495144 lib/xwrap.c --- a/lib/xwrap.c Sat Sep 13 14:48:37 2014 -0500 +++ b/lib/xwrap.c Sun Sep 14 12:29:44 2014 -0500 @@ -145,33 +145,41 @@ // 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]); + } } - dup2(cestnepasun[3], 1); - dup2(cestnepasun[3], 2); - if (cestnepasun[3] > 2) close(cestnepasun[3]); + if (pipes[1] != -1) { + dup2(cestnepasun[3], 1); + dup2(cestnepasun[3], 2); + if (cestnepasun[3] > 2 || !cestnepasun[3]) close(cestnepasun[3]); + } } if (argv) { if (CFG_TOYBOX) toy_exec(argv); @@ -180,18 +188,18 @@ } return 0; + } + // Parent process - } else { - if (pipes) { - close(cestnepasun[0]); - close(cestnepasun[3]); - } + if (pipes) { + if (pipes[0] != -1) close(cestnepasun[0]); + if (pipes[1] != -1) close(cestnepasun[3]); + } - return pid; - } + return pid; } -int xpclose(pid_t pid, int *pipes) +int xpclose_both(pid_t pid, int *pipes) { int rc = 127; @@ -204,6 +212,30 @@ 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 -r b748127e092e -r 2f9bc9495144 toys/lsb/mount.c --- a/toys/lsb/mount.c Sat Sep 13 14:48:37 2014 -0500 +++ b/toys/lsb/mount.c Sun Sep 14 12:29:44 2014 -0500 @@ -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 @@ 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 @@ } 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 @@ 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 -r b748127e092e -r 2f9bc9495144 toys/other/inotifyd.c --- a/toys/other/inotifyd.c Sat Sep 13 14:48:37 2014 -0500 +++ b/toys/other/inotifyd.c Sun Sep 14 12:29:44 2014 -0500 @@ -104,7 +104,7 @@ 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 -r b748127e092e -r 2f9bc9495144 toys/posix/cp.c --- a/toys/posix/cp.c Sat Sep 13 14:48:37 2014 -0500 +++ b/toys/posix/cp.c Sun Sep 14 12:29:44 2014 -0500 @@ -341,8 +341,7 @@ // 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 -r b748127e092e -r 2f9bc9495144 toys/posix/find.c --- a/toys/posix/find.c Sat Sep 13 14:48:37 2014 -0500 +++ b/toys/posix/find.c Sun Sep 14 12:29:44 2014 -0500 @@ -102,7 +102,7 @@ newargs[pos+rest] = 0; } - rc = xpclose(xpopen(newargs, 0), 0); + rc = xrun(newargs); llist_traverse(*dl, llist_free_double); *dl = 0;