diff options
author | Ron Yorston <rmy@pobox.com> | 2018-11-29 08:49:07 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-11-29 08:54:30 +0000 |
commit | 9271207c4eafe6e63fa14fdb02ee36f32d4b2a21 (patch) | |
tree | df941dc447c91fa33bf9c4f6a6ff99abb7067e6c | |
parent | b30eb568206e5df7749b61a4e2fb1dd41609931b (diff) | |
download | busybox-w32-9271207c4eafe6e63fa14fdb02ee36f32d4b2a21.tar.gz busybox-w32-9271207c4eafe6e63fa14fdb02ee36f32d4b2a21.tar.bz2 busybox-w32-9271207c4eafe6e63fa14fdb02ee36f32d4b2a21.zip |
ash: fixes to spawn_forkshell
If spawn fails:
- raise an error in spawn_forkshell, not at each call site;
- free the job by calling freejob, not free.
-rw-r--r-- | shell/ash.c | 26 |
1 files changed, 10 insertions, 16 deletions
diff --git a/shell/ash.c b/shell/ash.c index 1b40e3407..29d93cdde 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -380,7 +380,7 @@ static void forkshell_init(const char *idstr); | |||
380 | static void forkshell_child(struct forkshell *fs); | 380 | static void forkshell_child(struct forkshell *fs); |
381 | static void sticky_free(void *p); | 381 | static void sticky_free(void *p); |
382 | #define free(p) sticky_free(p) | 382 | #define free(p) sticky_free(p) |
383 | static int spawn_forkshell(struct job *jp, struct forkshell *fs, int mode); | 383 | static void spawn_forkshell(struct job *jp, struct forkshell *fs, int mode); |
384 | #endif | 384 | #endif |
385 | 385 | ||
386 | /* ============ Hash table sizes. Configurable. */ | 386 | /* ============ Hash table sizes. Configurable. */ |
@@ -5700,8 +5700,7 @@ openhere(union node *redir) | |||
5700 | fs.n = redir; | 5700 | fs.n = redir; |
5701 | fs.fd[0] = pip[0]; | 5701 | fs.fd[0] = pip[0]; |
5702 | fs.fd[1] = pip[1]; | 5702 | fs.fd[1] = pip[1]; |
5703 | if (spawn_forkshell(NULL, &fs, FORK_NOJOB) < 0) | 5703 | spawn_forkshell(NULL, &fs, FORK_NOJOB); |
5704 | ash_msg_and_raise_error("unable to spawn shell"); | ||
5705 | #else | 5704 | #else |
5706 | if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { | 5705 | if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { |
5707 | /* child */ | 5706 | /* child */ |
@@ -6796,8 +6795,7 @@ evalbackcmd(union node *n, struct backcmd *result) | |||
6796 | fs.n = n; | 6795 | fs.n = n; |
6797 | fs.fd[0] = pip[0]; | 6796 | fs.fd[0] = pip[0]; |
6798 | fs.fd[1] = pip[1]; | 6797 | fs.fd[1] = pip[1]; |
6799 | if (spawn_forkshell(jp, &fs, FORK_NOJOB) < 0) | 6798 | spawn_forkshell(jp, &fs, FORK_NOJOB); |
6800 | ash_msg_and_raise_error("unable to spawn shell"); | ||
6801 | #else | 6799 | #else |
6802 | if (forkshell(jp, n, FORK_NOJOB) == 0) { | 6800 | if (forkshell(jp, n, FORK_NOJOB) == 0) { |
6803 | /* child */ | 6801 | /* child */ |
@@ -9769,8 +9767,7 @@ evalsubshell(union node *n, int flags) | |||
9769 | fs.fpid = FS_EVALSUBSHELL; | 9767 | fs.fpid = FS_EVALSUBSHELL; |
9770 | fs.n = n; | 9768 | fs.n = n; |
9771 | fs.flags = flags; | 9769 | fs.flags = flags; |
9772 | if (spawn_forkshell(jp, &fs, backgnd) < 0) | 9770 | spawn_forkshell(jp, &fs, backgnd); |
9773 | ash_msg_and_raise_error("unable to spawn shell"); | ||
9774 | if ( 0 ) { | 9771 | if ( 0 ) { |
9775 | #else | 9772 | #else |
9776 | if (forkshell(jp, n, backgnd) == 0) { | 9773 | if (forkshell(jp, n, backgnd) == 0) { |
@@ -9901,8 +9898,7 @@ evalpipe(union node *n, int flags) | |||
9901 | fs.fd[0] = pip[0]; | 9898 | fs.fd[0] = pip[0]; |
9902 | fs.fd[1] = pip[1]; | 9899 | fs.fd[1] = pip[1]; |
9903 | fs.fd[2] = prevfd; | 9900 | fs.fd[2] = prevfd; |
9904 | if (spawn_forkshell(jp, &fs, n->npipe.pipe_backgnd) < 0) | 9901 | spawn_forkshell(jp, &fs, n->npipe.pipe_backgnd); |
9905 | ash_msg_and_raise_error("unable to spawn shell"); | ||
9906 | #else | 9902 | #else |
9907 | if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) { | 9903 | if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) { |
9908 | /* child */ | 9904 | /* child */ |
@@ -10714,8 +10710,7 @@ evalcommand(union node *cmd, int flags) | |||
10714 | fs.fd[0] = cmdentry.u.index; | 10710 | fs.fd[0] = cmdentry.u.index; |
10715 | fs.strlist = varlist.list; | 10711 | fs.strlist = varlist.list; |
10716 | jp = makejob(/*cmd,*/ 1); | 10712 | jp = makejob(/*cmd,*/ 1); |
10717 | if (spawn_forkshell(jp, &fs, FORK_FG) < 0) | 10713 | spawn_forkshell(jp, &fs, FORK_FG); |
10718 | ash_msg_and_raise_error("unable to spawn shell"); | ||
10719 | status = waitforjob(jp); | 10714 | status = waitforjob(jp); |
10720 | INT_ON; | 10715 | INT_ON; |
10721 | TRACE(("forked child exited with %d\n", exitstatus)); | 10716 | TRACE(("forked child exited with %d\n", exitstatus)); |
@@ -15105,8 +15100,7 @@ reinitvar(void) | |||
15105 | vlineno.var_text = linenovar; | 15100 | vlineno.var_text = linenovar; |
15106 | } | 15101 | } |
15107 | 15102 | ||
15108 | /* FIXME: should consider running forkparent() and forkchild() */ | 15103 | static void |
15109 | static int | ||
15110 | spawn_forkshell(struct job *jp, struct forkshell *fs, int mode) | 15104 | spawn_forkshell(struct job *jp, struct forkshell *fs, int mode) |
15111 | { | 15105 | { |
15112 | struct forkshell *new; | 15106 | struct forkshell *new; |
@@ -15121,11 +15115,11 @@ spawn_forkshell(struct job *jp, struct forkshell *fs, int mode) | |||
15121 | CloseHandle(new->hMapFile); | 15115 | CloseHandle(new->hMapFile); |
15122 | UnmapViewOfFile(new); | 15116 | UnmapViewOfFile(new); |
15123 | if (ret == -1) { | 15117 | if (ret == -1) { |
15124 | free(jp); | 15118 | if (jp) |
15125 | return -1; | 15119 | freejob(jp); |
15120 | ash_msg_and_raise_error("unable to spawn shell"); | ||
15126 | } | 15121 | } |
15127 | forkparent(jp, fs->node, mode, (HANDLE)ret); | 15122 | forkparent(jp, fs->node, mode, (HANDLE)ret); |
15128 | return ret == -1 ? -1 : 0; | ||
15129 | } | 15123 | } |
15130 | 15124 | ||
15131 | /* | 15125 | /* |