aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-08 15:46:04 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-08 15:46:04 +0100
commitd5b5c2fa151d318fa96778d5871e23ede312e5fa (patch)
treeff236f5a330a4df4a03b45c24a41c5301e4958dc /shell
parent0ef478f01bb3d42f6776f58fb5891e1430af8799 (diff)
downloadbusybox-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.c30
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)
9264static struct pipe *parse_jobspec(const char *str) 9264static 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 */