83 */
84 static void delete_running_struct(Running rp);
85 static Boolean dependency_conflict(Name target);
86 static Doname distribute_process(char **commands, Property line);
87 static void doname_subtree(Name target, Boolean do_get, Boolean implicit);
88 static void dump_out_file(char *filename, Boolean err);
89 static void finish_doname(Running rp);
90 static void maybe_reread_make_state(void);
91 static void process_next(void);
92 static void reset_conditionals(int cnt, Name *targets, Property *locals);
93 static pid_t run_rule_commands(char *host, char **commands);
94 static Property *set_conditionals(int cnt, Name *targets);
95 static void store_conditionals(Running rp);
96
97
98 /*
99 * execute_parallel(line, waitflg)
100 *
101 * DMake 2.x:
102 * parallel mode: spawns a parallel process to execute the command group.
103 * distributed mode: sends the command group down the pipe to rxm.
104 *
105 * Return value:
106 * The result of the execution
107 *
108 * Parameters:
109 * line The command group to execute
110 */
111 Doname
112 execute_parallel(Property line, Boolean waitflg, Boolean local)
113 {
114 int argcnt;
115 int cmd_options = 0;
116 char *commands[MAXRULES + 5];
117 char *cp;
118 Name dmake_name;
119 Name dmake_value;
120 int ignore;
121 Name make_machines_name;
122 char **p;
123 Property prop;
166 if ((dmake_mode_type == serial_mode) ||
167 ((dmake_mode_type == parallel_mode) && (waitflg))) {
168 return (execute_serial(line));
169 }
170
171 {
172 p = commands;
173 }
174
175 argcnt = 0;
176 for (rule = line->body.line.command_used;
177 rule != NULL;
178 rule = rule->next) {
179 if (posix && (touch || quest) && !rule->always_exec) {
180 continue;
181 }
182 if (vpath_defined) {
183 rule->command_line =
184 vpath_translation(rule->command_line);
185 }
186 if (dmake_mode_type == distributed_mode) {
187 cmd_options = 0;
188 if(local) {
189 cmd_options |= local_host_mask;
190 }
191 } else {
192 silent_flag = false;
193 ignore = 0;
194 }
195 if (rule->command_line->hash.length > 0) {
196 if (++argcnt == MAXRULES) {
197 if (dmake_mode_type == distributed_mode) {
198 /* XXX - tell rxm to execute on local host. */
199 /* I WAS HERE!!! */
200 } else {
201 /* Too many rules, run serially instead. */
202 return build_serial;
203 }
204 }
205 {
206 if (rule->silent && !silent) {
207 silent_flag = true;
208 }
209 if (rule->ignore_error) {
210 ignore++;
211 }
212 /* XXX - need to add support for + prefix */
213 if (silent_flag || ignore) {
214 *p = getmem((silent_flag ? 1 : 0) +
215 ignore +
216 (strlen(rule->
217 command_line->
218 string_mb)) +
219 1);
220 cp = *p++;
221 if (silent_flag) {
222 *cp++ = (int) at_char;
223 }
224 if (ignore) {
1209 for (rp_prev = &running_list, rp = running_list;
1210 rp != NULL;
1211 rp = rp->next) {
1212 bypass_for_loop_inc_4:
1213 /*
1214 * If the state is ok or failed, then this target has
1215 * finished building.
1216 * In parallel_mode, output the accumulated stdout/stderr.
1217 * Read the auto dependency stuff, handle a failed build,
1218 * update the target, then finish the doname process for
1219 * that target.
1220 */
1221 if (rp->state == build_ok || rp->state == build_failed) {
1222 *rp_prev = rp->next;
1223 if (rp->next == NULL) {
1224 running_tail = rp_prev;
1225 }
1226 if ((line2 = rp->command) == NULL) {
1227 line2 = get_prop(rp->target->prop, line_prop);
1228 }
1229 if (dmake_mode_type == distributed_mode) {
1230 if (rp->make_refd) {
1231 maybe_reread_make_state();
1232 }
1233 } else {
1234 /*
1235 * Check if there were any job output
1236 * from the parallel build.
1237 */
1238 if (rp->stdout_file != NULL) {
1239 if (stat(rp->stdout_file, &out_buf) < 0) {
1240 fatal(catgets(catd, 1, 130, "stat of %s failed: %s"),
1241 rp->stdout_file,
1242 errmsg(errno));
1243 }
1244 if ((line2 != NULL) &&
1245 (out_buf.st_size > 0)) {
1246 cmds_length = 0;
1247 for (rule = line2->body.line.command_used,
1248 silent_flag = silent;
1249 rule != NULL;
1250 rule = rule->next) {
1251 cmds_length += rule->command_line->hash.length + 1;
1252 silent_flag = BOOLEAN(silent_flag || rule->silent);
1253 }
1254 if (out_buf.st_size != cmds_length || silent_flag ||
1255 output_mode == txt2_mode) {
1256 dump_out_file(rp->stdout_file, false);
1257 }
1258 }
1259 (void) unlink(rp->stdout_file);
1260 retmem_mb(rp->stdout_file);
1261 rp->stdout_file = NULL;
1262 }
1263
1264 if (!out_err_same && (rp->stderr_file != NULL)) {
1265 if (stat(rp->stderr_file, &out_buf) < 0) {
1266 fatal(catgets(catd, 1, 130, "stat of %s failed: %s"),
1267 rp->stderr_file,
1268 errmsg(errno));
1269 }
1270 if ((line2 != NULL) &&
1271 (out_buf.st_size > 0)) {
1272 dump_out_file(rp->stderr_file, true);
1273 }
1274 (void) unlink(rp->stderr_file);
1275 retmem_mb(rp->stderr_file);
1276 rp->stderr_file = NULL;
1277 }
1278 }
1279 check_state(rp->temp_file);
1280 if (rp->temp_file != NULL) {
1281 free_name(rp->temp_file);
1282 }
1283 rp->temp_file = NULL;
1284 if (rp->state == build_failed) {
1285 line = get_prop(rp->target->prop, line_prop);
1286 if (line != NULL) {
1287 line->body.line.command_used = NULL;
1288 }
1289 if (continue_after_error ||
1290 fatal_in_progress ||
1291 !docheck) {
1292 warning(catgets(catd, 1, 256, "Command failed for target `%s'"),
1293 rp->command ? line2->body.line.target->string_mb : rp->target->string_mb);
1294 build_failed_seen = true;
1295 } else {
1296 /*
1297 * XXX??? - DMake needs to exit(),
1298 * but shouldn't call fatal().
|
83 */
84 static void delete_running_struct(Running rp);
85 static Boolean dependency_conflict(Name target);
86 static Doname distribute_process(char **commands, Property line);
87 static void doname_subtree(Name target, Boolean do_get, Boolean implicit);
88 static void dump_out_file(char *filename, Boolean err);
89 static void finish_doname(Running rp);
90 static void maybe_reread_make_state(void);
91 static void process_next(void);
92 static void reset_conditionals(int cnt, Name *targets, Property *locals);
93 static pid_t run_rule_commands(char *host, char **commands);
94 static Property *set_conditionals(int cnt, Name *targets);
95 static void store_conditionals(Running rp);
96
97
98 /*
99 * execute_parallel(line, waitflg)
100 *
101 * DMake 2.x:
102 * parallel mode: spawns a parallel process to execute the command group.
103 *
104 * Return value:
105 * The result of the execution
106 *
107 * Parameters:
108 * line The command group to execute
109 */
110 Doname
111 execute_parallel(Property line, Boolean waitflg, Boolean local)
112 {
113 int argcnt;
114 int cmd_options = 0;
115 char *commands[MAXRULES + 5];
116 char *cp;
117 Name dmake_name;
118 Name dmake_value;
119 int ignore;
120 Name make_machines_name;
121 char **p;
122 Property prop;
165 if ((dmake_mode_type == serial_mode) ||
166 ((dmake_mode_type == parallel_mode) && (waitflg))) {
167 return (execute_serial(line));
168 }
169
170 {
171 p = commands;
172 }
173
174 argcnt = 0;
175 for (rule = line->body.line.command_used;
176 rule != NULL;
177 rule = rule->next) {
178 if (posix && (touch || quest) && !rule->always_exec) {
179 continue;
180 }
181 if (vpath_defined) {
182 rule->command_line =
183 vpath_translation(rule->command_line);
184 }
185
186 silent_flag = false;
187 ignore = 0;
188
189 if (rule->command_line->hash.length > 0) {
190 if (++argcnt == MAXRULES) {
191 return build_serial;
192 }
193 {
194 if (rule->silent && !silent) {
195 silent_flag = true;
196 }
197 if (rule->ignore_error) {
198 ignore++;
199 }
200 /* XXX - need to add support for + prefix */
201 if (silent_flag || ignore) {
202 *p = getmem((silent_flag ? 1 : 0) +
203 ignore +
204 (strlen(rule->
205 command_line->
206 string_mb)) +
207 1);
208 cp = *p++;
209 if (silent_flag) {
210 *cp++ = (int) at_char;
211 }
212 if (ignore) {
1197 for (rp_prev = &running_list, rp = running_list;
1198 rp != NULL;
1199 rp = rp->next) {
1200 bypass_for_loop_inc_4:
1201 /*
1202 * If the state is ok or failed, then this target has
1203 * finished building.
1204 * In parallel_mode, output the accumulated stdout/stderr.
1205 * Read the auto dependency stuff, handle a failed build,
1206 * update the target, then finish the doname process for
1207 * that target.
1208 */
1209 if (rp->state == build_ok || rp->state == build_failed) {
1210 *rp_prev = rp->next;
1211 if (rp->next == NULL) {
1212 running_tail = rp_prev;
1213 }
1214 if ((line2 = rp->command) == NULL) {
1215 line2 = get_prop(rp->target->prop, line_prop);
1216 }
1217
1218
1219 /*
1220 * Check if there were any job output
1221 * from the parallel build.
1222 */
1223 if (rp->stdout_file != NULL) {
1224 if (stat(rp->stdout_file, &out_buf) < 0) {
1225 fatal(catgets(catd, 1, 130, "stat of %s failed: %s"),
1226 rp->stdout_file,
1227 errmsg(errno));
1228 }
1229
1230 if ((line2 != NULL) &&
1231 (out_buf.st_size > 0)) {
1232 cmds_length = 0;
1233 for (rule = line2->body.line.command_used,
1234 silent_flag = silent;
1235 rule != NULL;
1236 rule = rule->next) {
1237 cmds_length += rule->command_line->hash.length + 1;
1238 silent_flag = BOOLEAN(silent_flag || rule->silent);
1239 }
1240 if (out_buf.st_size != cmds_length || silent_flag ||
1241 output_mode == txt2_mode) {
1242 dump_out_file(rp->stdout_file, false);
1243 }
1244 }
1245 (void) unlink(rp->stdout_file);
1246 retmem_mb(rp->stdout_file);
1247 rp->stdout_file = NULL;
1248 }
1249
1250 if (!out_err_same && (rp->stderr_file != NULL)) {
1251 if (stat(rp->stderr_file, &out_buf) < 0) {
1252 fatal(catgets(catd, 1, 130, "stat of %s failed: %s"),
1253 rp->stderr_file,
1254 errmsg(errno));
1255 }
1256 if ((line2 != NULL) &&
1257 (out_buf.st_size > 0)) {
1258 dump_out_file(rp->stderr_file, true);
1259 }
1260 (void) unlink(rp->stderr_file);
1261 retmem_mb(rp->stderr_file);
1262 rp->stderr_file = NULL;
1263 }
1264
1265 check_state(rp->temp_file);
1266 if (rp->temp_file != NULL) {
1267 free_name(rp->temp_file);
1268 }
1269 rp->temp_file = NULL;
1270 if (rp->state == build_failed) {
1271 line = get_prop(rp->target->prop, line_prop);
1272 if (line != NULL) {
1273 line->body.line.command_used = NULL;
1274 }
1275 if (continue_after_error ||
1276 fatal_in_progress ||
1277 !docheck) {
1278 warning(catgets(catd, 1, 256, "Command failed for target `%s'"),
1279 rp->command ? line2->body.line.target->string_mb : rp->target->string_mb);
1280 build_failed_seen = true;
1281 } else {
1282 /*
1283 * XXX??? - DMake needs to exit(),
1284 * but shouldn't call fatal().
|