]>
Commit | Line | Data |
---|---|---|
415fb8b5 PM |
1 | BASH PATCH REPORT |
2 | ================= | |
3 | ||
4 | Bash-Release: 5.0 | |
5 | Patch-ID: bash50-005 | |
6 | ||
7 | Bug-Reported-by: Brad Spencer <bspencer@blackberry.com> | |
8 | Bug-Reference-ID: <1b993ff2-ce4f-662a-6be4-393457362e47@blackberry.com> | |
9 | Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2019-01/msg00250.html | |
10 | ||
11 | Bug-Description: | |
12 | ||
13 | In certain cases, bash optimizes out a fork() call too early and prevents | |
14 | traps from running. | |
15 | ||
16 | Patch (apply with `patch -p0'): | |
17 | ||
18 | *** ../bash-5.0-patched/command.h 2018-07-20 21:16:31.000000000 -0400 | |
19 | --- command.h 2019-02-20 11:09:36.000000000 -0500 | |
20 | *************** | |
21 | *** 187,190 **** | |
22 | --- 188,192 ---- | |
23 | #define CMD_LASTPIPE 0x2000 | |
24 | #define CMD_STDPATH 0x4000 /* use standard path for command lookup */ | |
25 | + #define CMD_TRY_OPTIMIZING 0x8000 /* try to optimize this simple command */ | |
26 | ||
27 | /* What a command looks like. */ | |
28 | *** ../bash-5.0-patched/builtins/evalstring.c 2018-12-26 11:19:21.000000000 -0500 | |
29 | --- builtins/evalstring.c 2019-01-29 14:15:19.000000000 -0500 | |
30 | *************** | |
31 | *** 101,104 **** | |
32 | --- 101,113 ---- | |
33 | } | |
34 | ||
35 | + int | |
36 | + can_optimize_connection (command) | |
37 | + COMMAND *command; | |
38 | + { | |
39 | + return (*bash_input.location.string == '\0' && | |
40 | + (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && | |
41 | + command->value.Connection->second->type == cm_simple); | |
42 | + } | |
43 | + | |
44 | void | |
45 | optimize_fork (command) | |
46 | *************** | |
47 | *** 106,110 **** | |
48 | { | |
49 | if (command->type == cm_connection && | |
50 | ! (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR) && | |
51 | should_suppress_fork (command->value.Connection->second)) | |
52 | { | |
53 | --- 115,120 ---- | |
54 | { | |
55 | if (command->type == cm_connection && | |
56 | ! (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && | |
57 | ! (command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) && | |
58 | should_suppress_fork (command->value.Connection->second)) | |
59 | { | |
60 | *************** | |
61 | *** 413,418 **** | |
62 | command->value.Simple->flags |= CMD_NO_FORK; | |
63 | } | |
64 | ! else if (command->type == cm_connection) | |
65 | ! optimize_fork (command); | |
66 | #endif /* ONESHOT */ | |
67 | ||
68 | --- 423,438 ---- | |
69 | command->value.Simple->flags |= CMD_NO_FORK; | |
70 | } | |
71 | ! | |
72 | ! /* Can't optimize forks out here execept for simple commands. | |
73 | ! This knows that the parser sets up commands as left-side heavy | |
74 | ! (&& and || are left-associative) and after the single parse, | |
75 | ! if we are at the end of the command string, the last in a | |
76 | ! series of connection commands is | |
77 | ! command->value.Connection->second. */ | |
78 | ! else if (command->type == cm_connection && can_optimize_connection (command)) | |
79 | ! { | |
80 | ! command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; | |
81 | ! command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING; | |
82 | ! } | |
83 | #endif /* ONESHOT */ | |
84 | ||
85 | *** ../bash-5.0-patched/execute_cmd.c 2018-12-05 09:05:14.000000000 -0500 | |
86 | --- execute_cmd.c 2019-01-25 15:59:00.000000000 -0500 | |
87 | *************** | |
88 | *** 2768,2771 **** | |
89 | --- 2768,2773 ---- | |
90 | (exec_result != EXECUTION_SUCCESS))) | |
91 | { | |
92 | + optimize_fork (command); | |
93 | + | |
94 | second = command->value.Connection->second; | |
95 | if (ignore_return && second) | |
96 | *** ../bash-5.0/patchlevel.h 2016-06-22 14:51:03.000000000 -0400 | |
97 | --- patchlevel.h 2016-10-01 11:01:28.000000000 -0400 | |
98 | *************** | |
99 | *** 26,30 **** | |
100 | looks for to find the patch level (for the sccs version string). */ | |
101 | ||
102 | ! #define PATCHLEVEL 4 | |
103 | ||
104 | #endif /* _PATCHLEVEL_H_ */ | |
105 | --- 26,30 ---- | |
106 | looks for to find the patch level (for the sccs version string). */ | |
107 | ||
108 | ! #define PATCHLEVEL 5 | |
109 | ||
110 | #endif /* _PATCHLEVEL_H_ */ |