00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 #include "config.h"
00028 #endif
00029
00030 #include <stdio.h>
00031 #include <errno.h>
00032 #ifdef NEED_DECLARATION_ERRNO
00033 extern int errno;
00034 #endif
00035 #ifdef HAVE_STRING_H
00036 #include <string.h>
00037 #endif
00038 #ifdef HAVE_UNISTD_H
00039 #include <unistd.h>
00040 #endif
00041 #ifdef HAVE_STDLIB_H
00042 #include <stdlib.h>
00043 #endif
00044 #ifdef HAVE_SYS_WAIT_H
00045 #include <sys/wait.h>
00046 #endif
00047
00048 #include "libiberty.h"
00049 #include "safe-ctype.h"
00050
00051
00052 #define STDIN_FILE_NO 0
00053
00054
00055 #define STDOUT_FILE_NO 1
00056
00057
00058 #define READ_PORT 0
00059
00060
00061 #define WRITE_PORT 1
00062
00063 static char *install_error_msg = "installation problem, cannot exec `%s'";
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 #ifdef __MSDOS__
00129
00130
00131
00132
00133
00134
00135 #include <process.h>
00136
00137
00138 static int last_pid = 0;
00139 static int last_status = 0;
00140 static int last_reaped = 0;
00141
00142 int
00143 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
00144 const char *program;
00145 char * const *argv;
00146 const char *this_pname;
00147 const char *temp_base;
00148 char **errmsg_fmt, **errmsg_arg;
00149 int flags;
00150 {
00151 int rc;
00152
00153 last_pid++;
00154 if (last_pid < 0)
00155 last_pid = 1;
00156
00157 if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
00158 abort ();
00159
00160 #ifdef __DJGPP__
00161
00162 rc = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (P_WAIT, program, argv);
00163 #else
00164 char *scmd, *rf;
00165 FILE *argfile;
00166 int i, el = flags & PEXECUTE_SEARCH ? 4 : 0;
00167
00168 if (temp_base == 0)
00169 temp_base = choose_temp_base ();
00170 scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el);
00171 rf = scmd + strlen(program) + 2 + el;
00172 sprintf (scmd, "%s%s @%s.gp", program,
00173 (flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base);
00174 argfile = fopen (rf, "w");
00175 if (argfile == 0)
00176 {
00177 int errno_save = errno;
00178 free (scmd);
00179 errno = errno_save;
00180 *errmsg_fmt = "cannot open `%s.gp'";
00181 *errmsg_arg = temp_base;
00182 return -1;
00183 }
00184
00185 for (i=1; argv[i]; i++)
00186 {
00187 char *cp;
00188 for (cp = argv[i]; *cp; cp++)
00189 {
00190 if (*cp == '"' || *cp == '\'' || *cp == '\\' || ISSPACE (*cp))
00191 fputc ('\\', argfile);
00192 fputc (*cp, argfile);
00193 }
00194 fputc ('\n', argfile);
00195 }
00196 fclose (argfile);
00197
00198 rc = system (scmd);
00199
00200 {
00201 int errno_save = errno;
00202 remove (rf);
00203 free (scmd);
00204 errno = errno_save;
00205 }
00206 #endif
00207
00208 if (rc == -1)
00209 {
00210 *errmsg_fmt = install_error_msg;
00211 *errmsg_arg = (char *)program;
00212 return -1;
00213 }
00214
00215
00216 last_status = rc << 8;
00217 return last_pid;
00218 }
00219
00220
00221 #ifdef ECHILD
00222 #define PWAIT_ERROR ECHILD
00223 #else
00224 #define PWAIT_ERROR EINVAL
00225 #endif
00226
00227 int
00228 pwait (pid, status, flags)
00229 int pid;
00230 int *status;
00231 int flags;
00232 {
00233
00234 if (pid != last_pid
00235
00236 || pid == last_reaped)
00237 {
00238 errno = PWAIT_ERROR;
00239 return -1;
00240 }
00241
00242
00243 #ifdef __DJGPP__
00244 *status = (last_status >> 8);
00245 #else
00246 *status = last_status;
00247 #endif
00248 last_reaped = last_pid;
00249 return last_pid;
00250 }
00251
00252 #endif
00253
00254 #if defined (_WIN32) && ! defined (_UWIN)
00255
00256 #include <process.h>
00257
00258 #ifdef __CYGWIN__
00259
00260 #define fix_argv(argvec) (argvec)
00261
00262 extern int _spawnv ();
00263 extern int _spawnvp ();
00264
00265 #else
00266
00267
00268
00269
00270 static const char * const *
00271 fix_argv (argvec)
00272 char **argvec;
00273 {
00274 int i;
00275
00276 for (i = 1; argvec[i] != 0; i++)
00277 {
00278 int len, j;
00279 char *temp, *newtemp;
00280
00281 temp = argvec[i];
00282 len = strlen (temp);
00283 for (j = 0; j < len; j++)
00284 {
00285 if (temp[j] == '"')
00286 {
00287 newtemp = xmalloc (len + 2);
00288 strncpy (newtemp, temp, j);
00289 newtemp [j] = '\\';
00290 strncpy (&newtemp [j+1], &temp [j], len-j);
00291 newtemp [len+1] = 0;
00292 temp = newtemp;
00293 len++;
00294 j++;
00295 }
00296 }
00297
00298 argvec[i] = temp;
00299 }
00300
00301 for (i = 0; argvec[i] != 0; i++)
00302 {
00303 if (strpbrk (argvec[i], " \t"))
00304 {
00305 int len, trailing_backslash;
00306 char *temp;
00307
00308 len = strlen (argvec[i]);
00309 trailing_backslash = 0;
00310
00311
00312
00313
00314
00315
00316
00317
00318 if (len > 1
00319 && argvec[i][len-1] == '\\'
00320 && argvec[i][len-2] != '\\')
00321 {
00322 trailing_backslash = 1;
00323 ++len;
00324 }
00325
00326 len += 2;
00327
00328 temp = xmalloc (len + 1);
00329 temp[0] = '"';
00330 strcpy (temp + 1, argvec[i]);
00331 if (trailing_backslash)
00332 temp[len-2] = '\\';
00333 temp[len-1] = '"';
00334 temp[len] = '\0';
00335
00336 argvec[i] = temp;
00337 }
00338 }
00339
00340 return (const char * const *) argvec;
00341 }
00342 #endif
00343
00344 #include <io.h>
00345 #include <fcntl.h>
00346 #include <signal.h>
00347
00348
00349
00350 #ifndef _P_WAIT
00351 # define _P_WAIT 0
00352 # define _P_NOWAIT 1
00353 # define _P_OVERLAY 2
00354 # define _P_NOWAITO 3
00355 # define _P_DETACH 4
00356
00357 # define WAIT_CHILD 0
00358 # define WAIT_GRANDCHILD 1
00359 #endif
00360
00361
00362 int
00363 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
00364 const char *program;
00365 char * const *argv;
00366 const char *this_pname;
00367 const char *temp_base;
00368 char **errmsg_fmt, **errmsg_arg;
00369 int flags;
00370 {
00371 int pid;
00372 int pdes[2], org_stdin, org_stdout;
00373 int input_desc, output_desc;
00374 int retries, sleep_interval;
00375
00376
00377
00378
00379 static int last_pipe_input;
00380
00381
00382 if (flags & PEXECUTE_FIRST)
00383 last_pipe_input = STDIN_FILE_NO;
00384
00385 input_desc = last_pipe_input;
00386
00387
00388
00389 if (! (flags & PEXECUTE_LAST))
00390 {
00391 if (_pipe (pdes, 256, O_BINARY) < 0)
00392 {
00393 *errmsg_fmt = "pipe";
00394 *errmsg_arg = NULL;
00395 return -1;
00396 }
00397 output_desc = pdes[WRITE_PORT];
00398 last_pipe_input = pdes[READ_PORT];
00399 }
00400 else
00401 {
00402
00403 output_desc = STDOUT_FILE_NO;
00404 last_pipe_input = STDIN_FILE_NO;
00405 }
00406
00407 if (input_desc != STDIN_FILE_NO)
00408 {
00409 org_stdin = dup (STDIN_FILE_NO);
00410 dup2 (input_desc, STDIN_FILE_NO);
00411 close (input_desc);
00412 }
00413
00414 if (output_desc != STDOUT_FILE_NO)
00415 {
00416 org_stdout = dup (STDOUT_FILE_NO);
00417 dup2 (output_desc, STDOUT_FILE_NO);
00418 close (output_desc);
00419 }
00420
00421 pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
00422
00423 (_P_NOWAIT, program, fix_argv((char**)argv));
00424
00425 if (input_desc != STDIN_FILE_NO)
00426 {
00427 dup2 (org_stdin, STDIN_FILE_NO);
00428 close (org_stdin);
00429 }
00430
00431 if (output_desc != STDOUT_FILE_NO)
00432 {
00433 dup2 (org_stdout, STDOUT_FILE_NO);
00434 close (org_stdout);
00435 }
00436
00437 if (pid == -1)
00438 {
00439 *errmsg_fmt = install_error_msg;
00440 #ifdef __MINGW32__
00441 *errmsg_arg = (char*)program;
00442 #else
00443 *errmsg_arg = program;
00444 #endif
00445 return -1;
00446 }
00447
00448 return pid;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458 int
00459 pwait (pid, status, flags)
00460 int pid;
00461 int *status;
00462 int flags;
00463 {
00464 #ifdef __CYGWIN__
00465 return wait (status);
00466 #else
00467 int termstat;
00468
00469 pid = _cwait (&termstat, pid, WAIT_CHILD);
00470
00471
00472
00473
00474
00475
00476
00477
00478 if (termstat == 3)
00479 *status = SIGABRT;
00480 else
00481 *status = (((termstat) & 0xff) << 8);
00482
00483 return pid;
00484 #endif
00485 }
00486
00487 #endif
00488
00489 #ifdef OS2
00490
00491
00492 extern int spawnv ();
00493 extern int spawnvp ();
00494
00495 int
00496 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
00497 const char *program;
00498 char * const *argv;
00499 const char *this_pname;
00500 const char *temp_base;
00501 char **errmsg_fmt, **errmsg_arg;
00502 int flags;
00503 {
00504 int pid;
00505
00506 if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
00507 abort ();
00508
00509 pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
00510 if (pid == -1)
00511 {
00512 *errmsg_fmt = install_error_msg;
00513 *errmsg_arg = program;
00514 return -1;
00515 }
00516 return pid;
00517 }
00518
00519 int
00520 pwait (pid, status, flags)
00521 int pid;
00522 int *status;
00523 int flags;
00524 {
00525
00526
00527 int pid = wait (status);
00528 return pid;
00529 }
00530
00531 #endif
00532
00533 #ifdef MPW
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 static int first_time = 1;
00551
00552 int
00553 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
00554 const char *program;
00555 char * const *argv;
00556 const char *this_pname;
00557 const char *temp_base;
00558 char **errmsg_fmt, **errmsg_arg;
00559 int flags;
00560 {
00561 char tmpprogram[255];
00562 char *cp, *tmpname;
00563 int i;
00564
00565 mpwify_filename (program, tmpprogram);
00566 if (first_time)
00567 {
00568 printf ("Set Failed 0\n");
00569 first_time = 0;
00570 }
00571
00572 fputs ("If {Failed} == 0\n", stdout);
00573
00574
00575 if (flags & PEXECUTE_VERBOSE)
00576 {
00577 fputs ("\tEcho ", stdout);
00578 fputc ('\'', stdout);
00579 fputs (tmpprogram, stdout);
00580 fputc ('\'', stdout);
00581 fputc (' ', stdout);
00582 for (i=1; argv[i]; i++)
00583 {
00584 fputc ('\'', stdout);
00585
00586 if (strchr(argv[i], '/'))
00587 {
00588 tmpname = (char *) xmalloc (256);
00589 mpwify_filename (argv[i], tmpname);
00590 argv[i] = tmpname;
00591 }
00592 for (cp = argv[i]; *cp; cp++)
00593 {
00594
00595 if (strchr("'+", *cp))
00596 fputc ('\266', stdout);
00597 fputc (*cp, stdout);
00598 }
00599 fputc ('\'', stdout);
00600 fputc (' ', stdout);
00601 }
00602 fputs ("\n", stdout);
00603 }
00604 fputs ("\t", stdout);
00605 fputs (tmpprogram, stdout);
00606 fputc (' ', stdout);
00607
00608 for (i=1; argv[i]; i++)
00609 {
00610
00611 if (strchr(argv[i], '/'))
00612 {
00613 tmpname = (char *) xmalloc (256);
00614 mpwify_filename (argv[i], tmpname);
00615 argv[i] = tmpname;
00616 }
00617 if (strchr (argv[i], ' '))
00618 fputc ('\'', stdout);
00619 for (cp = argv[i]; *cp; cp++)
00620 {
00621
00622 if (strchr("'+", *cp))
00623 fputc ('\266', stdout);
00624 fputc (*cp, stdout);
00625 }
00626 if (strchr (argv[i], ' '))
00627 fputc ('\'', stdout);
00628 fputc (' ', stdout);
00629 }
00630
00631 fputs ("\n", stdout);
00632
00633
00634
00635
00636
00637 fputs ("\tSet TmpStatus {Status}\n", stdout);
00638 fputs ("\tIf {TmpStatus} != 0\n", stdout);
00639 fputs ("\t\tSet Failed {TmpStatus}\n", stdout);
00640 fputs ("\tEnd\n", stdout);
00641 fputs ("End\n", stdout);
00642
00643
00644 return 0;
00645 }
00646
00647 int
00648 pwait (pid, status, flags)
00649 int pid;
00650 int *status;
00651 int flags;
00652 {
00653 *status = 0;
00654 return 0;
00655 }
00656
00657
00658
00659
00660 void
00661 pfinish ()
00662 {
00663 printf ("\tExit \"{Failed}\"\n");
00664 }
00665
00666 #endif
00667
00668
00669 #if ! defined (__MSDOS__) && ! defined (OS2) && ! defined (MPW) \
00670 && ! (defined (_WIN32) && ! defined (_UWIN))
00671
00672 extern int execv ();
00673 extern int execvp ();
00674
00675 int
00676 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
00677 const char *program;
00678 char * const *argv;
00679 const char *this_pname;
00680 const char *temp_base ATTRIBUTE_UNUSED;
00681 char **errmsg_fmt, **errmsg_arg;
00682 int flags;
00683 {
00684 int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
00685 int pid;
00686 int pdes[2];
00687 int input_desc, output_desc;
00688 int retries, sleep_interval;
00689
00690
00691
00692 static int last_pipe_input;
00693
00694
00695 if (flags & PEXECUTE_FIRST)
00696 last_pipe_input = STDIN_FILE_NO;
00697
00698 input_desc = last_pipe_input;
00699
00700
00701
00702 if (! (flags & PEXECUTE_LAST))
00703 {
00704 if (pipe (pdes) < 0)
00705 {
00706 *errmsg_fmt = "pipe";
00707 *errmsg_arg = NULL;
00708 return -1;
00709 }
00710 output_desc = pdes[WRITE_PORT];
00711 last_pipe_input = pdes[READ_PORT];
00712 }
00713 else
00714 {
00715
00716 output_desc = STDOUT_FILE_NO;
00717 last_pipe_input = STDIN_FILE_NO;
00718 }
00719
00720
00721 sleep_interval = 1;
00722 pid = -1;
00723 for (retries = 0; retries < 4; retries++)
00724 {
00725 pid = fork ();
00726 if (pid >= 0)
00727 break;
00728 sleep (sleep_interval);
00729 sleep_interval *= 2;
00730 }
00731
00732 switch (pid)
00733 {
00734 case -1:
00735 *errmsg_fmt = "fork";
00736 *errmsg_arg = NULL;
00737 return -1;
00738
00739 case 0:
00740
00741 if (input_desc != STDIN_FILE_NO)
00742 {
00743 close (STDIN_FILE_NO);
00744 dup (input_desc);
00745 close (input_desc);
00746 }
00747 if (output_desc != STDOUT_FILE_NO)
00748 {
00749 close (STDOUT_FILE_NO);
00750 dup (output_desc);
00751 close (output_desc);
00752 }
00753
00754
00755 if (last_pipe_input != STDIN_FILE_NO)
00756 close (last_pipe_input);
00757
00758
00759 (*func) (program, argv);
00760
00761 fprintf (stderr, "%s: ", this_pname);
00762 fprintf (stderr, install_error_msg, program);
00763 fprintf (stderr, ": %s\n", xstrerror (errno));
00764 exit (-1);
00765
00766 return 0;
00767
00768 default:
00769
00770
00771 if (input_desc != STDIN_FILE_NO)
00772 close (input_desc);
00773 if (output_desc != STDOUT_FILE_NO)
00774 close (output_desc);
00775
00776
00777 return pid;
00778 }
00779 }
00780
00781 int
00782 pwait (pid, status, flags)
00783 int pid;
00784 int *status;
00785 int flags ATTRIBUTE_UNUSED;
00786 {
00787
00788
00789 #ifdef VMS
00790 pid = waitpid (-1, status, 0);
00791 #else
00792 pid = wait (status);
00793 #endif
00794 return pid;
00795 }
00796
00797 #endif