ocamltest: run_unix fix

If anything fails in the child process, it should exit immediately
rather than returning (continuing).
master
Sébastien Hinderer 2017-11-28 19:35:05 +01:00
parent df5689521f
commit bd75b05c9e
1 changed files with 34 additions and 15 deletions

View File

@ -64,6 +64,10 @@ myperror_with_location(__FILE__, __LINE__, settings, msg, ## __VA_ARGS__)
/* Same remark as for the error macro. */
#define child_error(msg, ...) \
myperror(msg, ## __VA_ARGS__); \
goto child_failed;
static void open_error_with_location(
const char *file, int line,
const command_settings *settings,
@ -145,31 +149,33 @@ static void update_environment(array local_env)
static int run_command_child(const command_settings *settings)
{
int res;
int stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; /* -1 = no redir */
int inputFlags = O_RDONLY;
int outputFlags =
O_CREAT | O_WRONLY | (settings->append ? O_APPEND : O_TRUNC);
int inputMode = 0400, outputMode = 0666;
if (setpgid(0, 0) == -1) myperror("setpgid");
if (setpgid(0, 0) == -1) child_error("setpgid");
if (is_defined(settings->stdin_filename))
{
stdin_fd = open(settings->stdin_filename, inputFlags, inputMode);
if (stdin_fd < 0)
{
open_error(settings->stdin_filename);
if ( dup2(stdin_fd, STDIN_FILENO) == -1 )
myperror("dup2 for stdin");
goto child_failed;
}
if (dup2(stdin_fd, STDIN_FILENO) == -1) child_error("dup2 for stdin");
}
if (is_defined(settings->stdout_filename))
{
stdout_fd = open(settings->stdout_filename, outputFlags, outputMode);
if (stdout_fd < 0)
if (stdout_fd < 0) {
open_error(settings->stdout_filename);
if ( dup2(stdout_fd, STDOUT_FILENO) == -1 )
myperror("dup2 for stdout");
goto child_failed;
}
if (dup2(stdout_fd, STDOUT_FILENO) == -1) child_error("dup2 for stdout");
}
if (is_defined(settings->stderr_filename))
@ -183,18 +189,23 @@ static int run_command_child(const command_settings *settings)
if (stderr_fd == -1)
{
stderr_fd = open(settings->stderr_filename, outputFlags, outputMode);
if (stderr_fd == -1) open_error(settings->stderr_filename);
if (stderr_fd == -1)
{
open_error(settings->stderr_filename);
goto child_failed;
}
}
if ( dup2(stderr_fd, STDERR_FILENO) == -1 )
myperror("dup2 for stderr");
if (dup2(stderr_fd, STDERR_FILENO) == -1) child_error("dup2 for stderr");
}
update_environment(settings->envp);
res = execvp(settings->program, settings->argv);
execvp(settings->program, settings->argv);
myperror("Cannot execute %s", settings->program);
return res;
child_failed:
return (-1);
}
/* Handles the termination of a process. Arguments:
@ -296,7 +307,15 @@ static int run_command_parent(const command_settings *settings, pid_t child_pid)
int run_command(const command_settings *settings)
{
pid_t child_pid = fork();
if (child_pid == -1) myperror("fork");
if (child_pid == 0) return run_command_child(settings);
else return run_command_parent(settings, child_pid);
switch (child_pid)
{
case -1:
myperror("fork");
return -1;
case 0: /* child process */
if (! run_command_child(settings)) exit(1);
default:
return run_command_parent(settings, child_pid);
}
}