Changeset 520 for trunk/src/gmake/job.c
- Timestamp:
- Sep 16, 2006, 6:56:25 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gmake/job.c
r516 r520 28 28 #include "debug.h" 29 29 #ifdef CONFIG_WITH_KMK_BUILTIN 30 # include "kmkbuiltin.h"30 # include "kmkbuiltin.h" 31 31 #endif 32 32 33 33 34 34 #include <string.h> 35 36 #ifdef MAKE_DLLSHELL37 #include <dlfcn.h>38 #endif39 35 40 36 /* Default shell to use. */ … … 64 60 #elif defined (__EMX__) 65 61 66 char *default_shell = "sh.exe"; 62 char *default_shell = "sh.exe"; /* bird changed this from "/bin/sh" as that doesn't make sense on OS/2. */ 67 63 int batch_mode_shell = 0; 68 64 … … 210 206 static int job_next_command PARAMS ((struct child *)); 211 207 static int start_waiting_job PARAMS ((struct child *)); 212 #ifdef MAKE_DLLSHELL213 static int spawn_command PARAMS ((char **argv, char **envp, struct child *child));214 #endif215 208 216 209 … … 492 485 int any_remote, any_local; 493 486 int dontcare; 494 #if defined(CONFIG_WITH_KMK_BUILTIN) || defined(MAKE_DLLSHELL)495 struct child *completed_child = 0;487 #ifdef CONFIG_WITH_KMK_BUILTIN 488 struct child *completed_child = NULL; 496 489 #endif 497 490 … … 534 527 any_remote |= c->remote; 535 528 any_local |= ! c->remote; 536 #if defined(CONFIG_WITH_KMK_BUILTIN) || defined(MAKE_DLLSHELL) 537 if (c->have_status) 529 #ifdef CONFIG_WITH_KMK_BUILTIN 530 if (c->has_status) 531 { 538 532 completed_child = c; 533 DB (DB_JOBS, (_("builtin child 0x%08lx (%s) PID %ld %s Status %ld\n"), 534 (unsigned long int) c, c->file->name, 535 (long) c->pid, c->remote ? _(" (remote)") : "", 536 (long) c->status)); 537 } 538 else 539 539 #endif 540 540 DB (DB_JOBS, (_("Live child 0x%08lx (%s) PID %ld %s\n"), … … 564 564 { 565 565 /* No remote children. Check for local children. */ 566 #if defined(CONFIG_WITH_KMK_BUILTIN) || defined(MAKE_DLLSHELL)566 #ifdef CONFIG_WITH_KMK_BUILTIN 567 567 if (completed_child) 568 568 { … … 577 577 } 578 578 else 579 #endif 579 #endif /* CONFIG_WITH_KMK_BUILTIN */ 580 580 #if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32) 581 581 if (any_local) … … 584 584 vmsWaitForChildren (&status); 585 585 pid = c->pid; 586 #elif MAKE_DLLSHELL587 pid = wait_jobs((int*)&status, block);588 586 #else 589 587 #ifdef WAIT_NOHANG … … 1039 1037 child->noerror = 1; 1040 1038 else if (!isblank ((unsigned char)*p)) 1039 #ifndef CONFIG_WITH_KMK_BUILTIN 1040 break; 1041 #else /* CONFIG_WITH_KMK_BUILTIN */ 1042 1041 1043 { 1042 #ifdef CONFIG_WITH_KMK_BUILTIN 1043 if ( !(flags & COMMANDS_BUILTIN) 1044 if ( !(flags & COMMANDS_KMK_BUILTIN) 1044 1045 && !strncmp(p, "kmk_builtin_", sizeof("kmk_builtin_") - 1)) 1045 flags |= COMMANDS_BUILTIN; 1046 #endif /* CONFIG_WITH_KMK_BUILTIN */ 1046 flags |= COMMANDS_KMK_BUILTIN; 1047 1047 break; 1048 1048 } 1049 #endif /* CONFIG_WITH_KMK_BUILTIN */ 1049 1050 ++p; 1050 1051 } … … 1058 1059 child->file->cmds->lines_flags[child->command_line - 1] 1059 1060 #ifdef CONFIG_WITH_KMK_BUILTIN 1060 |= flags & (COMMANDS_RECURSE | COMMANDS_ BUILTIN);1061 |= flags & (COMMANDS_RECURSE | COMMANDS_KMK_BUILTIN); 1061 1062 #else 1062 1063 |= flags & COMMANDS_RECURSE; … … 1184 1185 /* If builtin command then pass it on to the builtin shell interpreter. */ 1185 1186 1186 if ((flags & COMMANDS_ BUILTIN) && !just_print_flag)1187 if ((flags & COMMANDS_KMK_BUILTIN) && !just_print_flag) 1187 1188 { 1188 1189 int rc; … … 1209 1210 child->pid = (pid_t)42424242; 1210 1211 child->status = rc << 8; 1211 child->ha ve_status = 1;1212 child->has_status = 1; 1212 1213 return; 1213 1214 } … … 1323 1324 /* Never use fork()/exec() here! Use spawn() instead in exec_command() */ 1324 1325 child->pid = child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, 1325 argv, child->environment , child);1326 argv, child->environment); 1326 1327 if (child->pid < 0) 1327 1328 { … … 1506 1507 { 1507 1508 struct file *f = c->file; 1509 #ifdef DB_KMK 1508 1510 DB (DB_KMK, (_("start_waiting_job %p (`%s') command_flags=%#x slots=%d/%d\n"), c, c->file->name, c->file->command_flags, job_slots_used, job_slots)); 1511 #endif 1509 1512 1510 1513 /* If we can start a job remotely, we always want to, and don't care about … … 1514 1517 c->remote = start_remote_job_p (1); 1515 1518 1519 #ifdef CONFIG_WITH_EXTENDED_NOTPARALLEL 1516 1520 if (c->file->command_flags & COMMANDS_NOTPARALLEL) 1517 1521 { 1518 DB (DB_KMK, (_("not_parallel %d -> %d (file=%p `%s')\n"), not_parallel, not_parallel + 1, c->file, c->file->name)); 1522 DB (DB_KMK, (_("not_parallel %d -> %d (file=%p `%s') [start_waiting_job]\n"), 1523 not_parallel, not_parallel + 1, c->file, c->file->name)); 1524 assert(not_parallel >= 0); 1519 1525 ++not_parallel; 1520 1526 } 1527 #endif /* CONFIG_WITH_EXTENDED_NOTPARALLEL */ 1521 1528 1522 1529 /* If we are running at least one job already and the load average 1523 1530 is too high, make this one wait. */ 1524 1531 if (!c->remote 1532 #ifdef CONFIG_WITH_EXTENDED_NOTPARALLEL 1525 1533 && ((job_slots_used > 0 && (not_parallel > 0 || load_too_high ())) 1534 #else 1535 && ((job_slots_used > 0 && load_too_high ()) 1536 #endif 1526 1537 #ifdef WINDOWS32 1527 1538 || (process_used_slots () >= MAXIMUM_WAIT_OBJECTS) … … 1529 1540 )) 1530 1541 { 1542 #ifndef CONFIG_WITH_EXTENDED_NOTPARALLEL 1543 /* Put this child on the chain of children waiting for the load average 1544 to go down. */ 1545 set_command_state (f, cs_running); 1546 c->next = waiting_jobs; 1547 waiting_jobs = c; 1548 1549 #else /* CONFIG_WITH_EXTENDED_NOTPARALLEL */ 1550 1531 1551 /* Put this child on the chain of children waiting for the load average 1532 to go down. if not parallel, put it last. */1552 to go down. If not parallel, put it last. */ 1533 1553 set_command_state (f, cs_running); 1534 1554 c->next = waiting_jobs; … … 1541 1561 prev->next = c; 1542 1562 } 1543 else 1563 else /* FIXME: insert after the last node with COMMANDS_NOTPARALLEL set */ 1544 1564 waiting_jobs = c; 1545 1565 DB (DB_KMK, (_("queued child %p (`%s')\n"), c, c->file->name)); 1566 #endif /* CONFIG_WITH_EXTENDED_NOTPARALLEL */ 1546 1567 return 0; 1547 1568 } 1548 1549 1569 1550 1570 /* Start the first command; reap_children will run later command lines. */ … … 1555 1575 case cs_running: 1556 1576 c->next = children; 1557 DB (DB_JOBS, (_("Putting child 0x%08lx (%s) PID %ld%s on the chain. (%u/%u)\n"),1577 DB (DB_JOBS, (_("Putting child 0x%08lx (%s) PID %ld%s on the chain.\n"), 1558 1578 (unsigned long int) c, c->file->name, 1559 (long) c->pid, c->remote ? _(" (remote)") : "" , job_slots_used + 1, job_slots));1579 (long) c->pid, c->remote ? _(" (remote)") : "")); 1560 1580 children = c; 1561 1581 /* One more job slot is in use. */ … … 1830 1850 (void) start_waiting_job (c); 1831 1851 1832 if (job_slots == 1 || not_parallel > 0) 1852 #ifndef CONFIG_WITH_EXTENDED_NOTPARALLEL 1853 if (job_slots == 1 || not_parallel) 1833 1854 /* Since there is only one job slot, make things run linearly. 1834 1855 Wait for the child to die, setting the state to `cs_finished'. */ 1835 while (file->command_state == cs_running 1836 && (job_slots == 1 || not_parallel > 0) 1837 && (children != 0 || shell_function_pid != 0) /* reap_child condition - hackish! */) 1856 while (file->command_state == cs_running) 1838 1857 reap_children (1, 0); 1858 1859 #else /* CONFIG_WITH_EXTENDED_NOTPARALLEL */ 1860 1861 if (job_slots == 1 || not_parallel < 0) 1862 { 1863 /* Since there is only one job slot, make things run linearly. 1864 Wait for the child to die, setting the state to `cs_finished'. */ 1865 while (file->command_state == cs_running) 1866 reap_children (1, 0); 1867 } 1868 else if (not_parallel > 0) 1869 { 1870 /* wait for all live children to finish and then continue 1871 with the not-parallel child(s). FIXME: this loop could be better? */ 1872 while (file->command_state == cs_running 1873 && (children != 0 || shell_function_pid != 0) /* reap_child condition */ 1874 && not_parallel > 0) 1875 reap_children (1, 0); 1876 } 1877 #endif /* CONFIG_WITH_EXTENDED_NOTPARALLEL */ 1839 1878 1840 1879 return; … … 1987 2026 waiting_jobs = job->next; 1988 2027 1989 /* we've already counted it. */ 2028 #ifdef CONFIG_WITH_EXTENDED_NOTPARALLEL 2029 /* If it's a not-parallel job, we've already counted it once 2030 when it was queued in start_waiting_job, so decrement 2031 before sending it to start_waiting_job again. */ 1990 2032 if (job->file->command_flags & COMMANDS_NOTPARALLEL) 1991 2033 { 1992 DB (DB_KMK, (_("not_parallel %d -> %d (file=%p `%s') [waiting job]\n"), not_parallel, not_parallel - 1, job->file, job->file->name)); 2034 DB (DB_KMK, (_("not_parallel %d -> %d (file=%p `%s') [start_waiting_jobs]\n"), 2035 not_parallel, not_parallel - 1, job->file, job->file->name)); 2036 assert(not_parallel > 0); 1993 2037 --not_parallel; 1994 2038 } 2039 #endif /* CONFIG_WITH_EXTENDED_NOTPARALLEL */ 1995 2040 1996 2041 /* Try to start that job. We break out of the loop as soon … … 2006 2051 2007 2052 /* EMX: Start a child process. This function returns the new pid. */ 2008 /* The child argument can be NULL (that's why we return the pid), if it is2009 and the shell is a dllshell:// a child structure is created and inserted2010 into the child list so reap_children can do its job.2011 2012 BTW. the name of this function in this port is very misleading, spawn_job2013 would perhaps be more appropriate. */2014 2053 # if defined __MSDOS__ || defined __EMX__ 2015 2054 int 2016 child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp, 2017 struct child *child) 2055 child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp) 2018 2056 { 2019 2057 int pid; … … 2048 2086 CLOSE_ON_EXEC (stdout_fd); 2049 2087 2050 #ifdef MAKE_DLLSHELL2051 pid = spawn_command(argv, envp, child);2052 #else2053 2088 /* Run the command. */ 2054 2089 pid = exec_command (argv, envp); 2055 #endif2056 2090 2057 2091 /* Restore stdout/stdin of the parent and close temporary FDs. */ … … 2098 2132 #endif /* !AMIGA && !__MSDOS__ && !VMS */ 2099 2133 #endif /* !WINDOWS32 */ 2100 2101 2102 #ifdef MAKE_DLLSHELL2103 /* Globals for the currently loaded dllshell. */2104 char *dllshell_spec;2105 void *dllshell_dl;2106 void *dllshell_instance;2107 void *(*dllshell_init) PARAMS ((const char *spec));2108 pid_t (*dllshell_spawn) PARAMS ((void *instance, char **argv, char **envp, int *status, char *done));2109 pid_t (*dllshell_wait) PARAMS ((void *instance, int *status, int block));2110 2111 /* This is called when all pipes and such are configured for the2112 child process. The child argument may be null, see child_execute_job. */2113 static int spawn_command (char **argv, char **envp, struct child *c)2114 {2115 /* Now let's see if there is a DLLSHELL specifier in the2116 first argument. */2117 if (!strncmp(argv[0], "dllshell://", 11))2118 {2119 /* dllshell://<dllname>[!<realshell>[!whatever]] */2120 char *name, *name_end;2121 int insert_child = 0;2122 2123 /* parse it */2124 name = argv[0] + 11;2125 name_end = strchr (name, '!');2126 if (!name_end)2127 name_end = strchr (name, '\0');2128 if (name_end == name)2129 fatal (NILF, _("%s : malformed specifier!\n"), argv[0]);2130 2131 /* need loading? */2132 if (!dllshell_spec || strcmp (argv[0], dllshell_spec))2133 {2134 if (dllshell_spec)2135 fatal (NILF, _("cannot change the dllshell!!!\n"));2136 2137 dllshell_spec = strdup (argv[0]);2138 dllshell_spec[name_end - argv[0]] = '\0';2139 dllshell_dl = dlopen (dllshell_spec + (name - argv[0]), RTLD_LOCAL);2140 if (!dllshell_dl)2141 fatal (NILF, _("%s : failed to load! dlerror: '%s'\n"), argv[0], dlerror());2142 dllshell_spec[name_end - name] = '!';2143 2144 /* get symbols */2145 dllshell_init = dlsym (dllshell_dl, "dllshell_init");2146 if (!dllshell_init)2147 fatal (NILF, _("%s : failed to find symbols 'dllshell_init' dlerror: %s\n"), argv[0], dlerror());2148 dllshell_spawn = dlsym (dllshell_dl, "dllshell_spawn");2149 if (!dllshell_spawn)2150 fatal (NILF, _("%s : failed to find symbols 'dllshell_spawn' dlerror: %s\n"), argv[0], dlerror());2151 dllshell_wait = dlsym (dllshell_dl, "dllshell_wait");2152 if (!dllshell_wait)2153 fatal (NILF, _("%s : failed to find symbols 'dllshell_wait' dlerror: %s\n"), argv[0], dlerror());2154 2155 /* init */2156 dllshell_instance = dllshell_init(dllshell_spec);2157 if (!dllshell_instance)2158 fatal (NILF, _("%s : init failed!!!\n"), argv[0]);2159 }2160 2161 /* make child struct? */2162 if (!c)2163 {2164 c = (struct child *) xmalloc (sizeof (struct child));2165 bzero ((char *)c, sizeof (struct child));2166 insert_child = 1;2167 }2168 2169 /* call it. return value is 0 on succes, -1 on failure. */2170 c->pid = dllshell_spawn (dllshell_instance, argv, envp, &c->status, &c->dllshell_done);2171 DB (DB_JOBS, (_("dllshell pid=%x\n"), c->pid));2172 2173 if (insert_child && c->pid > 0)2174 {2175 c->next = children;2176 DB (DB_JOBS, (_("Putting child 0x%08lx (-) PID %ld on the chain.\n"),2177 (unsigned long int) c, (long) c->pid));2178 children = c;2179 /* One more job slot is in use. */2180 ++job_slots_used;2181 }2182 }2183 else2184 {2185 /* Run the command. */2186 #ifdef __EMX__2187 c->pid =2188 exec_command (argv, envp);2189 #else2190 # error MAKE_DLLSHELL is not ported to your platform yet.2191 #endif2192 DB (DB_JOBS, (_("spawn pid=%x\n"), c->pid));2193 }2194 2195 return c->pid;2196 }2197 2198 /* Waits or pools for a job to finish.2199 If the block argument the the function will not return2200 till a job is completed (if there are any jobs).2201 Returns pid of completed job.2202 Returns 0 if no jobs are finished.2203 Returns -1 if no jobs are running. */2204 pid_t wait_jobs (int *status, int block)2205 {2206 pid_t pid;2207 if (dllshell_wait)2208 pid = dllshell_wait(dllshell_instance, status, block);2209 else2210 {2211 if (block)2212 pid = WAIT_NOHANG(status);2213 else2214 pid = wait(status);2215 }2216 return pid;2217 }2218 2219 #endif /* MAKE_DLLSHELL */2220 2134 2221 2135 … … 2633 2547 #else /* !__MSDOS__ */ 2634 2548 else if (strcmp (shell, default_shell)) 2549 # ifndef KMK 2550 goto slow; 2551 #else /* KMK */ 2635 2552 { 2636 2553 /* Allow ash from kBuild. */ 2637 2554 const char *psz = strstr(shell, "/kmk_ash"); 2638 2555 if ( !psz 2639 || (!psz[sizeof("/kmk_ash")] && psz[sizeof("/kmk_ash")] == '.')) 2640 goto slow; 2641 } 2556 || (!psz[sizeof("/kmk_ash")] && psz[sizeof("/kmk_ash")] == '.')) /* FIXME: this test looks bogus... */ 2557 goto slow; 2558 } 2559 # endif /* KMK */ 2642 2560 #endif /* !__MSDOS__ && !__EMX__ */ 2643 2561 #endif /* not WINDOWS32 */ … … 3289 3207 } 3290 3208 #if defined(CONFIG_WITH_KMK_BUILTIN) && defined(WINDOWS32) 3209 /* On windows we have to avoid batch mode for builtin commands. */ 3291 3210 if (!strncmp(line, "kmk_builtin_", sizeof("kmk_builtin_") - 1)) 3292 3211 {
Note:
See TracChangeset
for help on using the changeset viewer.