Mercurial > hg > toybox
diff lib/xwrap.c @ 1334:9fd2bcedbeb5 draft
mount: start on option parsing, implement loopback and bind mount autodetection.
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 03 Jun 2014 06:27:24 -0500 |
parents | 85f297591693 |
children | 31cb9ba1815c |
line wrap: on
line diff
--- a/lib/xwrap.c Mon Jun 02 21:16:20 2014 -0500 +++ b/lib/xwrap.c Tue Jun 03 06:27:24 2014 -0500 @@ -143,6 +143,67 @@ perror_exit("exec %s", argv[0]); } +// 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. +// return: pid of child process +pid_t xpopen(char **argv, int *pipes) +{ + int cestnepasun[4], pid; + + // Make the pipes? + if (pipes) { + if (pipe(cestnepasun) || pipe(cestnepasun+2)) perror_exit("pipe"); + pipes[0] = cestnepasun[1]; + pipes[1] = cestnepasun[2]; + } + + // 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]); + } + dup2(cestnepasun[3], 1); + dup2(cestnepasun[3], 2); + if (cestnepasun[3] > 2) close(cestnepasun[3]); + } + if (argv) { + if (CFG_TOYBOX) toy_exec(argv); + execvp(argv[0], argv); + _exit(127); + } + return 0; + + // Parent process + } else { + if (pipes) { + close(cestnepasun[0]); + close(cestnepasun[3]); + } + + return pid; + } +} + +int xpclose(pid_t pid, int *pipes) +{ + int rc = 127; + + if (pipes) { + close(pipes[0]); + close(pipes[1]); + } + waitpid(pid, &rc, 0); + + return WIFEXITED(rc) ? WEXITSTATUS(rc) : WTERMSIG(rc) + 127; +} + void xaccess(char *path, int flags) { if (access(path, flags)) perror_exit("Can't access '%s'", path);