}
pid_t pipecmdv(int *fd_fromchild, int *fd_tochild, const char *cmd, va_list ap)
+{
+ char **arr = gather_args(cmd, ap);
+ pid_t ret;
+
+ if (!arr) {
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = pipecmdarr(fd_fromchild, fd_tochild, arr);
+ free_noerr(arr);
+ return ret;
+}
+
+pid_t pipecmdarr(int *fd_fromchild, int *fd_tochild, char *const *arr)
{
int tochild[2], fromchild[2], execfail[2];
pid_t childpid;
goto close_execfail_fail;
if (childpid == 0) {
- char **args = gather_args(cmd, ap);
-
if (fd_tochild)
close(tochild[1]);
if (fd_fromchild)
close(execfail[0]);
// Child runs command.
- if (!args)
- err = ENOMEM;
- else {
- if (tochild[0] != STDIN_FILENO) {
- if (dup2(tochild[0], STDIN_FILENO) == -1)
- goto child_errno_fail;
- close(tochild[0]);
- }
- if (fromchild[1] != STDOUT_FILENO) {
- if (dup2(fromchild[1], STDOUT_FILENO) == -1)
- goto child_errno_fail;
- close(fromchild[1]);
- }
- execvp(cmd, args);
- child_errno_fail:
- err = errno;
+ if (tochild[0] != STDIN_FILENO) {
+ if (dup2(tochild[0], STDIN_FILENO) == -1)
+ goto child_errno_fail;
+ close(tochild[0]);
+ }
+ if (fromchild[1] != STDOUT_FILENO) {
+ if (dup2(fromchild[1], STDOUT_FILENO) == -1)
+ goto child_errno_fail;
+ close(fromchild[1]);
}
+ execvp(arr[0], arr);
+
+ child_errno_fail:
+ err = errno;
write(execfail[1], &err, sizeof(err));
exit(127);
}
close(execfail[1]);
/* Child will close this without writing on successful exec. */
if (read(execfail[0], &err, sizeof(err)) == sizeof(err)) {
+ close(execfail[0]);
waitpid(childpid, NULL, 0);
errno = err;
return -1;
}
+ close(execfail[0]);
if (fd_tochild)
*fd_tochild = tochild[1];
if (fd_fromchild)