aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-11-15 19:58:19 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-11-15 19:58:19 +0100
commit647553a4fcbbc169b4390d9ef8e4657f0ffe1a5f (patch)
tree974dde9bc45566319f8b9750b6397fbafe94ad43 /shell/hush.c
parentff1822aed159e1c1b5a92dc5c1fd1648b026f8f4 (diff)
downloadbusybox-w32-647553a4fcbbc169b4390d9ef8e4657f0ffe1a5f.tar.gz
busybox-w32-647553a4fcbbc169b4390d9ef8e4657f0ffe1a5f.tar.bz2
busybox-w32-647553a4fcbbc169b4390d9ef8e4657f0ffe1a5f.zip
hush: wait for `cmd` to complete, and immediately store its exitcode in $?
function old new delta expand_vars_to_list 2129 2197 +68 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 891d87be7..6f394d1d5 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2287,7 +2287,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
2287 * expanded result may need to be globbed 2287 * expanded result may need to be globbed
2288 * and $IFS-splitted */ 2288 * and $IFS-splitted */
2289 debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch); 2289 debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch);
2290 process_command_subs(&subst_result, arg); 2290 G.last_exitcode = process_command_subs(&subst_result, arg);
2291 debug_printf_subst("SUBST RES '%s'\n", subst_result.data); 2291 debug_printf_subst("SUBST RES '%s'\n", subst_result.data);
2292 val = subst_result.data; 2292 val = subst_result.data;
2293 goto store_val; 2293 goto store_val;
@@ -3904,7 +3904,7 @@ static NOINLINE int run_pipe(struct pipe *pi)
3904 /* if someone gives us an empty string: `cmd with empty output` */ 3904 /* if someone gives us an empty string: `cmd with empty output` */
3905 if (!argv_expanded[0]) { 3905 if (!argv_expanded[0]) {
3906 debug_leave(); 3906 debug_leave();
3907 return 0; 3907 return 0; // or G.last_exitcode? see emptytick.tests
3908 } 3908 }
3909 3909
3910 x = find_builtin(argv_expanded[0]); 3910 x = find_builtin(argv_expanded[0]);
@@ -5202,10 +5202,10 @@ static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_
5202 5202
5203 5203
5204#if ENABLE_HUSH_TICK 5204#if ENABLE_HUSH_TICK
5205static FILE *generate_stream_from_string(const char *s) 5205static FILE *generate_stream_from_string(const char *s, pid_t *pid_p)
5206{ 5206{
5207 FILE *pf; 5207 pid_t pid;
5208 int pid, channel[2]; 5208 int channel[2];
5209# if !BB_MMU 5209# if !BB_MMU
5210 char **to_free; 5210 char **to_free;
5211# endif 5211# endif
@@ -5291,6 +5291,7 @@ static FILE *generate_stream_from_string(const char *s)
5291 } 5291 }
5292 5292
5293 /* parent */ 5293 /* parent */
5294 *pid_p = pid;
5294# if ENABLE_HUSH_FAST 5295# if ENABLE_HUSH_FAST
5295 G.count_SIGCHLD++; 5296 G.count_SIGCHLD++;
5296//bb_error_msg("[%d] fork in generate_stream_from_string: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); 5297//bb_error_msg("[%d] fork in generate_stream_from_string: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
@@ -5300,8 +5301,8 @@ static FILE *generate_stream_from_string(const char *s)
5300 free(to_free); 5301 free(to_free);
5301# endif 5302# endif
5302 close(channel[1]); 5303 close(channel[1]);
5303 pf = fdopen(channel[0], "r"); 5304//TODO: libbb: fdopen_or_die?
5304 return pf; 5305 return fdopen(channel[0], "r");
5305} 5306}
5306 5307
5307/* Return code is exit status of the process that is run. */ 5308/* Return code is exit status of the process that is run. */
@@ -5309,9 +5310,10 @@ static int process_command_subs(o_string *dest, const char *s)
5309{ 5310{
5310 FILE *pf; 5311 FILE *pf;
5311 struct in_str pipe_str; 5312 struct in_str pipe_str;
5312 int ch, eol_cnt; 5313 pid_t pid;
5314 int status, ch, eol_cnt;
5313 5315
5314 pf = generate_stream_from_string(s); 5316 pf = generate_stream_from_string(s, &pid);
5315 if (pf == NULL) 5317 if (pf == NULL)
5316 return 1; 5318 return 1;
5317 close_on_exec_on(fileno(pf)); 5319 close_on_exec_on(fileno(pf));
@@ -5331,16 +5333,14 @@ static int process_command_subs(o_string *dest, const char *s)
5331 o_addQchr(dest, ch); 5333 o_addQchr(dest, ch);
5332 } 5334 }
5333 5335
5334 debug_printf("done reading from pipe, pclose()ing\n"); 5336 debug_printf("done reading from `cmd` pipe, closing it\n");
5335 /* Note: we got EOF, and we just close the read end of the pipe.
5336 * We do not wait for the `cmd` child to terminate. bash and ash do.
5337 * Try these:
5338 * echo `echo Hi; exec 1>&-; sleep 2` - bash waits 2 sec
5339 * `false`; echo $? - bash outputs "1"
5340 */
5341 fclose(pf); 5337 fclose(pf);
5342 debug_printf("closed FILE from child. return 0\n"); 5338 /* We need to extract exitcode. Test case
5343 return 0; 5339 * "true; echo `sleep 1; false` $?"
5340 * should print 1 */
5341 safe_waitpid(pid, &status, 0);
5342 debug_printf("child exited. returning its exitcode:%d\n", WEXITSTATUS(status));
5343 return WEXITSTATUS(status);
5344} 5344}
5345#endif /* ENABLE_HUSH_TICK */ 5345#endif /* ENABLE_HUSH_TICK */
5346 5346