Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Background jobs with no job control / disown bug?
- X-seq: zsh-workers 524
- From: Zoltan Hidvegi <hzoli@xxxxxxxxxx>
- To: coleman@xxxxxxxxxxxxxxx (Richard Coleman)
- Subject: Re: Background jobs with no job control / disown bug?
- Date: Fri, 3 Nov 1995 16:05:45 +0100 (MET)
- In-reply-to: <199511031136.GAA02019@xxxxxxxxxxxxxxxxxxxxxxxxx> from "Richard Coleman" at Nov 3, 95 06:36:01 am
- Sender: hzoli@xxxxxxxxxx
> I had thought that adding a new pre-command `nojob' would be
> a good idea. But to do this right would probably require some
> work.
Zefram posted a solution for that which I like quite much. It is part of my
releases sine it appeared. I had to rewrite it for the latest test releases
and now it is much simpler than the original. The large patch to zsh.h only
renumbers the symbols.
Cheers,
Zoltan
diff -c Doc/zshbuiltins.1.orig Doc/zshbuiltins.1
*** Doc/zshbuiltins.1.orig Sun Oct 29 11:52:03 1995
--- Doc/zshbuiltins.1 Fri Nov 3 13:48:25 1995
***************
*** 225,231 ****
--- 225,237 ----
are disabled. Disabled objects can be enabled with the \fBenable\fP
command.
.TP
+ .PD 0
\fBdisown\fP [ \fIjob\fP ... ]
+ .TP
+ \fIjob\fP ... \fB&|\fP
+ .TP
+ \fIjob\fP ... \fB&!\fP
+ .PD
Remove the specified jobs from the job table; the shell will
no longer report their status, and will not complain if you
try to exit an interactive shell with them running or stopped.
diff -c Doc/zshmisc.1.orig Doc/zshmisc.1
*** Doc/zshmisc.1.orig Sun Oct 29 11:52:06 1995
--- Doc/zshmisc.1 Fri Nov 3 13:49:00 1995
***************
*** 35,46 ****
operators have equal precedence and are left associative.
.PP
A \fIlist\fP is a sequence of one or more sublists
! separated by, and optionally terminated by, \fB;\fP, \fB&\fP,
! or a newline.
Normally the shell waits for each list to finish before executing
the next one.
! If a list is terminated by a \fB&\fP, the shell executes
! it in the background, and does not wait for it to finish.
.SH "PRECOMMAND MODIFIERS"
A simple command may be preceded by a \fIprecommand\fP modifier
which will alter how the command is interpreted.
--- 35,46 ----
operators have equal precedence and are left associative.
.PP
A \fIlist\fP is a sequence of one or more sublists
! separated by, and optionally terminated by, \fB;\fP, \fB&\fP, \fB&|\fP,
! \fB&!\fP or a newline.
Normally the shell waits for each list to finish before executing
the next one.
! If a list is terminated by \fB&\fP, \fB&|\fP or \fB&!\fP, the shell
! executes it in the background, and does not wait for it to finish.
.SH "PRECOMMAND MODIFIERS"
A simple command may be preceded by a \fIprecommand\fP modifier
which will alter how the command is interpreted.
***************
*** 642,647 ****
--- 642,655 ----
.PP
indicating that the job which was started asynchronously was job number
1 and had one (top-level) process, whose process id was 1234.
+ .PP
+ If a job is started with
+ .BR &|
+ or
+ .BR &! ,
+ then that job is immediately disowned. After startup, it
+ does not have a place in the job table, and is not subject
+ to the job control features described here.
.PP
If you are running a job and wish to do something else you may hit the key
\fB^Z\fR (control-Z) which sends a TSTP signal to the current job.
diff -c Src/exec.c.orig Src/exec.c
*** Src/exec.c.orig Sun Oct 29 11:50:12 1995
--- Src/exec.c Fri Nov 3 13:07:52 1995
***************
*** 647,653 ****
lastwj = newjob;
if (l->flags & PFLAG_COPROC)
close(ipipe[1]);
! spawnjob();
child_unblock();
return 0;
} else {
--- 647,658 ----
lastwj = newjob;
if (l->flags & PFLAG_COPROC)
close(ipipe[1]);
! if (how & Z_DISOWN) {
! deletejob(jobtab + thisjob);
! thisjob = -1;
! }
! else
! spawnjob();
child_unblock();
return 0;
} else {
***************
*** 1131,1137 ****
/* If the command begins with `%', then assume it is a *
* reference to a job in the job table. */
if (nonempty(args) && *(char *)peekfirst(args) == '%') {
! pushnode(args, dupstring((how & Z_ASYNC) ? "bg" : "fg"));
how = Z_SYNC;
}
--- 1136,1142 ----
/* If the command begins with `%', then assume it is a *
* reference to a job in the job table. */
if (nonempty(args) && *(char *)peekfirst(args) == '%') {
! pushnode(args, dupstring((how & Z_DISOWN) ? "disown" : (how & Z_ASYNC) ? "bg" : "fg"));
how = Z_SYNC;
}
***************
*** 1298,1304 ****
close(synch[1]);
read(synch[0], &dummy, 1);
close(synch[0]);
! if (how & Z_ASYNC) {
lastpid = pid;
} else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars)) {
/* search for STTY=... */
--- 1303,1309 ----
close(synch[1]);
read(synch[0], &dummy, 1);
close(synch[0]);
! if ((how & Z_ASYNC) && !(how & Z_DISOWN)) {
lastpid = pid;
} else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars)) {
/* search for STTY=... */
diff -c Src/lex.c.orig Src/lex.c
*** Src/lex.c.orig Sun Oct 29 11:50:23 1995
--- Src/lex.c Fri Nov 3 13:05:38 1995
***************
*** 187,192 ****
--- 187,193 ----
case SEMI:
case DSEMI:
case AMPER:
+ case AMPERBANG:
case INPAR:
case INBRACE:
case DBAR:
***************
*** 425,435 ****
break;
case LX1_AMPER:
d = hgetc();
! if (d != '&') {
! hungetc(d);
! return AMPER;
! }
! return DAMPER;
case LX1_BAR:
d = hgetc();
if (d == '|')
--- 426,437 ----
break;
case LX1_AMPER:
d = hgetc();
! if (d == '&')
! return DAMPER;
! else if (d == '!' || d == '|')
! return AMPERBANG;
! hungetc(d);
! return AMPER;
case LX1_BAR:
d = hgetc();
if (d == '|')
diff -c Src/parse.c.orig Src/parse.c
*** Src/parse.c.orig Sun Oct 29 11:50:30 1995
--- Src/parse.c Fri Nov 3 13:05:39 1995
***************
*** 48,54 ****
/*
* event : ENDINPUT
* | SEPER
! * | sublist [ SEPER | AMPER ]
*/
/**/
List
--- 48,54 ----
/*
* event : ENDINPUT
* | SEPER
! * | sublist [ SEPER | AMPER | AMPERBANG ]
*/
/**/
List
***************
*** 90,95 ****
--- 90,100 ----
l->type = Z_ASYNC;
l->left = sl;
yylex();
+ } else if (tok == AMPERBANG) {
+ l = (List) make_list();
+ l->type = Z_ASYNC | Z_DISOWN;
+ l->left = sl;
+ yylex();
} else
l = NULL;
if (!l) {
***************
*** 135,141 ****
}
/*
! * list : { SEPER } [ sublist [ { SEPER | AMPER } list ] ]
*/
/**/
--- 140,146 ----
}
/*
! * list : { SEPER } [ sublist [ { SEPER | AMPER | AMPERBANG } list ] ]
*/
/**/
***************
*** 148,159 ****
while (tok == SEPER)
yylex();
if ((sl = par_sublist()))
! if (tok == SEPER || tok == AMPER) {
l = (List) make_list();
l->left = sl;
! l->type = (tok == SEPER) ? Z_SYNC : Z_ASYNC;
incmdpos = 1;
! while (tok == SEPER || tok == AMPER)
yylex();
l->right = par_list();
} else {
--- 153,165 ----
while (tok == SEPER)
yylex();
if ((sl = par_sublist()))
! if (tok == SEPER || tok == AMPER || tok == AMPERBANG) {
l = (List) make_list();
l->left = sl;
! l->type = (tok == SEPER) ? Z_SYNC :
! (tok == AMPER) ? Z_ASYNC : Z_ASYNC | Z_DISOWN;
incmdpos = 1;
! while (tok == SEPER || tok == AMPER || tok == AMPERBANG)
yylex();
l->right = par_list();
} else {
***************
*** 928,934 ****
break;
yylex();
}
! if (tok == AMPER)
YYERROR;
for (;;) {
if (tok == STRING) {
--- 934,940 ----
break;
yylex();
}
! if (tok == AMPER || tok == AMPERBANG)
YYERROR;
for (;;) {
if (tok == STRING) {
diff -c Src/text.c.orig Src/text.c
*** Src/text.c.orig Sun Oct 29 11:50:34 1995
--- Src/text.c Fri Nov 3 13:05:39 1995
***************
*** 164,171 ****
switch (NT_TYPE(n->ntype)) {
case N_LIST:
gt2(_List(n)->left);
! if (_List(n)->type & Z_ASYNC)
taddstr(" &");
simplifyright(_List(n));
if (_List(n)->right) {
if (tnewlins)
--- 164,174 ----
switch (NT_TYPE(n->ntype)) {
case N_LIST:
gt2(_List(n)->left);
! if (_List(n)->type & Z_ASYNC) {
taddstr(" &");
+ if (_List(n)->type & Z_DISOWN)
+ taddstr("|");
+ }
simplifyright(_List(n));
if (_List(n)->right) {
if (tnewlins)
diff -c Src/zle_tricky.c.orig Src/zle_tricky.c
*** Src/zle_tricky.c.orig Sun Oct 29 11:50:53 1995
--- Src/zle_tricky.c Fri Nov 3 13:05:39 1995
***************
*** 931,937 ****
/* We reached the end. */
if (tok == ENDINPUT)
break;
! if (tok == BAR || tok == AMPER || tok == BARAMP ||
tok == DBAR || tok == DAMPER)
/* This is one of the things that separate commands. If we
already have the things we need (e.g. the token strings),
--- 931,937 ----
/* We reached the end. */
if (tok == ENDINPUT)
break;
! if (tok == BAR || tok == AMPER || tok == AMPERBANG || tok == BARAMP ||
tok == DBAR || tok == DAMPER)
/* This is one of the things that separate commands. If we
already have the things we need (e.g. the token strings),
diff -c Src/zsh.h.orig Src/zsh.h
*** Src/zsh.h.orig Fri Nov 3 13:05:39 1995
--- Src/zsh.h Fri Nov 3 13:47:01 1995
***************
*** 130,161 ****
#define INOUTPAR 35
#define DINPAR 36
#define DOUTPAR 37
/* Tokens for reserved words */
! #define DASH 38 /* - */
! #define CASE 39 /* case */
! #define COMMAND 40 /* command */
! #define COPROC 41 /* coproc */
! #define DO 42 /* do */
! #define DONE 43 /* done */
! #define ELIF 44 /* elif */
! #define ELSE 45 /* else */
! #define ZEND 46 /* end */
! #define ESAC 47 /* esac */
! #define EXEC 48 /* exec */
! #define FI 49 /* fi */
! #define FOR 50 /* for */
! #define FOREACH 51 /* foreach */
! #define FUNC 52 /* function */
! #define IF 53 /* if */
! #define NOCORRECT 54 /* nocorrect */
! #define NOGLOB 55 /* noglob */
! #define REPEAT 56 /* repeat */
! #define SELECT 57 /* select */
! #define THEN 58 /* then */
! #define TIME 59 /* time */
! #define UNTIL 60 /* until */
! #define WHILE 61 /* while */
#define WRITE 0
#define WRITENOW 1
--- 130,162 ----
#define INOUTPAR 35
#define DINPAR 36
#define DOUTPAR 37
+ #define AMPERBANG 38
/* Tokens for reserved words */
! #define DASH 39 /* - */
! #define CASE 40 /* case */
! #define COMMAND 41 /* command */
! #define COPROC 42 /* coproc */
! #define DO 43 /* do */
! #define DONE 44 /* done */
! #define ELIF 45 /* elif */
! #define ELSE 46 /* else */
! #define ZEND 47 /* end */
! #define ESAC 48 /* esac */
! #define EXEC 49 /* exec */
! #define FI 50 /* fi */
! #define FOR 51 /* for */
! #define FOREACH 52 /* foreach */
! #define FUNC 53 /* function */
! #define IF 54 /* if */
! #define NOCORRECT 55 /* nocorrect */
! #define NOGLOB 56 /* noglob */
! #define REPEAT 57 /* repeat */
! #define SELECT 58 /* select */
! #define THEN 59 /* then */
! #define TIME 60 /* time */
! #define UNTIL 61 /* until */
! #define WHILE 62 /* while */
#define WRITE 0
#define WRITENOW 1
***************
*** 325,330 ****
--- 326,332 ----
#define Z_TIMED (1<<0) /* pipeline is being timed */
#define Z_SYNC (1<<1) /* run this sublist synchronously (;) */
#define Z_ASYNC (1<<2) /* run this sublist asynchronously (&) */
+ #define Z_DISOWN (1<<3) /* run this sublist without job control (&|) */
/* tree element for sublists */
Messages sorted by:
Reverse Date,
Date,
Thread,
Author