0001
0002 #include <unistd.h>
0003 #include <sys/types.h>
0004 #include <sys/stat.h>
0005 #include <fcntl.h>
0006 #include <string.h>
0007 #include <linux/string.h>
0008 #include <errno.h>
0009 #include <sys/wait.h>
0010 #include "subcmd-util.h"
0011 #include "run-command.h"
0012 #include "exec-cmd.h"
0013
0014 #define STRERR_BUFSIZE 128
0015
0016 static inline void close_pair(int fd[2])
0017 {
0018 close(fd[0]);
0019 close(fd[1]);
0020 }
0021
0022 static inline void dup_devnull(int to)
0023 {
0024 int fd = open("/dev/null", O_RDWR);
0025 dup2(fd, to);
0026 close(fd);
0027 }
0028
0029 int start_command(struct child_process *cmd)
0030 {
0031 int need_in, need_out, need_err;
0032 int fdin[2], fdout[2], fderr[2];
0033 char sbuf[STRERR_BUFSIZE];
0034
0035
0036
0037
0038
0039
0040 need_in = !cmd->no_stdin && cmd->in < 0;
0041 if (need_in) {
0042 if (pipe(fdin) < 0) {
0043 if (cmd->out > 0)
0044 close(cmd->out);
0045 return -ERR_RUN_COMMAND_PIPE;
0046 }
0047 cmd->in = fdin[1];
0048 }
0049
0050 need_out = !cmd->no_stdout
0051 && !cmd->stdout_to_stderr
0052 && cmd->out < 0;
0053 if (need_out) {
0054 if (pipe(fdout) < 0) {
0055 if (need_in)
0056 close_pair(fdin);
0057 else if (cmd->in)
0058 close(cmd->in);
0059 return -ERR_RUN_COMMAND_PIPE;
0060 }
0061 cmd->out = fdout[0];
0062 }
0063
0064 need_err = !cmd->no_stderr && cmd->err < 0;
0065 if (need_err) {
0066 if (pipe(fderr) < 0) {
0067 if (need_in)
0068 close_pair(fdin);
0069 else if (cmd->in)
0070 close(cmd->in);
0071 if (need_out)
0072 close_pair(fdout);
0073 else if (cmd->out)
0074 close(cmd->out);
0075 return -ERR_RUN_COMMAND_PIPE;
0076 }
0077 cmd->err = fderr[0];
0078 }
0079
0080 fflush(NULL);
0081 cmd->pid = fork();
0082 if (!cmd->pid) {
0083 if (cmd->no_stdin)
0084 dup_devnull(0);
0085 else if (need_in) {
0086 dup2(fdin[0], 0);
0087 close_pair(fdin);
0088 } else if (cmd->in) {
0089 dup2(cmd->in, 0);
0090 close(cmd->in);
0091 }
0092
0093 if (cmd->no_stderr)
0094 dup_devnull(2);
0095 else if (need_err) {
0096 dup2(fderr[1], 2);
0097 close_pair(fderr);
0098 }
0099
0100 if (cmd->no_stdout)
0101 dup_devnull(1);
0102 else if (cmd->stdout_to_stderr)
0103 dup2(2, 1);
0104 else if (need_out) {
0105 dup2(fdout[1], 1);
0106 close_pair(fdout);
0107 } else if (cmd->out > 1) {
0108 dup2(cmd->out, 1);
0109 close(cmd->out);
0110 }
0111
0112 if (cmd->dir && chdir(cmd->dir))
0113 die("exec %s: cd to %s failed (%s)", cmd->argv[0],
0114 cmd->dir, str_error_r(errno, sbuf, sizeof(sbuf)));
0115 if (cmd->env) {
0116 for (; *cmd->env; cmd->env++) {
0117 if (strchr(*cmd->env, '='))
0118 putenv((char*)*cmd->env);
0119 else
0120 unsetenv(*cmd->env);
0121 }
0122 }
0123 if (cmd->preexec_cb)
0124 cmd->preexec_cb();
0125 if (cmd->exec_cmd) {
0126 execv_cmd(cmd->argv);
0127 } else {
0128 execvp(cmd->argv[0], (char *const*) cmd->argv);
0129 }
0130 exit(127);
0131 }
0132
0133 if (cmd->pid < 0) {
0134 int err = errno;
0135 if (need_in)
0136 close_pair(fdin);
0137 else if (cmd->in)
0138 close(cmd->in);
0139 if (need_out)
0140 close_pair(fdout);
0141 else if (cmd->out)
0142 close(cmd->out);
0143 if (need_err)
0144 close_pair(fderr);
0145 return err == ENOENT ?
0146 -ERR_RUN_COMMAND_EXEC :
0147 -ERR_RUN_COMMAND_FORK;
0148 }
0149
0150 if (need_in)
0151 close(fdin[0]);
0152 else if (cmd->in)
0153 close(cmd->in);
0154
0155 if (need_out)
0156 close(fdout[1]);
0157 else if (cmd->out)
0158 close(cmd->out);
0159
0160 if (need_err)
0161 close(fderr[1]);
0162
0163 return 0;
0164 }
0165
0166 static int wait_or_whine(pid_t pid)
0167 {
0168 char sbuf[STRERR_BUFSIZE];
0169
0170 for (;;) {
0171 int status, code;
0172 pid_t waiting = waitpid(pid, &status, 0);
0173
0174 if (waiting < 0) {
0175 if (errno == EINTR)
0176 continue;
0177 fprintf(stderr, " Error: waitpid failed (%s)",
0178 str_error_r(errno, sbuf, sizeof(sbuf)));
0179 return -ERR_RUN_COMMAND_WAITPID;
0180 }
0181 if (waiting != pid)
0182 return -ERR_RUN_COMMAND_WAITPID_WRONG_PID;
0183 if (WIFSIGNALED(status))
0184 return -ERR_RUN_COMMAND_WAITPID_SIGNAL;
0185
0186 if (!WIFEXITED(status))
0187 return -ERR_RUN_COMMAND_WAITPID_NOEXIT;
0188 code = WEXITSTATUS(status);
0189 switch (code) {
0190 case 127:
0191 return -ERR_RUN_COMMAND_EXEC;
0192 case 0:
0193 return 0;
0194 default:
0195 return -code;
0196 }
0197 }
0198 }
0199
0200 int finish_command(struct child_process *cmd)
0201 {
0202 return wait_or_whine(cmd->pid);
0203 }
0204
0205 int run_command(struct child_process *cmd)
0206 {
0207 int code = start_command(cmd);
0208 if (code)
0209 return code;
0210 return finish_command(cmd);
0211 }
0212
0213 static void prepare_run_command_v_opt(struct child_process *cmd,
0214 const char **argv,
0215 int opt)
0216 {
0217 memset(cmd, 0, sizeof(*cmd));
0218 cmd->argv = argv;
0219 cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
0220 cmd->exec_cmd = opt & RUN_EXEC_CMD ? 1 : 0;
0221 cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
0222 }
0223
0224 int run_command_v_opt(const char **argv, int opt)
0225 {
0226 struct child_process cmd;
0227 prepare_run_command_v_opt(&cmd, argv, opt);
0228 return run_command(&cmd);
0229 }