diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-08 15:46:04 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-08 15:46:04 +0100 |
| commit | d5b5c2fa151d318fa96778d5871e23ede312e5fa (patch) | |
| tree | ff236f5a330a4df4a03b45c24a41c5301e4958dc /shell | |
| parent | 0ef478f01bb3d42f6776f58fb5891e1430af8799 (diff) | |
| download | busybox-w32-d5b5c2fa151d318fa96778d5871e23ede312e5fa.tar.gz busybox-w32-d5b5c2fa151d318fa96778d5871e23ede312e5fa.tar.bz2 busybox-w32-d5b5c2fa151d318fa96778d5871e23ede312e5fa.zip | |
hush: support %%, %+ and % jobspec (meaning "current job")
function old new delta
parse_jobspec 83 133 +50
builtin_wait 278 283 +5
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/shell/hush.c b/shell/hush.c index a56d3b280..58132ef17 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -347,7 +347,7 @@ | |||
| 347 | 347 | ||
| 348 | #define ERR_PTR ((void*)(long)1) | 348 | #define ERR_PTR ((void*)(long)1) |
| 349 | 349 | ||
| 350 | #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" | 350 | #define JOB_STATUS_FORMAT "[%u] %-22s %.40s\n" |
| 351 | 351 | ||
| 352 | #define _SPECIAL_VARS_STR "_*@$!?#" | 352 | #define _SPECIAL_VARS_STR "_*@$!?#" |
| 353 | #define SPECIAL_VARS_STR ("_*@$!?#" + 1) | 353 | #define SPECIAL_VARS_STR ("_*@$!?#" + 1) |
| @@ -563,7 +563,7 @@ struct pipe { | |||
| 563 | int alive_cmds; /* number of commands running (not exited) */ | 563 | int alive_cmds; /* number of commands running (not exited) */ |
| 564 | int stopped_cmds; /* number of commands alive, but stopped */ | 564 | int stopped_cmds; /* number of commands alive, but stopped */ |
| 565 | #if ENABLE_HUSH_JOB | 565 | #if ENABLE_HUSH_JOB |
| 566 | int jobid; /* job number */ | 566 | unsigned jobid; /* job number */ |
| 567 | pid_t pgrp; /* process group ID for the job */ | 567 | pid_t pgrp; /* process group ID for the job */ |
| 568 | char *cmdtext; /* name of job */ | 568 | char *cmdtext; /* name of job */ |
| 569 | #endif | 569 | #endif |
| @@ -740,7 +740,7 @@ struct globals { | |||
| 740 | #endif | 740 | #endif |
| 741 | #if ENABLE_HUSH_JOB | 741 | #if ENABLE_HUSH_JOB |
| 742 | int run_list_level; | 742 | int run_list_level; |
| 743 | int last_jobid; | 743 | unsigned last_jobid; |
| 744 | pid_t saved_tty_pgrp; | 744 | pid_t saved_tty_pgrp; |
| 745 | struct pipe *job_list; | 745 | struct pipe *job_list; |
| 746 | # define G_saved_tty_pgrp (G.saved_tty_pgrp) | 746 | # define G_saved_tty_pgrp (G.saved_tty_pgrp) |
| @@ -7043,7 +7043,7 @@ static void insert_bg_job(struct pipe *pi) | |||
| 7043 | job->cmdtext = xstrdup(get_cmdtext(pi)); | 7043 | job->cmdtext = xstrdup(get_cmdtext(pi)); |
| 7044 | 7044 | ||
| 7045 | if (G_interactive_fd) | 7045 | if (G_interactive_fd) |
| 7046 | printf("[%d] %d %s\n", job->jobid, job->cmds[0].pid, job->cmdtext); | 7046 | printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext); |
| 7047 | G.last_jobid = job->jobid; | 7047 | G.last_jobid = job->jobid; |
| 7048 | } | 7048 | } |
| 7049 | 7049 | ||
| @@ -9264,11 +9264,21 @@ static int FAST_FUNC builtin_type(char **argv) | |||
| 9264 | static struct pipe *parse_jobspec(const char *str) | 9264 | static struct pipe *parse_jobspec(const char *str) |
| 9265 | { | 9265 | { |
| 9266 | struct pipe *pi; | 9266 | struct pipe *pi; |
| 9267 | int jobnum; | 9267 | unsigned jobnum; |
| 9268 | 9268 | ||
| 9269 | if (sscanf(str, "%%%d", &jobnum) != 1) { | 9269 | if (sscanf(str, "%%%u", &jobnum) != 1) { |
| 9270 | bb_error_msg("bad argument '%s'", str); | 9270 | if (str[0] != '%' |
| 9271 | return NULL; | 9271 | || (str[1] != '%' && str[1] != '+' && str[1] != '\0') |
| 9272 | ) { | ||
| 9273 | bb_error_msg("bad argument '%s'", str); | ||
| 9274 | return NULL; | ||
| 9275 | } | ||
| 9276 | /* It is "%%", "%+" or "%" - current job */ | ||
| 9277 | jobnum = G.last_jobid; | ||
| 9278 | if (jobnum == 0) { | ||
| 9279 | bb_error_msg("no current job"); | ||
| 9280 | return NULL; | ||
| 9281 | } | ||
| 9272 | } | 9282 | } |
| 9273 | for (pi = G.job_list; pi; pi = pi->next) { | 9283 | for (pi = G.job_list; pi; pi = pi->next) { |
| 9274 | if (pi->jobid == jobnum) { | 9284 | if (pi->jobid == jobnum) { |
| @@ -9622,13 +9632,15 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
| 9622 | #if ENABLE_HUSH_JOB | 9632 | #if ENABLE_HUSH_JOB |
| 9623 | if (argv[0][0] == '%') { | 9633 | if (argv[0][0] == '%') { |
| 9624 | struct pipe *wait_pipe; | 9634 | struct pipe *wait_pipe; |
| 9635 | ret = 127; /* bash compat for bad jobspecs */ | ||
| 9625 | wait_pipe = parse_jobspec(*argv); | 9636 | wait_pipe = parse_jobspec(*argv); |
| 9626 | if (wait_pipe) { | 9637 | if (wait_pipe) { |
| 9627 | ret = job_exited_or_stopped(wait_pipe); | 9638 | ret = job_exited_or_stopped(wait_pipe); |
| 9628 | if (ret < 0) | 9639 | if (ret < 0) |
| 9629 | ret = wait_for_child_or_signal(wait_pipe, 0); | 9640 | ret = wait_for_child_or_signal(wait_pipe, 0); |
| 9630 | continue; | ||
| 9631 | } | 9641 | } |
| 9642 | /* else: parse_jobspec() already emitted error msg */ | ||
| 9643 | continue; | ||
| 9632 | } | 9644 | } |
| 9633 | #endif | 9645 | #endif |
| 9634 | /* mimic bash message */ | 9646 | /* mimic bash message */ |
