Changeset 2596 for vendor/gnumake/current/job.c
- Timestamp:
- Jun 20, 2012, 12:44:52 AM (13 years ago)
- Location:
- vendor/gnumake/current
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/gnumake/current
- Property svn:ignore deleted
-
vendor/gnumake/current/job.c
r1989 r2596 1 1 /* Job execution and handling for GNU Make. 2 2 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software4 Foundation, Inc.3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 4 2010 Free Software Foundation, Inc. 5 5 This file is part of GNU Make. 6 6 … … 175 175 #endif /* Don't have `union wait'. */ 176 176 177 #if ndef HAVE_UNISTD_H177 #if !defined(HAVE_UNISTD_H) && !defined(WINDOWS32) 178 178 int dup2 (); 179 179 int execve (); … … 187 187 #endif 188 188 189 /* Different systems have different requirements for pid_t. 190 Plus we have to support gettext string translation... Argh. */ 191 static const char * 192 pid2str (pid_t pid) 193 { 194 static char pidstring[100]; 195 #if defined(WINDOWS32) && (__GNUC__ > 3 || _MSC_VER > 1300) 196 /* %Id is only needed for 64-builds, which were not supported by 197 older versions of Windows compilers. */ 198 sprintf (pidstring, "%Id", pid); 199 #else 200 sprintf (pidstring, "%lu", (unsigned long) pid); 201 #endif 202 return pidstring; 203 } 204 189 205 int getloadavg (double loadavg[], int nelem); 190 206 int start_remote_job (char **argv, char **envp, int stdin_fd, int *is_remote, … … 236 252 */ 237 253 int 238 w32_kill( int pid, int sig)254 w32_kill(pid_t pid, int sig) 239 255 { 240 256 return ((process_kill((HANDLE)pid, sig) == TRUE) ? 0 : -1); … … 249 265 { 250 266 const char *const ext = unixy ? "sh" : "bat"; 251 const char *error = NULL;267 const char *error_string = NULL; 252 268 char temp_path[MAXPATHLEN]; /* need to know its length */ 253 269 unsigned path_size = GetTempPath(sizeof temp_path, temp_path); … … 295 311 else 296 312 { 297 error = map_windows32_error_to_string (er);313 error_string = map_windows32_error_to_string (er); 298 314 break; 299 315 } … … 304 320 char *const path = xmalloc (final_size); 305 321 memcpy (path, temp_path, final_size); 306 *fd = _open_osfhandle (( long)h, 0);322 *fd = _open_osfhandle ((intptr_t)h, 0); 307 323 if (unixy) 308 324 { … … 318 334 319 335 *fd = -1; 320 if (error == NULL)321 error = _("Cannot create a temporary file\n");322 fatal (NILF, error );336 if (error_string == NULL) 337 error_string = _("Cannot create a temporary file\n"); 338 fatal (NILF, error_string); 323 339 324 340 /* not reached */ … … 371 387 #endif /* __EMX__ */ 372 388 389 /* determines whether path looks to be a Bourne-like shell. */ 390 int 391 is_bourne_compatible_shell (const char *path) 392 { 393 /* list of known unix (Bourne-like) shells */ 394 const char *unix_shells[] = { 395 "sh", 396 "bash", 397 "ksh", 398 "rksh", 399 "zsh", 400 "ash", 401 "dash", 402 NULL 403 }; 404 unsigned i, len; 405 406 /* find the rightmost '/' or '\\' */ 407 const char *name = strrchr (path, '/'); 408 char *p = strrchr (path, '\\'); 409 410 if (name && p) /* take the max */ 411 name = (name > p) ? name : p; 412 else if (p) /* name must be 0 */ 413 name = p; 414 else if (!name) /* name and p must be 0 */ 415 name = path; 416 417 if (*name == '/' || *name == '\\') name++; 418 419 /* this should be able to deal with extensions on Windows-like systems */ 420 for (i = 0; unix_shells[i] != NULL; i++) { 421 len = strlen(unix_shells[i]); 422 #if defined(WINDOWS32) || defined(__MSDOS__) 423 if ((strncasecmp (name, unix_shells[i], len) == 0) && 424 (strlen(name) >= len && (name[len] == '\0' || name[len] == '.'))) 425 #else 426 if ((strncmp (name, unix_shells[i], len) == 0) && 427 (strlen(name) >= len && name[len] == '\0')) 428 #endif 429 return 1; /* a known unix-style shell */ 430 } 431 432 /* if not on the list, assume it's not a Bourne-like shell */ 433 return 0; 434 } 435 373 436 374 437 … … 518 581 any_remote |= c->remote; 519 582 any_local |= ! c->remote; 520 DB (DB_JOBS, (_("Live child 0x%08lx (%s) PID %ld%s\n"),521 (unsigned long int) c, c->file->name,522 (long) c->pid,c->remote ? _(" (remote)") : ""));583 DB (DB_JOBS, (_("Live child %p (%s) PID %s %s\n"), 584 c, c->file->name, pid2str (c->pid), 585 c->remote ? _(" (remote)") : "")); 523 586 #ifdef VMS 524 587 break; … … 556 619 else 557 620 #endif 558 pid = wait (&status);621 EINTRLOOP(pid, wait (&status)); 559 622 #endif /* !VMS */ 560 623 } … … 641 704 } 642 705 else 643 DB (DB_VERBOSE, ("Main thread handle = 0x%08lx\n", 644 (unsigned long)main_thread)); 706 DB (DB_VERBOSE, ("Main thread handle = %p\n", main_thread)); 645 707 } 646 708 … … 698 760 699 761 DB (DB_JOBS, (child_failed 700 ? _("Reaping losing child 0x%08lx PID %ld %s\n") 701 : _("Reaping winning child 0x%08lx PID %ld %s\n"), 702 (unsigned long int) c, (long) c->pid, 703 c->remote ? _(" (remote)") : "")); 762 ? _("Reaping losing child %p PID %s %s\n") 763 : _("Reaping winning child %p PID %s %s\n"), 764 c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); 704 765 705 766 if (c->sh_batch_file) { … … 802 863 notice_finished_file (c->file); 803 864 804 DB (DB_JOBS, (_("Removing child 0x%08lx PID %ld%s from chain.\n"), 805 (unsigned long int) c, (long) c->pid, 806 c->remote ? _(" (remote)") : "")); 865 DB (DB_JOBS, (_("Removing child %p PID %s%s from chain.\n"), 866 c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); 807 867 808 868 /* Block fatal signals while frobnicating the list, so that … … 848 908 { 849 909 if (!jobserver_tokens) 850 fatal (NILF, "INTERNAL: Freeing child 0x%08lx(%s) but no tokens left!\n",851 (unsigned long int)child, child->file->name);910 fatal (NILF, "INTERNAL: Freeing child %p (%s) but no tokens left!\n", 911 child, child->file->name); 852 912 853 913 /* If we're using the jobserver and this child is not the only outstanding … … 865 925 pfatal_with_name (_("write jobserver")); 866 926 867 DB (DB_JOBS, (_("Released token for child 0x%08lx(%s).\n"),868 (unsigned long int)child, child->file->name));927 DB (DB_JOBS, (_("Released token for child %p (%s).\n"), 928 child, child->file->name)); 869 929 } 870 930 … … 974 1034 static int bad_stdin = -1; 975 1035 #endif 976 register char *p; 977 int flags; 1036 char *p; 1037 /* Must be volatile to silence bogus GCC warning about longjmp/vfork. */ 1038 volatile int flags; 978 1039 #ifdef VMS 979 1040 char *argv; … … 1112 1173 unixy_shell /* the test is complicated and we already did it */ 1113 1174 #else 1114 (argv[0] && !strcmp (argv[0], "/bin/sh")) 1115 #endif 1116 && (argv[1] 1117 && argv[1][0] == '-' && argv[1][1] == 'c' && argv[1][2] == '\0') 1175 (argv[0] && is_bourne_compatible_shell(argv[0])) 1176 #endif 1177 && (argv[1] && argv[1][0] == '-' 1178 && 1179 ((argv[1][1] == 'c' && argv[1][2] == '\0') 1180 || 1181 (argv[1][1] == 'e' && argv[1][2] == 'c' && argv[1][3] == '\0'))) 1118 1182 && (argv[2] && argv[2][0] == ':' && argv[2][1] == '\0') 1119 1183 && argv[3] == NULL) … … 1282 1346 close (job_rfd); 1283 1347 1348 #ifdef SET_STACK_SIZE 1349 /* Reset limits, if necessary. */ 1350 if (stack_limit.rlim_cur) 1351 setrlimit (RLIMIT_STACK, &stack_limit); 1352 #endif 1353 1284 1354 child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, 1285 1355 argv, child->environment); … … 1382 1452 1383 1453 if (hPID != INVALID_HANDLE_VALUE) 1384 child->pid = ( int) hPID;1454 child->pid = (pid_t) hPID; 1385 1455 else { 1386 1456 int i; … … 1459 1529 case cs_running: 1460 1530 c->next = children; 1461 DB (DB_JOBS, (_("Putting child 0x%08lx (%s) PID %ld%s on the chain.\n"),1462 (unsigned long int) c, c->file->name,1463 (long) c->pid,c->remote ? _(" (remote)") : ""));1531 DB (DB_JOBS, (_("Putting child %p (%s) PID %s%s on the chain.\n"), 1532 c, c->file->name, pid2str (c->pid), 1533 c->remote ? _(" (remote)") : "")); 1464 1534 children = c; 1465 1535 /* One more job slot is in use. */ … … 1601 1671 Copy the remaining uninteresting text to the output. */ 1602 1672 if (out != in) 1603 strcpy (out, in);1673 memmove (out, in, strlen (in) + 1); 1604 1674 1605 1675 /* Finally, expand the line. */ … … 1611 1681 `struct child', and add that to the chain. */ 1612 1682 1613 c = xmalloc (sizeof (struct child)); 1614 memset (c, '\0', sizeof (struct child)); 1683 c = xcalloc (sizeof (struct child)); 1615 1684 c->file = file; 1616 1685 c->command_lines = lines; … … 1713 1782 if (got_token == 1) 1714 1783 { 1715 DB (DB_JOBS, (_("Obtained token for child 0x%08lx(%s).\n"),1716 (unsigned long int)c, c->file->name));1784 DB (DB_JOBS, (_("Obtained token for child %p (%s).\n"), 1785 c, c->file->name)); 1717 1786 break; 1718 1787 } … … 2032 2101 int i; 2033 2102 fprintf(stderr, 2034 _("process_easy() failed failedto launch process (e=%ld)\n"),2103 _("process_easy() failed to launch process (e=%ld)\n"), 2035 2104 process_last_err(hPID)); 2036 2105 for (i = 0; argv[i]; i++) … … 2061 2130 break; 2062 2131 else 2132 { 2133 char *pidstr = xstrdup (pid2str ((pid_t)hWaitPID)); 2134 2063 2135 fprintf(stderr, 2064 _("make reaped child pid %ld, still waiting for pid %ld\n"), 2065 (DWORD)hWaitPID, (DWORD)hPID); 2136 _("make reaped child pid %s, still waiting for pid %s\n"), 2137 pidstr, pid2str ((pid_t)hPID)); 2138 free (pidstr); 2139 } 2066 2140 } 2067 2141 … … 2222 2296 static char ** 2223 2297 construct_command_argv_internal (char *line, char **restp, char *shell, 2224 char * ifs, int flags,2298 char *shellflags, char *ifs, int flags, 2225 2299 char **batch_filename_ptr) 2226 2300 { … … 2263 2337 "continue", "export", "read", "readonly", 2264 2338 "shift", "times", "trap", "switch", "unset", 2265 0 };2339 "ulimit", 0 }; 2266 2340 2267 2341 char *sh_chars; … … 2305 2379 #elif defined (WINDOWS32) 2306 2380 static char sh_chars_dos[] = "\"|&<>"; 2307 static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls", 2308 "copy", "ctty", "date", "del", "dir", "echo", 2309 "erase", "exit", "for", "goto", "if", "if", "md", 2310 "mkdir", "path", "pause", "prompt", "rd", "rem", 2311 "ren", "rename", "rmdir", "set", "shift", "time", 2312 "type", "ver", "verify", "vol", ":", 0 }; 2381 static char *sh_cmds_dos[] = { "assoc", "break", "call", "cd", "chcp", 2382 "chdir", "cls", "color", "copy", "ctty", 2383 "date", "del", "dir", "echo", "echo.", 2384 "endlocal", "erase", "exit", "for", "ftype", 2385 "goto", "if", "if", "md", "mkdir", "path", 2386 "pause", "prompt", "rd", "rem", "ren", 2387 "rename", "rmdir", "set", "setlocal", 2388 "shift", "time", "title", "type", "ver", 2389 "verify", "vol", ":", 0 }; 2313 2390 static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^"; 2314 2391 static char *sh_cmds_sh[] = { "cd", "eval", "exec", "exit", "login", … … 2332 2409 "login", "logout", "read", "readonly", "set", 2333 2410 "shift", "switch", "test", "times", "trap", 2334 "u mask", "wait", "while", 0 };2411 "ulimit", "umask", "unset", "wait", "while", 0 }; 2335 2412 # ifdef HAVE_DOS_PATHS 2336 2413 /* This is required if the MSYS/Cygwin ports (which do not define … … 2426 2503 if (*ap != ' ' && *ap != '\t' && *ap != '\n') 2427 2504 goto slow; 2505 2506 if (shellflags != 0) 2507 if (shellflags[0] != '-' 2508 || ((shellflags[1] != 'c' || shellflags[2] != '\0') 2509 && (shellflags[1] != 'e' || shellflags[2] != 'c' || shellflags[3] != '\0'))) 2510 goto slow; 2428 2511 2429 2512 i = strlen (line) + 1; … … 2491 2574 /* Not inside a string, but it's a special char. */ 2492 2575 goto slow; 2576 else if (one_shell && *p == '\n') 2577 /* In .ONESHELL mode \n is a separator like ; or && */ 2578 goto slow; 2493 2579 #ifdef __MSDOS__ 2494 2580 else if (*p == '.' && p[1] == '.' && p[2] == '.' && p[3] != '.') … … 2708 2794 return 0; 2709 2795 #endif /* WINDOWS32 */ 2796 2710 2797 { 2711 2798 /* SHELL may be a multi-word command. Construct a command line 2712 " SHELL -cLINE", with all special chars in LINE escaped.2799 "$(SHELL) $(.SHELLFLAGS) LINE", with all special chars in LINE escaped. 2713 2800 Then recurse, expanding this command line to get the final 2714 2801 argument list. */ 2715 2802 2716 2803 unsigned int shell_len = strlen (shell); 2717 #ifndef VMS2718 static char minus_c[] = " -c ";2719 #else2720 static char minus_c[] = "";2721 #endif2722 2804 unsigned int line_len = strlen (line); 2723 2724 char *new_line = alloca (shell_len + (sizeof (minus_c)-1) 2725 + (line_len*2) + 1); 2805 unsigned int sflags_len = strlen (shellflags); 2726 2806 char *command_ptr = NULL; /* used for batch_mode_shell mode */ 2807 char *new_line; 2727 2808 2728 2809 # ifdef __EMX__ /* is this necessary? */ 2729 2810 if (!unixy_shell) 2730 minus_c[1] = '/'; /* " /c" */2811 shellflags[0] = '/'; /* "/c" */ 2731 2812 # endif 2732 2813 2814 /* In .ONESHELL mode we are allowed to throw the entire current 2815 recipe string at a single shell and trust that the user 2816 has configured the shell and shell flags, and formatted 2817 the string, appropriately. */ 2818 if (one_shell) 2819 { 2820 /* If the shell is Bourne compatible, we must remove and ignore 2821 interior special chars [@+-] because they're meaningless to 2822 the shell itself. If, however, we're in .ONESHELL mode and 2823 have changed SHELL to something non-standard, we should 2824 leave those alone because they could be part of the 2825 script. In this case we must also leave in place 2826 any leading [@+-] for the same reason. */ 2827 2828 /* Remove and ignore interior prefix chars [@+-] because they're 2829 meaningless given a single shell. */ 2830 #if defined __MSDOS__ || defined (__EMX__) 2831 if (unixy_shell) /* the test is complicated and we already did it */ 2832 #else 2833 if (is_bourne_compatible_shell(shell)) 2834 #endif 2835 { 2836 const char *f = line; 2837 char *t = line; 2838 2839 /* Copy the recipe, removing and ignoring interior prefix chars 2840 [@+-]: they're meaningless in .ONESHELL mode. */ 2841 while (f[0] != '\0') 2842 { 2843 int esc = 0; 2844 2845 /* This is the start of a new recipe line. 2846 Skip whitespace and prefix characters. */ 2847 while (isblank (*f) || *f == '-' || *f == '@' || *f == '+') 2848 ++f; 2849 2850 /* Copy until we get to the next logical recipe line. */ 2851 while (*f != '\0') 2852 { 2853 *(t++) = *(f++); 2854 if (f[-1] == '\\') 2855 esc = !esc; 2856 else 2857 { 2858 /* On unescaped newline, we're done with this line. */ 2859 if (f[-1] == '\n' && ! esc) 2860 break; 2861 2862 /* Something else: reset the escape sequence. */ 2863 esc = 0; 2864 } 2865 } 2866 } 2867 *t = '\0'; 2868 } 2869 2870 new_argv = xmalloc (4 * sizeof (char *)); 2871 new_argv[0] = xstrdup(shell); 2872 new_argv[1] = xstrdup(shellflags); 2873 new_argv[2] = line; 2874 new_argv[3] = NULL; 2875 return new_argv; 2876 } 2877 2878 new_line = alloca (shell_len + 1 + sflags_len + 1 2879 + (line_len*2) + 1); 2733 2880 ap = new_line; 2734 2881 memcpy (ap, shell, shell_len); 2735 2882 ap += shell_len; 2736 memcpy (ap, minus_c, sizeof (minus_c) - 1); 2737 ap += sizeof (minus_c) - 1; 2883 *(ap++) = ' '; 2884 memcpy (ap, shellflags, sflags_len); 2885 ap += sflags_len; 2886 *(ap++) = ' '; 2738 2887 command_ptr = ap; 2739 2888 for (p = line; *p != '\0'; ++p) … … 2785 2934 *ap++ = *p; 2786 2935 } 2787 if (ap == new_line + shell_len + s izeof (minus_c) - 1)2936 if (ap == new_line + shell_len + sflags_len + 2) 2788 2937 /* Line was empty. */ 2789 2938 return 0; … … 2837 2986 } else 2838 2987 #endif /* WINDOWS32 */ 2988 2839 2989 if (unixy_shell) 2840 new_argv = construct_command_argv_internal (new_line, 0, 0, 0, flags, 0); 2990 new_argv = construct_command_argv_internal (new_line, 0, 0, 0, 0, flags, 0); 2991 2841 2992 #ifdef __EMX__ 2842 2993 else if (!unixy_shell) … … 2849 3000 char *q = new_line; 2850 3001 memcpy (new_line, line, line_len + 1); 2851 /* replace all backslash-newline combination and also following tabs */ 2852 while (*q != '\0') 3002 /* Replace all backslash-newline combination and also following tabs. 3003 Important: stop at the first '\n' because that's what the loop above 3004 did. The next line starting at restp[0] will be executed during the 3005 next call of this function. */ 3006 while (*q != '\0' && *q != '\n') 2853 3007 { 2854 3008 if (q[0] == '\\' && q[1] == '\n') … … 2911 3065 cannot backslash-escape the special characters (see above). */ 2912 3066 new_argv = xmalloc (sizeof (char *)); 2913 line_len = strlen (new_line) - shell_len - s izeof (minus_c) + 1;3067 line_len = strlen (new_line) - shell_len - sflags_len - 2; 2914 3068 new_argv[0] = xmalloc (line_len + 1); 2915 3069 strncpy (new_argv[0], 2916 new_line + shell_len + s izeof (minus_c) - 1, line_len);3070 new_line + shell_len + sflags_len + 2, line_len); 2917 3071 new_argv[0][line_len] = '\0'; 2918 3072 } … … 2946 3100 int cmd_flags, char **batch_filename_ptr) 2947 3101 { 2948 char *shell, *ifs ;3102 char *shell, *ifs, *shellflags; 2949 3103 char **argv; 2950 3104 … … 3051 3205 #endif /* __EMX__ */ 3052 3206 3207 shellflags = allocated_variable_expand_for_file ("$(.SHELLFLAGS)", file); 3053 3208 ifs = allocated_variable_expand_for_file ("$(IFS)", file); 3054 3209 … … 3056 3211 } 3057 3212 3058 argv = construct_command_argv_internal (line, restp, shell, ifs,3213 argv = construct_command_argv_internal (line, restp, shell, shellflags, ifs, 3059 3214 cmd_flags, batch_filename_ptr); 3060 3215 3061 3216 free (shell); 3217 free (shellflags); 3062 3218 free (ifs); 3063 3219 #endif /* !VMS */ … … 3083 3239 return fd; 3084 3240 } 3085 #endif /* !HA PE_DUP2 && !_AMIGA */3241 #endif /* !HAVE_DUP2 && !_AMIGA */ 3086 3242 3087 3243 /* On VMS systems, include special VMS functions. */
Note:
See TracChangeset
for help on using the changeset viewer.