Print this page
make: remove maketool support


  32 
  33 /*
  34  * Included files
  35  */
  36 #include <sys/wait.h>                     /* WIFEXITED(status) */
  37 #include <alloca.h>               /* alloca() */
  38 
  39 #include <stdio.h>                /* errno */
  40 #include <errno.h>                /* errno */
  41 #include <fcntl.h>                /* open() */
  42 #include <mksh/dosys.h>
  43 #include <mksh/macro.h>           /* getvar() */
  44 #include <mksh/misc.h>            /* getmem(), fatal_mksh(), errmsg() */
  45 #include <mksdmsi18n/mksdmsi18n.h>        /* libmksdmsi18n_init() */
  46 #include <sys/signal.h>           /* SIG_DFL */
  47 #include <sys/stat.h>             /* open() */
  48 #include <sys/wait.h>             /* wait() */
  49 #include <ulimit.h>               /* ulimit() */
  50 #include <unistd.h>               /* close(), dup2() */
  51 
  52 
  53 
  54 /*
  55  * Defined macros
  56  */
  57 #define SEND_MTOOL_MSG(cmds)
  58 
  59 /*
  60  * typedefs & structs
  61  */
  62 
  63 /*
  64  * Static variables
  65  */
  66 
  67 /*
  68  * File table of contents
  69  */
  70 static Boolean  exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path);
  71 
  72 /*
  73  * Workaround for NFS bug. Sometimes, when running 'open' on a remote
  74  * dmake server, it fails with "Stale NFS file handle" error.
  75  * The second attempt seems to work.
  76  */
  77 int
  78 my_open(const char *path, int oflag, mode_t mode) {


 119                 if (dup2(1, 2) == -1) {
 120                         fatal_mksh(NOCATGETS("*** Error: dup2(1, 2) failed: %s"),
 121                                 errmsg(errno));
 122                 }
 123         } else if ((i = my_open(stderr_file,
 124                         O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
 125                         S_IREAD | S_IWRITE)) < 0) {
 126                 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 91, "Couldn't open standard error temp file `%s': %s"),
 127                       stderr_file,
 128                       errmsg(errno));
 129         } else {
 130                 if (dup2(i, 2) == -1) {
 131                         fatal_mksh(NOCATGETS("*** Error: dup2(3, 2) failed: %s"),
 132                                 errmsg(errno));
 133                 }
 134                 close(i);
 135         }
 136 }
 137 
 138 /*
 139  *      dosys_mksh(command, ignore_error, call_make, silent_error, target)
 140  *
 141  *      Check if command string contains meta chars and dispatch to
 142  *      the proper routine for executing one command line.
 143  *
 144  *      Return value:
 145  *                              Indicates if the command execution failed
 146  *
 147  *      Parameters:
 148  *              command         The command to run
 149  *              ignore_error    Should we abort when an error is seen?
 150  *              call_make       Did command reference $(MAKE) ?
 151  *              silent_error    Should error messages be suppressed for dmake?
 152  *              target          Target we are building
 153  *
 154  *      Global variables used:
 155  *              do_not_exec_rule Is -n on?
 156  *              working_on_targets We started processing real targets
 157  */
 158 Doname
 159 dosys_mksh(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
 160 {
 161         register int            length = command->hash.length;
 162         register wchar_t        *p;
 163         register wchar_t        *q;
 164         register wchar_t        *cmd_string;
 165         struct stat             before;
 166         Doname                  result;
 167         Boolean                 working_on_targets_mksh = true;
 168         Wstring wcb(command);
 169         p = wcb.get_string();
 170         cmd_string = p;
 171 
 172         /* Strip spaces from head of command string */
 173         while (iswspace(*p)) {
 174                 p++, length--;
 175         }
 176         if (*p == (int) nul_char) {
 177                 return build_failed;
 178         }
 179         /* If we are faking it we just return */
 180         if (do_not_exec_rule &&
 181             working_on_targets_mksh &&
 182             !call_make &&
 183             !always_exec) {
 184                 return build_ok;
 185         }
 186 
 187         /* Copy string to make it OK to write it. */
 188         q = ALLOC_WC(length + 1);
 189         (void) wscpy(q, p);
 190         /* Write the state file iff this command uses make. */
 191 /* XXX - currently does not support recursive make's, $(MAKE)'s
 192         if (call_make && command_changed) {
 193                 write_state_file(0, false);
 194         }
 195         (void) stat(make_state->string_mb, &before);
 196  */
 197         /*
 198          * Run command directly if it contains no shell meta chars,
 199          * else run it using the shell.
 200          */
 201         /* XXX - command->meta *may* not be set correctly */
 202         if (await(ignore_error,
 203                   silent_error,
 204                   target,
 205                   cmd_string,
 206                   command->meta ?
 207                     doshell(q, ignore_error, redirect_out_err, stdout_file, stderr_file, nice_prio) :
 208                     doexec(q, ignore_error, redirect_out_err, stdout_file, stderr_file, vroot_path, nice_prio),
 209                   false,
 210                   NULL,
 211                   -1)) {
 212 
 213 #ifdef PRINT_EXIT_STATUS
 214                 warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_ok."));
 215 #endif
 216 
 217                 result = build_ok;
 218         } else {
 219 
 220 #ifdef PRINT_EXIT_STATUS
 221                 warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_failed."));
 222 #endif
 223 
 224                 result = build_failed;
 225         }
 226         retmem(q);
 227 
 228 /* XXX - currently does not support recursive make's, $(MAKE)'s
 229         if ((report_dependencies_level == 0) &&
 230             call_make) {
 231                 make_state->stat.time = (time_t)file_no_time;
 232                 (void)exists(make_state);
 233                 if (before.st_mtime == make_state->stat.time) {
 234                         return result;
 235                 }
 236                 makefile_type = reading_statefile;
 237                 if (read_trace_level > 1) {
 238                         trace_reader = true;
 239                 }
 240                 (void) read_simple_file(make_state,
 241                                         false,
 242                                         false,
 243                                         false,
 244                                         false,
 245                                         false,
 246                                         true);
 247                 trace_reader = false;
 248         }
 249  */
 250         return result;
 251 }
 252 
 253 /*
 254  *      doshell(command, ignore_error)
 255  *
 256  *      Used to run command lines that include shell meta-characters.
 257  *      The make macro SHELL is supposed to contain a path to the shell.
 258  *
 259  *      Return value:
 260  *                              The pid of the process we started
 261  *
 262  *      Parameters:
 263  *              command         The command to run
 264  *              ignore_error    Should we abort on error?
 265  *
 266  *      Global variables used:
 267  *              filter_stderr   If -X is on we redirect stderr
 268  *              shell_name      The Name "SHELL", used to get the path to shell
 269  */
 270 int
 271 doshell(wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, int nice_prio)
 272 {
 273         char                    *argv[6];
 274         int                     argv_index = 0;
 275         int                     cmd_argv_index;
 276         int                     length;
 277         char                    nice_prio_buf[MAXPATHLEN];
 278         register Name           shell = getvar(shell_name);
 279         register char           *shellname;
 280         char                    *tmp_mbs_buffer;
 281 
 282 
 283         if (IS_EQUAL(shell->string_mb, "")) {
 284                 shell = shell_name;
 285         }
 286         if ((shellname = strrchr(shell->string_mb, (int) slash_char)) == NULL) {
 287                 shellname = shell->string_mb;
 288         } else {
 289                 shellname++;
 290         }
 291 


 299                 (void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
 300                 argv[argv_index++] = strdup(nice_prio_buf);
 301         }
 302         argv[argv_index++] = shellname;
 303         argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
 304         if ((length = wslen(command)) >= MAXPATHLEN) {
 305                 tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
 306                 (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
 307                 cmd_argv_index = argv_index;
 308                 argv[argv_index++] = strdup(tmp_mbs_buffer);
 309                 retmem_mb(tmp_mbs_buffer);
 310         } else {
 311                 WCSTOMBS(mbs_buffer, command);
 312                 cmd_argv_index = argv_index;
 313                 argv[argv_index++] = strdup(mbs_buffer);
 314         }
 315         argv[argv_index] = NULL;
 316         (void) fflush(stdout);
 317         if ((childPid = fork()) == 0) {
 318                 enable_interrupt((void (*) (int)) SIG_DFL);
 319                 if (redirect_out_err) {
 320                         redirect_io(stdout_file, stderr_file);
 321                 }
 322 #if 0
 323                 if (filter_stderr) {
 324                         redirect_stderr();
 325                 }
 326 #endif
 327                 if (nice_prio != 0) {
 328                         (void) execve(NOCATGETS("/usr/bin/nice"), argv, environ);
 329                         fatal_mksh(catgets(libmksdmsi18n_catd, 1, 92, "Could not load `/usr/bin/nice': %s"),
 330                               errmsg(errno));
 331                 } else {
 332                         (void) execve(shell->string_mb, argv, environ);
 333                         fatal_mksh(catgets(libmksdmsi18n_catd, 1, 93, "Could not load Shell from `%s': %s"),
 334                               shell->string_mb,
 335                               errmsg(errno));
 336                 }
 337         }
 338         if (childPid  == -1) {
 339                 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 94, "fork failed: %s"),
 340                       errmsg(errno));
 341         }


 419         return failed;
 420 }
 421 
 422 /*
 423  *      doexec(command, ignore_error)
 424  *
 425  *      Will scan an argument string and split it into words
 426  *      thus building an argument list that can be passed to exec_ve()
 427  *
 428  *      Return value:
 429  *                              The pid of the process started here
 430  *
 431  *      Parameters:
 432  *              command         The command to run
 433  *              ignore_error    Should we abort on error?
 434  *
 435  *      Global variables used:
 436  *              filter_stderr   If -X is on we redirect stderr
 437  */
 438 int
 439 doexec(register wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
 440 {
 441         int                     arg_count = 5;
 442         char                    **argv;
 443         int                     length;
 444         char                    nice_prio_buf[MAXPATHLEN];
 445         register char           **p;
 446         wchar_t                 *q;
 447         register wchar_t        *t;
 448         char                    *tmp_mbs_buffer;
 449 
 450         /*
 451          * Only prepend the /usr/bin/nice command to the original command
 452          * if the nice priority, nice_prio, is NOT zero (0).
 453          * Nice priorities can be a positive or a negative number.
 454          */
 455         if (nice_prio != 0) {
 456                 arg_count += 2;
 457         }
 458         for (t = command; *t != (int) nul_char; t++) {
 459                 if (iswspace(*t)) {


 497                 }
 498                 if (*t) {
 499                         for (*t++ = (int) nul_char; iswspace(*t); t++);
 500                 }
 501                 if ((length = wslen(q)) >= MAXPATHLEN) {
 502                         tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
 503                         (void) wcstombs(tmp_mbs_buffer, q, (length * MB_LEN_MAX) + 1);
 504                         *p++ = strdup(tmp_mbs_buffer);
 505                         retmem_mb(tmp_mbs_buffer);
 506                 } else {
 507                         WCSTOMBS(mbs_buffer, q);
 508                         *p++ = strdup(mbs_buffer);
 509                 }
 510         }
 511         *p = NULL;
 512 
 513         /* Then exec the command with that argument list. */
 514         (void) fflush(stdout);
 515         if ((childPid = fork()) == 0) {
 516                 enable_interrupt((void (*) (int)) SIG_DFL);
 517                 if (redirect_out_err) {
 518                         redirect_io(stdout_file, stderr_file);
 519                 }
 520 #if 0
 521                 if (filter_stderr) {
 522                         redirect_stderr();
 523                 }
 524 #endif
 525                 (void) exec_vp(argv[1], argv, environ, ignore_error, vroot_path);
 526                 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 96, "Cannot load command `%s': %s"), argv[1], errmsg(errno));
 527         }
 528         if (childPid  == -1) {
 529                 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 97, "fork failed: %s"),
 530                       errmsg(errno));
 531         }
 532         for (int i = 0; argv[i] != NULL; i++) {
 533                 retmem_mb(argv[i]);
 534         }
 535         return childPid;
 536 }
 537 
 538 /*
 539  *      await(ignore_error, silent_error, target, command, running_pid)


 542  *      the returned status when the child process terminates.
 543  *
 544  *      Return value:
 545  *                              Returns true if commands ran OK
 546  *
 547  *      Parameters:
 548  *              ignore_error    Should we abort on error?
 549  *              silent_error    Should error messages be suppressed for dmake?
 550  *              target          The target we are building, for error msgs
 551  *              command         The command we ran, for error msgs
 552  *              running_pid     The pid of the process we are waiting for
 553  *              
 554  *      Static variables used:
 555  *              filter_file     The fd for the filter file
 556  *              filter_file_name The name of the filter file
 557  *
 558  *      Global variables used:
 559  *              filter_stderr   Set if -X is on
 560  */
 561 Boolean
 562 await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, void *xdrs_p, int job_msg_id)
 563 {
 564         int                     status;
 565         char                    *buffer;
 566         int                     core_dumped;
 567         int                     exit_status;
 568         FILE                    *outfp;
 569         register pid_t          pid;
 570         struct stat             stat_buff;
 571         int                     termination_signal;
 572         char                    tmp_buf[MAXPATHLEN];
 573 
 574         while ((pid = wait(&status)) != running_pid) {
 575                 if (pid == -1) {
 576                         fatal_mksh(catgets(libmksdmsi18n_catd, 1, 98, "wait() failed: %s"), errmsg(errno));
 577                 }
 578         }
 579         (void) fflush(stdout);
 580         (void) fflush(stderr);
 581 
 582         if (status == 0) {


 589         }
 590 
 591 #ifdef PRINT_EXIT_STATUS
 592         warning_mksh(NOCATGETS("I'm in await(), and status is *NOT* 0."));
 593 #endif
 594 
 595 
 596         exit_status = WEXITSTATUS(status);
 597 
 598 #ifdef PRINT_EXIT_STATUS
 599         warning_mksh(NOCATGETS("I'm in await(), and exit_status is %d."), exit_status);
 600 #endif
 601 
 602         termination_signal = WTERMSIG(status);
 603         core_dumped = WCOREDUMP(status);
 604 
 605         /*
 606          * If the child returned an error, we now try to print a
 607          * nice message about it.
 608          */
 609         SEND_MTOOL_MSG(
 610                 make_output_msg = new Avo_CmdOutput();
 611                 (void) sprintf(tmp_buf, "%d", job_msg_id);
 612                 make_output_msg->appendOutput(strdup(tmp_buf));
 613         );
 614 
 615         tmp_buf[0] = (int) nul_char;
 616         if (!silent_error) {
 617                 if (exit_status != 0) {
 618                         (void) fprintf(stdout,
 619                                        catgets(libmksdmsi18n_catd, 1, 103, "*** Error code %d"),
 620                                        exit_status);
 621                         SEND_MTOOL_MSG(
 622                                 (void) sprintf(&tmp_buf[strlen(tmp_buf)],
 623                                                catgets(libmksdmsi18n_catd, 1, 104, "*** Error code %d"),
 624                                                exit_status);
 625                         );
 626                 } else {
 627                                 (void) fprintf(stdout,
 628                                                catgets(libmksdmsi18n_catd, 1, 105, "*** Signal %d"),
 629                                                termination_signal);
 630                                 SEND_MTOOL_MSG(
 631                                         (void) sprintf(&tmp_buf[strlen(tmp_buf)],
 632                                                        catgets(libmksdmsi18n_catd, 1, 106, "*** Signal %d"),
 633                                                        termination_signal);
 634                                 );
 635                         if (core_dumped) {
 636                                 (void) fprintf(stdout,
 637                                                catgets(libmksdmsi18n_catd, 1, 107, " - core dumped"));
 638                                 SEND_MTOOL_MSG(
 639                                         (void) sprintf(&tmp_buf[strlen(tmp_buf)],
 640                                                        catgets(libmksdmsi18n_catd, 1, 108, " - core dumped"));
 641                                 );
 642                         }
 643                 }
 644                 if (ignore_error) {
 645                         (void) fprintf(stdout,
 646                                        catgets(libmksdmsi18n_catd, 1, 109, " (ignored)"));
 647                         SEND_MTOOL_MSG(
 648                                 (void) sprintf(&tmp_buf[strlen(tmp_buf)],
 649                                                catgets(libmksdmsi18n_catd, 1, 110, " (ignored)"));
 650                         );
 651                 }
 652                 (void) fprintf(stdout, "\n");
 653                 (void) fflush(stdout);
 654                 SEND_MTOOL_MSG(
 655                         make_output_msg->appendOutput(strdup(tmp_buf));
 656                 );
 657         }
 658         SEND_MTOOL_MSG(
 659                 xdr_msg = (RWCollectable*) make_output_msg;
 660                 xdr(xdrs_p, xdr_msg);
 661                 delete make_output_msg;
 662         );
 663 
 664 #ifdef PRINT_EXIT_STATUS
 665         warning_mksh(NOCATGETS("I'm in await(), returning failed."));
 666 #endif
 667 
 668         return failed;
 669 }
 670 
 671 /*
 672  *      sh_command2string(command, destination)
 673  *
 674  *      Run one sh command and capture the output from it.
 675  *
 676  *      Return value:
 677  *
 678  *      Parameters:
 679  *              command         The command to run
 680  *              destination     Where to deposit the output from the command
 681  *              
 682  *      Static variables used:




  32 
  33 /*
  34  * Included files
  35  */
  36 #include <sys/wait.h>                     /* WIFEXITED(status) */
  37 #include <alloca.h>               /* alloca() */
  38 
  39 #include <stdio.h>                /* errno */
  40 #include <errno.h>                /* errno */
  41 #include <fcntl.h>                /* open() */
  42 #include <mksh/dosys.h>
  43 #include <mksh/macro.h>           /* getvar() */
  44 #include <mksh/misc.h>            /* getmem(), fatal_mksh(), errmsg() */
  45 #include <mksdmsi18n/mksdmsi18n.h>        /* libmksdmsi18n_init() */
  46 #include <sys/signal.h>           /* SIG_DFL */
  47 #include <sys/stat.h>             /* open() */
  48 #include <sys/wait.h>             /* wait() */
  49 #include <ulimit.h>               /* ulimit() */
  50 #include <unistd.h>               /* close(), dup2() */
  51 







  52 /*
  53  * typedefs & structs
  54  */
  55 
  56 /*
  57  * Static variables
  58  */
  59 
  60 /*
  61  * File table of contents
  62  */
  63 static Boolean  exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path);
  64 
  65 /*
  66  * Workaround for NFS bug. Sometimes, when running 'open' on a remote
  67  * dmake server, it fails with "Stale NFS file handle" error.
  68  * The second attempt seems to work.
  69  */
  70 int
  71 my_open(const char *path, int oflag, mode_t mode) {


 112                 if (dup2(1, 2) == -1) {
 113                         fatal_mksh(NOCATGETS("*** Error: dup2(1, 2) failed: %s"),
 114                                 errmsg(errno));
 115                 }
 116         } else if ((i = my_open(stderr_file,
 117                         O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
 118                         S_IREAD | S_IWRITE)) < 0) {
 119                 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 91, "Couldn't open standard error temp file `%s': %s"),
 120                       stderr_file,
 121                       errmsg(errno));
 122         } else {
 123                 if (dup2(i, 2) == -1) {
 124                         fatal_mksh(NOCATGETS("*** Error: dup2(3, 2) failed: %s"),
 125                                 errmsg(errno));
 126                 }
 127                 close(i);
 128         }
 129 }
 130 
 131 /*



















































































































 132  *      doshell(command, ignore_error)
 133  *
 134  *      Used to run command lines that include shell meta-characters.
 135  *      The make macro SHELL is supposed to contain a path to the shell.
 136  *
 137  *      Return value:
 138  *                              The pid of the process we started
 139  *
 140  *      Parameters:
 141  *              command         The command to run
 142  *              ignore_error    Should we abort on error?
 143  *
 144  *      Global variables used:
 145  *              filter_stderr   If -X is on we redirect stderr
 146  *              shell_name      The Name "SHELL", used to get the path to shell
 147  */
 148 int
 149 doshell(wchar_t *command, register Boolean ignore_error, char *stdout_file, char *stderr_file, int nice_prio)
 150 {
 151         char                    *argv[6];
 152         int                     argv_index = 0;
 153         int                     cmd_argv_index;
 154         int                     length;
 155         char                    nice_prio_buf[MAXPATHLEN];
 156         register Name           shell = getvar(shell_name);
 157         register char           *shellname;
 158         char                    *tmp_mbs_buffer;
 159 
 160 
 161         if (IS_EQUAL(shell->string_mb, "")) {
 162                 shell = shell_name;
 163         }
 164         if ((shellname = strrchr(shell->string_mb, (int) slash_char)) == NULL) {
 165                 shellname = shell->string_mb;
 166         } else {
 167                 shellname++;
 168         }
 169 


 177                 (void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
 178                 argv[argv_index++] = strdup(nice_prio_buf);
 179         }
 180         argv[argv_index++] = shellname;
 181         argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
 182         if ((length = wslen(command)) >= MAXPATHLEN) {
 183                 tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
 184                 (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
 185                 cmd_argv_index = argv_index;
 186                 argv[argv_index++] = strdup(tmp_mbs_buffer);
 187                 retmem_mb(tmp_mbs_buffer);
 188         } else {
 189                 WCSTOMBS(mbs_buffer, command);
 190                 cmd_argv_index = argv_index;
 191                 argv[argv_index++] = strdup(mbs_buffer);
 192         }
 193         argv[argv_index] = NULL;
 194         (void) fflush(stdout);
 195         if ((childPid = fork()) == 0) {
 196                 enable_interrupt((void (*) (int)) SIG_DFL);



 197 #if 0
 198                 if (filter_stderr) {
 199                         redirect_stderr();
 200                 }
 201 #endif
 202                 if (nice_prio != 0) {
 203                         (void) execve(NOCATGETS("/usr/bin/nice"), argv, environ);
 204                         fatal_mksh(catgets(libmksdmsi18n_catd, 1, 92, "Could not load `/usr/bin/nice': %s"),
 205                               errmsg(errno));
 206                 } else {
 207                         (void) execve(shell->string_mb, argv, environ);
 208                         fatal_mksh(catgets(libmksdmsi18n_catd, 1, 93, "Could not load Shell from `%s': %s"),
 209                               shell->string_mb,
 210                               errmsg(errno));
 211                 }
 212         }
 213         if (childPid  == -1) {
 214                 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 94, "fork failed: %s"),
 215                       errmsg(errno));
 216         }


 294         return failed;
 295 }
 296 
 297 /*
 298  *      doexec(command, ignore_error)
 299  *
 300  *      Will scan an argument string and split it into words
 301  *      thus building an argument list that can be passed to exec_ve()
 302  *
 303  *      Return value:
 304  *                              The pid of the process started here
 305  *
 306  *      Parameters:
 307  *              command         The command to run
 308  *              ignore_error    Should we abort on error?
 309  *
 310  *      Global variables used:
 311  *              filter_stderr   If -X is on we redirect stderr
 312  */
 313 int
 314 doexec(register wchar_t *command, register Boolean ignore_error, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
 315 {
 316         int                     arg_count = 5;
 317         char                    **argv;
 318         int                     length;
 319         char                    nice_prio_buf[MAXPATHLEN];
 320         register char           **p;
 321         wchar_t                 *q;
 322         register wchar_t        *t;
 323         char                    *tmp_mbs_buffer;
 324 
 325         /*
 326          * Only prepend the /usr/bin/nice command to the original command
 327          * if the nice priority, nice_prio, is NOT zero (0).
 328          * Nice priorities can be a positive or a negative number.
 329          */
 330         if (nice_prio != 0) {
 331                 arg_count += 2;
 332         }
 333         for (t = command; *t != (int) nul_char; t++) {
 334                 if (iswspace(*t)) {


 372                 }
 373                 if (*t) {
 374                         for (*t++ = (int) nul_char; iswspace(*t); t++);
 375                 }
 376                 if ((length = wslen(q)) >= MAXPATHLEN) {
 377                         tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
 378                         (void) wcstombs(tmp_mbs_buffer, q, (length * MB_LEN_MAX) + 1);
 379                         *p++ = strdup(tmp_mbs_buffer);
 380                         retmem_mb(tmp_mbs_buffer);
 381                 } else {
 382                         WCSTOMBS(mbs_buffer, q);
 383                         *p++ = strdup(mbs_buffer);
 384                 }
 385         }
 386         *p = NULL;
 387 
 388         /* Then exec the command with that argument list. */
 389         (void) fflush(stdout);
 390         if ((childPid = fork()) == 0) {
 391                 enable_interrupt((void (*) (int)) SIG_DFL);



 392 #if 0
 393                 if (filter_stderr) {
 394                         redirect_stderr();
 395                 }
 396 #endif
 397                 (void) exec_vp(argv[1], argv, environ, ignore_error, vroot_path);
 398                 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 96, "Cannot load command `%s': %s"), argv[1], errmsg(errno));
 399         }
 400         if (childPid  == -1) {
 401                 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 97, "fork failed: %s"),
 402                       errmsg(errno));
 403         }
 404         for (int i = 0; argv[i] != NULL; i++) {
 405                 retmem_mb(argv[i]);
 406         }
 407         return childPid;
 408 }
 409 
 410 /*
 411  *      await(ignore_error, silent_error, target, command, running_pid)


 414  *      the returned status when the child process terminates.
 415  *
 416  *      Return value:
 417  *                              Returns true if commands ran OK
 418  *
 419  *      Parameters:
 420  *              ignore_error    Should we abort on error?
 421  *              silent_error    Should error messages be suppressed for dmake?
 422  *              target          The target we are building, for error msgs
 423  *              command         The command we ran, for error msgs
 424  *              running_pid     The pid of the process we are waiting for
 425  *              
 426  *      Static variables used:
 427  *              filter_file     The fd for the filter file
 428  *              filter_file_name The name of the filter file
 429  *
 430  *      Global variables used:
 431  *              filter_stderr   Set if -X is on
 432  */
 433 Boolean
 434 await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, void *xdrs_p, int job_msg_id)
 435 {
 436         int                     status;
 437         char                    *buffer;
 438         int                     core_dumped;
 439         int                     exit_status;
 440         FILE                    *outfp;
 441         register pid_t          pid;
 442         struct stat             stat_buff;
 443         int                     termination_signal;
 444         char                    tmp_buf[MAXPATHLEN];
 445 
 446         while ((pid = wait(&status)) != running_pid) {
 447                 if (pid == -1) {
 448                         fatal_mksh(catgets(libmksdmsi18n_catd, 1, 98, "wait() failed: %s"), errmsg(errno));
 449                 }
 450         }
 451         (void) fflush(stdout);
 452         (void) fflush(stderr);
 453 
 454         if (status == 0) {


 461         }
 462 
 463 #ifdef PRINT_EXIT_STATUS
 464         warning_mksh(NOCATGETS("I'm in await(), and status is *NOT* 0."));
 465 #endif
 466 
 467 
 468         exit_status = WEXITSTATUS(status);
 469 
 470 #ifdef PRINT_EXIT_STATUS
 471         warning_mksh(NOCATGETS("I'm in await(), and exit_status is %d."), exit_status);
 472 #endif
 473 
 474         termination_signal = WTERMSIG(status);
 475         core_dumped = WCOREDUMP(status);
 476 
 477         /*
 478          * If the child returned an error, we now try to print a
 479          * nice message about it.
 480          */





 481         
 482         tmp_buf[0] = (int) nul_char;
 483         if (!silent_error) {
 484                 if (exit_status != 0) {
 485                         (void) fprintf(stdout,
 486                                        catgets(libmksdmsi18n_catd, 1, 103, "*** Error code %d"),
 487                                        exit_status);





 488                 } else {
 489                                 (void) fprintf(stdout,
 490                                                catgets(libmksdmsi18n_catd, 1, 105, "*** Signal %d"),
 491                                                termination_signal);





 492                         if (core_dumped) {
 493                                 (void) fprintf(stdout,
 494                                                catgets(libmksdmsi18n_catd, 1, 107, " - core dumped"));




 495                         }
 496                 }
 497                 if (ignore_error) {
 498                         (void) fprintf(stdout,
 499                                        catgets(libmksdmsi18n_catd, 1, 109, " (ignored)"));




 500                 }
 501                 (void) fprintf(stdout, "\n");
 502                 (void) fflush(stdout);
 503         }








 504 
 505 #ifdef PRINT_EXIT_STATUS
 506         warning_mksh(NOCATGETS("I'm in await(), returning failed."));
 507 #endif
 508 
 509         return failed;
 510 }
 511 
 512 /*
 513  *      sh_command2string(command, destination)
 514  *
 515  *      Run one sh command and capture the output from it.
 516  *
 517  *      Return value:
 518  *
 519  *      Parameters:
 520  *              command         The command to run
 521  *              destination     Where to deposit the output from the command
 522  *              
 523  *      Static variables used: