* Background jobs with no job control / disown bug?
@ 1995-11-03 11:28 Peter William Stephenson
1995-11-03 11:36 ` Richard Coleman
1995-11-03 14:32 ` Chip Salzenberg
0 siblings, 2 replies; 5+ messages in thread
From: Peter William Stephenson @ 1995-11-03 11:28 UTC (permalink / raw)
To: Zsh hackers list
It occurred to me that one way of avoiding a background job getting
job control (disown is not a sufficient method in a function) is to
unsetopt MONITOR, spawn the job, then setopt MONITOR again. This
nearly works. Unfortunately,
% unsetopt monitor
% sleep 30 &
% setopt monitor
% jobs
[1] + running
i.e. it's still in the job table (but you'll find you can't do
anything with it). I suggest deleting jobs from the job table when
this is the case. I believe the following patch to spawnjob() to
delete the job table entry will fix this.
I should like to hear from someone who knows something about job
control whether this is right. For example, is it correct (as I
believe) to delete the process structures etc. as well as the job
table entry as deletejob() does? Is this going to have some dire
effect on some pipeline I don't know about (reading exec.c it seems
like everything does)?
(If it is correct and the job's associated structures need deleting,
then why doesn't disown seem to do this, instead of simply zeroing the
job entry? I don't think we can both be right. See bin_fg() in builtin.c)
*** Src/jobs.c~ Sun Oct 29 11:50:22 1995
--- Src/jobs.c Fri Nov 3 12:06:38 1995
***************
*** 590,596 ****
fflush(stderr);
}
}
! if (!jobtab[thisjob].procs)
deletejob(jobtab + thisjob);
else
jobtab[thisjob].stat |= STAT_LOCKED;
--- 590,596 ----
fflush(stderr);
}
}
! if (!jobtab[thisjob].procs || !jobbing)
deletejob(jobtab + thisjob);
else
jobtab[thisjob].stat |= STAT_LOCKED;
--
Peter Stephenson <pws@ifh.de> Tel: +49 33762 77366
WWW: http://www.ifh.de/~pws/ Fax: +49 33762 77330
Deutches Electronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen
DESY-IfH, 15735 Zeuthen, Germany.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Background jobs with no job control / disown bug?
1995-11-03 11:28 Background jobs with no job control / disown bug? Peter William Stephenson
@ 1995-11-03 11:36 ` Richard Coleman
1995-11-03 15:05 ` Zoltan Hidvegi
1995-11-03 14:32 ` Chip Salzenberg
1 sibling, 1 reply; 5+ messages in thread
From: Richard Coleman @ 1995-11-03 11:36 UTC (permalink / raw)
To: zsh-workers
> It occurred to me that one way of avoiding a background job getting
> job control (disown is not a sufficient method in a function) is to
> unsetopt MONITOR, spawn the job, then setopt MONITOR again. This
> nearly works. Unfortunately,
>
> % unsetopt monitor
> % sleep 30 &
> % setopt monitor
> % jobs
> [1] + running
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.
I was thinking that this and `noalias' would both be good ideas.
I havn't looked at how to implement them yet.
rc
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Background jobs with no job control / disown bug?
1995-11-03 11:28 Background jobs with no job control / disown bug? Peter William Stephenson
1995-11-03 11:36 ` Richard Coleman
@ 1995-11-03 14:32 ` Chip Salzenberg
1 sibling, 0 replies; 5+ messages in thread
From: Chip Salzenberg @ 1995-11-03 14:32 UTC (permalink / raw)
To: Peter William Stephenson; +Cc: zsh-workers
According to Peter William Stephenson:
> It occurred to me that one way of avoiding a background job getting
> job control (disown is not a sufficient method in a function) is to
> unsetopt MONITOR, spawn the job, then setopt MONITOR again.
How about spawning it from a subshell?
% (sleep 30&)
% jobs
%
--
Chip Salzenberg, aka <chs@nando.net>
"Hey, it's the Miss Alternate Universe Pageant!"
-- Crow T. Robot, MST3K: "Stranded In Space"
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Background jobs with no job control / disown bug?
1995-11-03 11:36 ` Richard Coleman
@ 1995-11-03 15:05 ` Zoltan Hidvegi
1995-11-03 15:47 ` Zefram
0 siblings, 1 reply; 5+ messages in thread
From: Zoltan Hidvegi @ 1995-11-03 15:05 UTC (permalink / raw)
To: Richard Coleman
> 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 */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Background jobs with no job control / disown bug?
1995-11-03 15:05 ` Zoltan Hidvegi
@ 1995-11-03 15:47 ` Zefram
0 siblings, 0 replies; 5+ messages in thread
From: Zefram @ 1995-11-03 15:47 UTC (permalink / raw)
To: Z Shell workers mailing list
>> 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.
Indeed, that's a lot simpler than what I wrote. Making the Z_* flags
ORable was a good move.
I think this functionality should get into zsh at some point, but I'm
not sure which syntax would be better. I think nojob is a little
cleaner, but generally these prefixes indicate that the command will
actually be treated differently (cf. noglob, nocorrect). &! is similar
in effect to &, so the similarity in form is appropriate. But then
there's coproc... On the whole I think I favour the &! syntax, partly
on the assumption that someone will implement an option to support the
ksh coprocess syntax (|&). Then again, how will we do a disowned
coprocess? (|&! is rather ugly.)
There's one more issue I'd like to resolve concerning this
functionality, which I didn't get working in my patch the way I wanted
it. I think it actually adds the job to the job table and then deletes
it again, whereas it would be preferable to have the job never entered
into the table at all. I think my patch is OK w.r.t. keeping %+ and %-
the same, though.
-zefram
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~1995-11-03 16:12 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-11-03 11:28 Background jobs with no job control / disown bug? Peter William Stephenson
1995-11-03 11:36 ` Richard Coleman
1995-11-03 15:05 ` Zoltan Hidvegi
1995-11-03 15:47 ` Zefram
1995-11-03 14:32 ` Chip Salzenberg
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).