| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: compat.c,v 1.229 2021/11/28 23:12:51 rillig Exp $ */ | | 1 | /* $NetBSD: compat.c,v 1.230 2021/12/15 10:04:49 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | | 4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -86,27 +86,27 @@ | | | @@ -86,27 +86,27 @@ |
86 | #include <sys/stat.h> | | 86 | #include <sys/stat.h> |
87 | #include <sys/wait.h> | | 87 | #include <sys/wait.h> |
88 | | | 88 | |
89 | #include <errno.h> | | 89 | #include <errno.h> |
90 | #include <signal.h> | | 90 | #include <signal.h> |
91 | | | 91 | |
92 | #include "make.h" | | 92 | #include "make.h" |
93 | #include "dir.h" | | 93 | #include "dir.h" |
94 | #include "job.h" | | 94 | #include "job.h" |
95 | #include "metachar.h" | | 95 | #include "metachar.h" |
96 | #include "pathnames.h" | | 96 | #include "pathnames.h" |
97 | | | 97 | |
98 | /* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */ | | 98 | /* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */ |
99 | MAKE_RCSID("$NetBSD: compat.c,v 1.229 2021/11/28 23:12:51 rillig Exp $"); | | 99 | MAKE_RCSID("$NetBSD: compat.c,v 1.230 2021/12/15 10:04:49 rillig Exp $"); |
100 | | | 100 | |
101 | static GNode *curTarg = NULL; | | 101 | static GNode *curTarg = NULL; |
102 | static pid_t compatChild; | | 102 | static pid_t compatChild; |
103 | static int compatSigno; | | 103 | static int compatSigno; |
104 | | | 104 | |
105 | /* | | 105 | /* |
106 | * CompatDeleteTarget -- delete the file of a failed, interrupted, or | | 106 | * CompatDeleteTarget -- delete the file of a failed, interrupted, or |
107 | * otherwise duffed target if not inhibited by .PRECIOUS. | | 107 | * otherwise duffed target if not inhibited by .PRECIOUS. |
108 | */ | | 108 | */ |
109 | static void | | 109 | static void |
110 | CompatDeleteTarget(GNode *gn) | | 110 | CompatDeleteTarget(GNode *gn) |
111 | { | | 111 | { |
112 | if (gn != NULL && !Targ_Precious(gn)) { | | 112 | if (gn != NULL && !Targ_Precious(gn)) { |
| @@ -207,122 +207,122 @@ UseShell(const char *cmd MAKE_ATTR_UNUSE | | | @@ -207,122 +207,122 @@ UseShell(const char *cmd MAKE_ATTR_UNUSE |
207 | #endif | | 207 | #endif |
208 | } | | 208 | } |
209 | | | 209 | |
210 | /* | | 210 | /* |
211 | * Execute the next command for a target. If the command returns an error, | | 211 | * Execute the next command for a target. If the command returns an error, |
212 | * the node's made field is set to ERROR and creation stops. | | 212 | * the node's made field is set to ERROR and creation stops. |
213 | * | | 213 | * |
214 | * Input: | | 214 | * Input: |
215 | * cmdp Command to execute | | 215 | * cmdp Command to execute |
216 | * gn Node from which the command came | | 216 | * gn Node from which the command came |
217 | * ln List node that contains the command | | 217 | * ln List node that contains the command |
218 | * | | 218 | * |
219 | * Results: | | 219 | * Results: |
220 | * 0 if the command succeeded, 1 if an error occurred. | | 220 | * true if the command succeeded. |
221 | */ | | 221 | */ |
222 | int | | 222 | bool |
223 | Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln) | | 223 | Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln) |
224 | { | | 224 | { |
225 | char *cmdStart; /* Start of expanded command */ | | 225 | char *cmdStart; /* Start of expanded command */ |
226 | char *bp; | | 226 | char *bp; |
227 | bool silent; /* Don't print command */ | | 227 | bool silent; /* Don't print command */ |
228 | bool doIt; /* Execute even if -n */ | | 228 | bool doIt; /* Execute even if -n */ |
229 | volatile bool errCheck; /* Check errors */ | | 229 | volatile bool errCheck; /* Check errors */ |
230 | int reason; /* Reason for child's death */ | | 230 | int reason; /* Reason for child's death */ |
231 | int status; /* Description of child's death */ | | 231 | int status; /* Description of child's death */ |
232 | pid_t cpid; /* Child actually found */ | | 232 | pid_t cpid; /* Child actually found */ |
233 | pid_t retstat; /* Result of wait */ | | 233 | pid_t retstat; /* Result of wait */ |
234 | const char **volatile av; /* Argument vector for thing to exec */ | | 234 | const char **volatile av; /* Argument vector for thing to exec */ |
235 | char **volatile mav; /* Copy of the argument vector for freeing */ | | 235 | char **volatile mav; /* Copy of the argument vector for freeing */ |
236 | bool useShell; /* True if command should be executed | | 236 | bool useShell; /* True if command should be executed |
237 | * using a shell */ | | 237 | * using a shell */ |
238 | const char *volatile cmd = cmdp; | | 238 | const char *volatile cmd = cmdp; |
239 | | | 239 | |
240 | silent = (gn->type & OP_SILENT) != OP_NONE; | | 240 | silent = (gn->type & OP_SILENT) != OP_NONE; |
241 | errCheck = !(gn->type & OP_IGNORE); | | 241 | errCheck = !(gn->type & OP_IGNORE); |
242 | doIt = false; | | 242 | doIt = false; |
243 | | | 243 | |
244 | (void)Var_Subst(cmd, gn, VARE_WANTRES, &cmdStart); | | 244 | (void)Var_Subst(cmd, gn, VARE_WANTRES, &cmdStart); |
245 | /* TODO: handle errors */ | | 245 | /* TODO: handle errors */ |
246 | | | 246 | |
247 | if (cmdStart[0] == '\0') { | | 247 | if (cmdStart[0] == '\0') { |
248 | free(cmdStart); | | 248 | free(cmdStart); |
249 | return 0; | | 249 | return true; |
250 | } | | 250 | } |
251 | cmd = cmdStart; | | 251 | cmd = cmdStart; |
252 | LstNode_Set(ln, cmdStart); | | 252 | LstNode_Set(ln, cmdStart); |
253 | | | 253 | |
254 | if (gn->type & OP_SAVE_CMDS) { | | 254 | if (gn->type & OP_SAVE_CMDS) { |
255 | GNode *endNode = Targ_GetEndNode(); | | 255 | GNode *endNode = Targ_GetEndNode(); |
256 | if (gn != endNode) { | | 256 | if (gn != endNode) { |
257 | /* | | 257 | /* |
258 | * Append the expanded command, to prevent the | | 258 | * Append the expanded command, to prevent the |
259 | * local variables from being interpreted in the | | 259 | * local variables from being interpreted in the |
260 | * scope of the .END node. | | 260 | * scope of the .END node. |
261 | * | | 261 | * |
262 | * A probably unintended side effect of this is that | | 262 | * A probably unintended side effect of this is that |
263 | * the expanded command will be expanded again in the | | 263 | * the expanded command will be expanded again in the |
264 | * .END node. Therefore, a literal '$' in these | | 264 | * .END node. Therefore, a literal '$' in these |
265 | * commands must be written as '$$$$' instead of the | | 265 | * commands must be written as '$$$$' instead of the |
266 | * usual '$$'. | | 266 | * usual '$$'. |
267 | */ | | 267 | */ |
268 | Lst_Append(&endNode->commands, cmdStart); | | 268 | Lst_Append(&endNode->commands, cmdStart); |
269 | return 0; | | 269 | return true; |
270 | } | | 270 | } |
271 | } | | 271 | } |
272 | if (strcmp(cmdStart, "...") == 0) { | | 272 | if (strcmp(cmdStart, "...") == 0) { |
273 | gn->type |= OP_SAVE_CMDS; | | 273 | gn->type |= OP_SAVE_CMDS; |
274 | return 0; | | 274 | return true; |
275 | } | | 275 | } |
276 | | | 276 | |
277 | for (;;) { | | 277 | for (;;) { |
278 | if (*cmd == '@') | | 278 | if (*cmd == '@') |
279 | silent = !DEBUG(LOUD); | | 279 | silent = !DEBUG(LOUD); |
280 | else if (*cmd == '-') | | 280 | else if (*cmd == '-') |
281 | errCheck = false; | | 281 | errCheck = false; |
282 | else if (*cmd == '+') { | | 282 | else if (*cmd == '+') { |
283 | doIt = true; | | 283 | doIt = true; |
284 | if (shellName == NULL) /* we came here from jobs */ | | 284 | if (shellName == NULL) /* we came here from jobs */ |
285 | Shell_Init(); | | 285 | Shell_Init(); |
286 | } else | | 286 | } else |
287 | break; | | 287 | break; |
288 | cmd++; | | 288 | cmd++; |
289 | } | | 289 | } |
290 | | | 290 | |
291 | while (ch_isspace(*cmd)) | | 291 | while (ch_isspace(*cmd)) |
292 | cmd++; | | 292 | cmd++; |
293 | | | 293 | |
294 | /* | | 294 | /* |
295 | * If we did not end up with a command, just skip it. | | 295 | * If we did not end up with a command, just skip it. |
296 | */ | | 296 | */ |
297 | if (cmd[0] == '\0') | | 297 | if (cmd[0] == '\0') |
298 | return 0; | | 298 | return true; |
299 | | | 299 | |
300 | useShell = UseShell(cmd); | | 300 | useShell = UseShell(cmd); |
301 | /* | | 301 | /* |
302 | * Print the command before echoing if we're not supposed to be quiet | | 302 | * Print the command before echoing if we're not supposed to be quiet |
303 | * for this one. We also print the command if -n given. | | 303 | * for this one. We also print the command if -n given. |
304 | */ | | 304 | */ |
305 | if (!silent || !GNode_ShouldExecute(gn)) { | | 305 | if (!silent || !GNode_ShouldExecute(gn)) { |
306 | printf("%s\n", cmd); | | 306 | printf("%s\n", cmd); |
307 | fflush(stdout); | | 307 | fflush(stdout); |
308 | } | | 308 | } |
309 | | | 309 | |
310 | /* | | 310 | /* |
311 | * If we're not supposed to execute any commands, this is as far as | | 311 | * If we're not supposed to execute any commands, this is as far as |
312 | * we go... | | 312 | * we go... |
313 | */ | | 313 | */ |
314 | if (!doIt && !GNode_ShouldExecute(gn)) | | 314 | if (!doIt && !GNode_ShouldExecute(gn)) |
315 | return 0; | | 315 | return true; |
316 | | | 316 | |
317 | DEBUG1(JOB, "Execute: '%s'\n", cmd); | | 317 | DEBUG1(JOB, "Execute: '%s'\n", cmd); |
318 | | | 318 | |
319 | if (useShell) { | | 319 | if (useShell) { |
320 | /* | | 320 | /* |
321 | * We need to pass the command off to the shell, typically | | 321 | * We need to pass the command off to the shell, typically |
322 | * because the command contains a "meta" character. | | 322 | * because the command contains a "meta" character. |
323 | */ | | 323 | */ |
324 | static const char *shargv[5]; | | 324 | static const char *shargv[5]; |
325 | | | 325 | |
326 | /* The following work for any of the builtin shell specs. */ | | 326 | /* The following work for any of the builtin shell specs. */ |
327 | int shargc = 0; | | 327 | int shargc = 0; |
328 | shargv[shargc++] = shellPath; | | 328 | shargv[shargc++] = shellPath; |
| @@ -444,37 +444,37 @@ Compat_RunCommand(const char *cmdp, GNod | | | @@ -444,37 +444,37 @@ Compat_RunCommand(const char *cmdp, GNod |
444 | */ | | 444 | */ |
445 | printf(" (ignored)\n"); | | 445 | printf(" (ignored)\n"); |
446 | status = 0; | | 446 | status = 0; |
447 | } | | 447 | } |
448 | } | | 448 | } |
449 | | | 449 | |
450 | free(cmdStart); | | 450 | free(cmdStart); |
451 | compatChild = 0; | | 451 | compatChild = 0; |
452 | if (compatSigno != 0) { | | 452 | if (compatSigno != 0) { |
453 | bmake_signal(compatSigno, SIG_DFL); | | 453 | bmake_signal(compatSigno, SIG_DFL); |
454 | kill(myPid, compatSigno); | | 454 | kill(myPid, compatSigno); |
455 | } | | 455 | } |
456 | | | 456 | |
457 | return status; | | 457 | return status == 0; |
458 | } | | 458 | } |
459 | | | 459 | |
460 | static void | | 460 | static void |
461 | RunCommands(GNode *gn) | | 461 | RunCommands(GNode *gn) |
462 | { | | 462 | { |
463 | StringListNode *ln; | | 463 | StringListNode *ln; |
464 | | | 464 | |
465 | for (ln = gn->commands.first; ln != NULL; ln = ln->next) { | | 465 | for (ln = gn->commands.first; ln != NULL; ln = ln->next) { |
466 | const char *cmd = ln->datum; | | 466 | const char *cmd = ln->datum; |
467 | if (Compat_RunCommand(cmd, gn, ln) != 0) | | 467 | if (!Compat_RunCommand(cmd, gn, ln)) |
468 | break; | | 468 | break; |
469 | } | | 469 | } |
470 | } | | 470 | } |
471 | | | 471 | |
472 | static void | | 472 | static void |
473 | MakeNodes(GNodeList *gnodes, GNode *pgn) | | 473 | MakeNodes(GNodeList *gnodes, GNode *pgn) |
474 | { | | 474 | { |
475 | GNodeListNode *ln; | | 475 | GNodeListNode *ln; |
476 | | | 476 | |
477 | for (ln = gnodes->first; ln != NULL; ln = ln->next) { | | 477 | for (ln = gnodes->first; ln != NULL; ln = ln->next) { |
478 | GNode *cohort = ln->datum; | | 478 | GNode *cohort = ln->datum; |
479 | Compat_Make(cohort, pgn); | | 479 | Compat_Make(cohort, pgn); |
480 | } | | 480 | } |