zsh-workers
 help / color / mirror / code / Atom feed
* 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).