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>
This commit is contained in:
26
shell/hush.c
26
shell/hush.c
@ -347,7 +347,7 @@
|
|||||||
|
|
||||||
#define ERR_PTR ((void*)(long)1)
|
#define ERR_PTR ((void*)(long)1)
|
||||||
|
|
||||||
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
|
#define JOB_STATUS_FORMAT "[%u] %-22s %.40s\n"
|
||||||
|
|
||||||
#define _SPECIAL_VARS_STR "_*@$!?#"
|
#define _SPECIAL_VARS_STR "_*@$!?#"
|
||||||
#define SPECIAL_VARS_STR ("_*@$!?#" + 1)
|
#define SPECIAL_VARS_STR ("_*@$!?#" + 1)
|
||||||
@ -563,7 +563,7 @@ struct pipe {
|
|||||||
int alive_cmds; /* number of commands running (not exited) */
|
int alive_cmds; /* number of commands running (not exited) */
|
||||||
int stopped_cmds; /* number of commands alive, but stopped */
|
int stopped_cmds; /* number of commands alive, but stopped */
|
||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
int jobid; /* job number */
|
unsigned jobid; /* job number */
|
||||||
pid_t pgrp; /* process group ID for the job */
|
pid_t pgrp; /* process group ID for the job */
|
||||||
char *cmdtext; /* name of job */
|
char *cmdtext; /* name of job */
|
||||||
#endif
|
#endif
|
||||||
@ -740,7 +740,7 @@ struct globals {
|
|||||||
#endif
|
#endif
|
||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
int run_list_level;
|
int run_list_level;
|
||||||
int last_jobid;
|
unsigned last_jobid;
|
||||||
pid_t saved_tty_pgrp;
|
pid_t saved_tty_pgrp;
|
||||||
struct pipe *job_list;
|
struct pipe *job_list;
|
||||||
# define G_saved_tty_pgrp (G.saved_tty_pgrp)
|
# define G_saved_tty_pgrp (G.saved_tty_pgrp)
|
||||||
@ -7043,7 +7043,7 @@ static void insert_bg_job(struct pipe *pi)
|
|||||||
job->cmdtext = xstrdup(get_cmdtext(pi));
|
job->cmdtext = xstrdup(get_cmdtext(pi));
|
||||||
|
|
||||||
if (G_interactive_fd)
|
if (G_interactive_fd)
|
||||||
printf("[%d] %d %s\n", job->jobid, job->cmds[0].pid, job->cmdtext);
|
printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext);
|
||||||
G.last_jobid = job->jobid;
|
G.last_jobid = job->jobid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9264,12 +9264,22 @@ static int FAST_FUNC builtin_type(char **argv)
|
|||||||
static struct pipe *parse_jobspec(const char *str)
|
static struct pipe *parse_jobspec(const char *str)
|
||||||
{
|
{
|
||||||
struct pipe *pi;
|
struct pipe *pi;
|
||||||
int jobnum;
|
unsigned jobnum;
|
||||||
|
|
||||||
if (sscanf(str, "%%%d", &jobnum) != 1) {
|
if (sscanf(str, "%%%u", &jobnum) != 1) {
|
||||||
|
if (str[0] != '%'
|
||||||
|
|| (str[1] != '%' && str[1] != '+' && str[1] != '\0')
|
||||||
|
) {
|
||||||
bb_error_msg("bad argument '%s'", str);
|
bb_error_msg("bad argument '%s'", str);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* It is "%%", "%+" or "%" - current job */
|
||||||
|
jobnum = G.last_jobid;
|
||||||
|
if (jobnum == 0) {
|
||||||
|
bb_error_msg("no current job");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (pi = G.job_list; pi; pi = pi->next) {
|
for (pi = G.job_list; pi; pi = pi->next) {
|
||||||
if (pi->jobid == jobnum) {
|
if (pi->jobid == jobnum) {
|
||||||
return pi;
|
return pi;
|
||||||
@ -9622,13 +9632,15 @@ static int FAST_FUNC builtin_wait(char **argv)
|
|||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
if (argv[0][0] == '%') {
|
if (argv[0][0] == '%') {
|
||||||
struct pipe *wait_pipe;
|
struct pipe *wait_pipe;
|
||||||
|
ret = 127; /* bash compat for bad jobspecs */
|
||||||
wait_pipe = parse_jobspec(*argv);
|
wait_pipe = parse_jobspec(*argv);
|
||||||
if (wait_pipe) {
|
if (wait_pipe) {
|
||||||
ret = job_exited_or_stopped(wait_pipe);
|
ret = job_exited_or_stopped(wait_pipe);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
ret = wait_for_child_or_signal(wait_pipe, 0);
|
ret = wait_for_child_or_signal(wait_pipe, 0);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
/* else: parse_jobspec() already emitted error msg */
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* mimic bash message */
|
/* mimic bash message */
|
||||||
|
Reference in New Issue
Block a user