Skip to content

Commit

Permalink
Move errno mapping for errors from action's outside of process_create…
Browse files Browse the repository at this point in the history
… + map extra errors for execvp
  • Loading branch information
DaanDeMeyer committed Nov 3, 2018
1 parent 3bdf728 commit f5cdaf5
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
5 changes: 5 additions & 0 deletions include/reproc/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ typedef enum {
REPROC_FILE_NOT_FOUND,
/*! The given name was too long (most systems have path length limits). */
REPROC_NAME_TOO_LONG,
/*! The given argument list was too long (some systems limit the size of argv.
*/
REPROC_ARGS_TOO_LONG,
/*! The system does not support executing the given binary. */
REPROC_NOT_EXECUTABLE,
/*! Unlike POSIX, Windows does not include information about exactly which
errors can occur in its documentation. If an error occurs that is not known
functions will return #REPROC_UNKNOWN_ERROR. */
Expand Down
14 changes: 11 additions & 3 deletions src/reproc/posix/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,9 @@ REPROC_ERROR process_create(int (*action)(const void *), const void *data,
case EACCES: error = REPROC_PERMISSION_DENIED; break;
case EPERM: error = REPROC_PERMISSION_DENIED; break;
case ELOOP: error = REPROC_SYMLINK_LOOP; break;
case ENOMEM: error = REPROC_NOT_ENOUGH_MEMORY; break;
case ENAMETOOLONG: error = REPROC_NAME_TOO_LONG; break;
case ENOENT: error = REPROC_FILE_NOT_FOUND; break;
case ENOTDIR: error = REPROC_FILE_NOT_FOUND; break;
case EMFILE: error = REPROC_PIPE_LIMIT_REACHED; break;
case ENAMETOOLONG: error = REPROC_NAME_TOO_LONG; break;
case EINTR: error = REPROC_INTERRUPTED; break;
default: error = REPROC_UNKNOWN_ERROR; break;
}
Expand Down Expand Up @@ -243,6 +241,15 @@ static int timeout_process(const void *data)
return 0;
}

static REPROC_ERROR timeout_map_error(int error)
{
switch(error) {
case EINTR: return REPROC_INTERRUPTED;
case ENOMEM: return REPROC_NOT_ENOUGH_MEMORY;
default: return REPROC_UNKNOWN_ERROR;
}
}

// See Design section in README.md for an explanation of how this works.
static REPROC_ERROR wait_timeout(pid_t pid, unsigned int timeout,
unsigned int *exit_status)
Expand All @@ -268,6 +275,7 @@ static REPROC_ERROR wait_timeout(pid_t pid, unsigned int timeout,

pid_t timeout_pid = 0;
error = process_create(timeout_process, &timeout, &options, &timeout_pid);
if (error == REPROC_UNKNOWN_ERROR) { error = timeout_map_error(errno); }
if (error) { return error; }

// -reproc->pid waits for all processes in the reproc->pid process group
Expand Down
8 changes: 5 additions & 3 deletions src/reproc/posix/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ struct process_options {
};

/* Creates child process and calls action with data in the child process. The
process id of the new child process is assigned to pid. */
REPROC_ERROR process_create(int (*action)(const void *), const void *data,
struct process_options *options, pid_t *pid);
process id of the new child process is assigned to pid. map_error is used to
translate errno values returned from action to REPROC_ERROR values. */
REPROC_ERROR
process_create(int (*action)(const void *), const void *data,
struct process_options *options, pid_t *pid);

REPROC_ERROR process_wait(pid_t pid, unsigned int timeout,
unsigned int *exit_status);
Expand Down
16 changes: 16 additions & 0 deletions src/reproc/posix/reproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ static int exec_process(const void *data)
return 0;
}

static REPROC_ERROR exec_map_error(int error)
{
switch(error) {
case E2BIG: return REPROC_ARGS_TOO_LONG;
case EACCES: return REPROC_PERMISSION_DENIED;
case EINVAL: return REPROC_NOT_EXECUTABLE;
case ELOOP: return REPROC_SYMLINK_LOOP;
case ENAMETOOLONG: return REPROC_NAME_TOO_LONG;
case ENOENT: return REPROC_FILE_NOT_FOUND;
case ENOTDIR: return REPROC_FILE_NOT_FOUND;
case ENOMEM: return REPROC_NOT_ENOUGH_MEMORY;
default: return REPROC_UNKNOWN_ERROR;
}
}

REPROC_ERROR reproc_start(reproc_type *process, int argc,
const char *const *argv,
const char *working_directory)
Expand Down Expand Up @@ -74,6 +89,7 @@ REPROC_ERROR reproc_start(reproc_type *process, int argc,

// Fork a child process and call exec.
error = process_create(exec_process, argv, &options, &process->id);
if (error == REPROC_UNKNOWN_ERROR) { error = exec_map_error(errno); }

cleanup:
// An error has ocurred or the child pipe endpoints have been copied to the
Expand Down

0 comments on commit f5cdaf5

Please sign in to comment.