From 9da708772cd9b48121c7e5ac539ff36f086f1438 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Fri, 6 Sep 2019 20:56:19 -0400 Subject: [PATCH] Align child_execute_job among different ports Create a struct childbase which is the basics of struct child needed to invoke child_execute_job(), and can be cast back and forth to a struct child. Ensure all implementations of child_execute_job() take the same arguments. * src/job.h (CHILDBASE): Create a macro to hold the base parts. (struct childbase): A structure containing CHILDBASE. (struct child): Use CHILDBASE as the initial part of child. [VMS]: Remove declaration of VMS version of child_execute_job. * src/job.c (start_job_command): Use new child_execute_job() call. (child_execute_job) [__EMX__]: Implement new calling signature. (child_execute_job): Implement new calling signature. * src/main.c (main) [__EMX__]: Use new child_execute_job() call. * src/function.c (func_shell_base): Use new child_execute_job() call. * src/vmsjobs.c (vmsHandleChildTerm): Accept struct childbase. * src/vmsjobs.c (child_execute_job): Implement new calling signature. Modify the return value to be pid_t, not a boolean, and return the PID rather than setting it in the child. This is OK because our only caller immediately reset PID to -1 anyway if we return 0. --- src/function.c | 14 +++++++++----- src/job.c | 39 +++++++++++++++++++-------------------- src/job.h | 46 +++++++++++++++++++++++++++------------------- src/main.c | 9 +++++++-- src/vmsjobs.c | 32 ++++++++++++++------------------ 5 files changed, 76 insertions(+), 64 deletions(-) diff --git a/src/function.c b/src/function.c index b7097545..adef7e6f 100644 --- a/src/function.c +++ b/src/function.c @@ -1780,12 +1780,16 @@ func_shell_base (char *o, char **argv, int trim_newlines) fd_noinherit (pipedes[0]); { - struct output out; - out.syncout = 1; - out.out = pipedes[1]; - out.err = errfd; + struct childbase child; + child.cmd_name = NULL; + child.output.syncout = 1; + child.output.out = pipedes[1]; + child.output.err = errfd; + child.environment = envp; - pid = child_execute_job (&out, 1, command_argv, envp); + pid = child_execute_job (&child, 1, command_argv); + + free (child.cmd_name); } if (pid < 0) diff --git a/src/job.c b/src/job.c index 5b372a29..0c68e01f 100644 --- a/src/job.c +++ b/src/job.c @@ -1452,8 +1452,7 @@ start_job_command (struct child *child) child->remote = 0; #ifdef VMS - if (!child_execute_job (child, argv)) - child->pid = -1; + child->pid = child_execute_job ((struct childbase *)child, 1, argv); #else @@ -1461,8 +1460,8 @@ start_job_command (struct child *child) jobserver_pre_child (flags & COMMANDS_RECURSE); - child->pid = child_execute_job (&child->output, child->good_stdin, - argv, child->environment); + child->pid = child_execute_job ((struct childbase *)child, + child->good_stdin, argv); environ = parent_environ; /* Restore value child may have clobbered. */ jobserver_post_child (flags & COMMANDS_RECURSE); @@ -2163,7 +2162,7 @@ start_waiting_jobs (void) /* EMX: Start a child process. This function returns the new pid. */ # if defined __EMX__ pid_t -child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) +child_execute_job (struct childbase *child, int good_stdin, char **argv) { pid_t pid; int fdin = good_stdin ? FD_STDIN : get_bad_stdin (); @@ -2174,12 +2173,12 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) int save_fderr = -1; /* Divert child output if we want to capture output. */ - if (out && out->syncout) + if (child->output.syncout) { - if (out->out >= 0) - fdout = out->out; - if (out->err >= 0) - fderr = out->err; + if (child->output.out >= 0) + fdout = child->output.out; + if (child->output.err >= 0) + fderr = child->output.err; } /* For each FD which needs to be redirected first make a dup of the standard @@ -2225,7 +2224,7 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) } /* Run the command. */ - pid = exec_command (argv, envp); + pid = exec_command (argv, child->environment); /* Restore stdout/stdin/stderr of the parent and close temporary FDs. */ if (save_fdin >= 0) @@ -2262,9 +2261,9 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) /* POSIX: Create a child process executing the command in ARGV. - ENVP is the environment of the new program. Returns the PID or -1. */ + Returns the PID or -1. */ pid_t -child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) +child_execute_job (struct childbase *child, int good_stdin, char **argv) { const int fdin = good_stdin ? FD_STDIN : get_bad_stdin (); int fdout = FD_STDOUT; @@ -2278,12 +2277,12 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) #endif /* Divert child output if we want to capture it. */ - if (out && out->syncout) + if (child->output.syncout) { - if (out->out >= 0) - fdout = out->out; - if (out->err >= 0) - fderr = out->err; + if (child->output.out >= 0) + fdout = child->output.out; + if (child->output.err >= 0) + fderr = child->output.err; } #if !defined(USE_POSIX_SPAWN) @@ -2311,7 +2310,7 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) EINTRLOOP (r, dup2 (fderr, FD_STDERR)); /* Run the command. */ - exec_command (argv, envp); + exec_command (argv, child->environment); #else /* use posix_spawn() */ @@ -2361,7 +2360,7 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) goto cleanup; /* Start the program. */ - while ((r = posix_spawnp (&pid, argv[0], &fa, &attr, argv, envp)) == EINTR) + while ((r = posix_spawnp (&pid, argv[0], &fa, &attr, argv, child->environment)) == EINTR) ; cleanup: diff --git a/src/job.h b/src/job.h index 339d7232..4f1da97c 100644 --- a/src/job.h +++ b/src/job.h @@ -18,31 +18,44 @@ this program. If not, see . */ /* Structure describing a running or dead child process. */ +#ifdef VMS +#define VMSCHILD \ + char *comname; /* Temporary command file name */ \ + int efn; /* Completion event flag number */ \ + int cstatus; /* Completion status */ \ + int vms_launch_status; /* non-zero if lib$spawn, etc failed */ +#else +#define VMSCHILD +#endif + +#define CHILDBASE \ + char *cmd_name; /* Alloced copy of command run. */ \ + char **environment; /* Environment for commands. */ \ + VMSCHILD \ + struct output output /* Output for this child. */ + + +struct childbase + { + CHILDBASE; + }; + struct child { + CHILDBASE; + struct child *next; /* Link in the chain. */ struct file *file; /* File being remade. */ - char **environment; /* Environment for commands. */ - char *sh_batch_file; /* Script file for shell commands */ char **command_lines; /* Array of variable-expanded cmd lines. */ char *command_ptr; /* Ptr into command_lines[command_line]. */ - char *cmd_name; /* Alloced copy of argv[0] that was run. */ - - struct output output; /* Output for this child. */ - -#ifdef VMS - char *comname; /* Temporary command file name */ - int efn; /* Completion event flag number */ - int cstatus; /* Completion status */ - int vms_launch_status; /* non-zero if lib$spawn, etc failed */ -#endif unsigned int command_line; /* Index into command_lines. */ - pid_t pid; /* Child process's ID number. */ + pid_t pid; /* Child process's ID number. */ + unsigned int remote:1; /* Nonzero if executing remotely. */ unsigned int noerror:1; /* Nonzero if commands contained a '-'. */ unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */ @@ -63,12 +76,7 @@ void start_waiting_jobs (void); char **construct_command_argv (char *line, char **restp, struct file *file, int cmd_flags, char** batch_file); -#ifdef VMS -int child_execute_job (struct child *child, char *argv); -#else -pid_t child_execute_job (struct output *out, int good_stdin, - char **argv, char **envp); -#endif +pid_t child_execute_job (struct childbase *child, int good_stdin, char **argv); #ifdef _AMIGA void exec_command (char **argv) __attribute__ ((noreturn)); diff --git a/src/main.c b/src/main.c index 07ca6e64..04d6ba54 100644 --- a/src/main.c +++ b/src/main.c @@ -2469,7 +2469,12 @@ main (int argc, char **argv, char **envp) termination. */ pid_t pid; int r; - pid = child_execute_job (NULL, 1, nargv, environ); + struct childbase child; + child.cmd_name = NULL; + child.output.syncout = 0; + child.environment = environ; + + pid = child_execute_job (&child, 1, nargv); /* is this loop really necessary? */ do { @@ -2640,7 +2645,7 @@ init_switches (void) for (i = 0; switches[i].c != '\0'; ++i) { long_options[i].name = (char *) (switches[i].long_name == 0 ? "" : - switches[i].long_name); + switches[i].long_name); long_options[i].flag = 0; long_options[i].val = switches[i].c; if (short_option (switches[i].c)) diff --git a/src/vmsjobs.c b/src/vmsjobs.c index 444ce591..b5052e94 100644 --- a/src/vmsjobs.c +++ b/src/vmsjobs.c @@ -104,11 +104,12 @@ static int ctrlYPressed= 0; inner mode level AST. */ static int -vmsHandleChildTerm (struct child *child) +vmsHandleChildTerm (struct childbase *cbase) { - int exit_code; + struct child *child = (struct child*)cbase; struct child *lastc, *c; int child_failed; + int exit_code; /* The child efn is 0 when a built-in or null command is executed successfully with out actually creating a child. @@ -803,8 +804,8 @@ build_vms_cmd (char **cmd_tokens, return cmd_dsc; } -int -child_execute_job (struct child *child, char *argv) +pid_t +child_execute_job (struct childbase *child, int good_stdin UNUSED, char *argv) { int i; @@ -841,11 +842,10 @@ child_execute_job (struct child *child, char *argv) /* Only a built-in or a null command - Still need to run term AST */ child->cstatus = VMS_POSIX_EXIT_MASK; child->vms_launch_status = SS$_NORMAL; - /* TODO what is this "magic number" */ - child->pid = 270163; /* Special built-in */ child->efn = 0; vmsHandleChildTerm (child); - return 1; + /* TODO what is this "magic number" */ + return 270163; /* Special built-in */ } sprintf (procname, "GMAKE_%05x", getpid () & 0xfffff); @@ -1162,11 +1162,9 @@ child_execute_job (struct child *child, char *argv) free (cmd_tokens[cmd_tkn_index++]); child->cstatus = VMS_POSIX_EXIT_MASK | (MAKE_TROUBLE << 3); child->vms_launch_status = SS$_ABORT; - /* TODO what is this "magic number" */ - child->pid = 270163; /* Special built-in */ child->efn = 0; errno = token.cmd_errno; - return 0; + return -1; } /* Save any redirection to append file */ @@ -1206,21 +1204,18 @@ child_execute_job (struct child *child, char *argv) free (cmd_dsc); child->cstatus = VMS_POSIX_EXIT_MASK | (MAKE_TROUBLE << 3); child->vms_launch_status = SS$_ABORT; - /* TODO what is this "magic number" */ - child->pid = 270163; /* Special built-in */ child->efn = 0; - return 0; + return -1; } /* Only a built-in or a null command - Still need to run term AST */ free (cmd_dsc); child->cstatus = VMS_POSIX_EXIT_MASK; child->vms_launch_status = SS$_NORMAL; - /* TODO what is this "magic number" */ - child->pid = 270163; /* Special built-in */ child->efn = 0; vmsHandleChildTerm (child); - return 1; + /* TODO what is this "magic number" */ + return 270163; /* Special built-in */ } if (cmd_dsc->dsc$w_length > MAX_DCL_LINE_LENGTH) @@ -1339,7 +1334,7 @@ child_execute_job (struct child *child, char *argv) unlink (child->comname); free (child->comname); } - return 0; + return -1; } } @@ -1465,5 +1460,6 @@ child_execute_job (struct child *child, char *argv) } } - return (status & 1); + /* TODO what is this "magic number" */ + return (status & 1) ? 270163 : -1 ; }