zsh-workers
 help / color / mirror / code / Atom feed
* Zsh 2.6-beta10 problem: builtin time/other builtin
@ 1995-09-16 13:07 jepler
  1995-09-18 14:45 ` P.Stephenson
  0 siblings, 1 reply; 2+ messages in thread
From: jepler @ 1995-09-16 13:07 UTC (permalink / raw)
  To: zsh-workers


Hello.

I have been having a problem (With zsh 2.6 betas 8 and 10 on a Linux
1.2 system, zsh 2.6 beta 10 on an IRIX 5.3 system, and zsh 2.6 beta 5
on a SunOS 4.1 system) with the use of builtin time with another builtin.

Actually there are two different problems. :)  However, type 2 doesn't
occur on the sunos, so it may be a bug in Linux even though I can't get a
similar bogus output with /usr/bin/time in any way I thought of trying.

0.  The sort of thing I expect
% time /bin/echo foo
foo
0.132s real  0.040s user  0.100s system  100% /bin/echo foo
% /usr/bin/time /bin/echo foo
foo
0.05user 0.07system 0:00.12elapsed 94%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (18major+73minor)pagefaults 0swaps
% time ( echo foo )
foo
( echo foo )  0.02s user 0.01s system 100% cpu 0.18 total

1.  Time of builtins -- All zsh 2.6 versions and platforms I have tested
% which time echo
time: shell reserved word
echo: shell built-in command
% time echo foo
foo

    The alert eye will notice that there is no output of 'time' for that
command.

2.  Time in subshells -- Only linux 1.2.9, but with betas 8 and 10, the
only versions I have tested
% which time
time: shell reserved word
% ( time /bin/echo foo )
foo
0.139s real  -11786.160s user  -1171.120s system  -9329435%

    The alert eye will notice that the user and system time taken by this
'echo' are less than trustworthy.  The 'real' time seems to be accurate,
however.

If a copy of config.status or the 'reporter' output is desired, especially
for the Linux machine, I'll be happy to supply.

Thanks for taking the time to read this, I hope builtin time will get
fixed in the future.  For now, I am just using a real time in preference
to the builtin one.

ObPraise: Thanks for writing something to save me from csh-style shells

Jeff
-- 
\/ Jeff Epler jepler@{herbie.unl.edu|cse.unl.edu|nyx.cs.du.edu}


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Zsh 2.6-beta10 problem: builtin time/other builtin
  1995-09-16 13:07 Zsh 2.6-beta10 problem: builtin time/other builtin jepler
@ 1995-09-18 14:45 ` P.Stephenson
  0 siblings, 0 replies; 2+ messages in thread
From: P.Stephenson @ 1995-09-18 14:45 UTC (permalink / raw)
  To: Zsh hackers list; +Cc: jepler

jepler@herbie.unl.edu wrote:
> 1.  Time of builtins -- All zsh 2.6 versions and platforms I have tested
> % which time echo
> time: shell reserved word
> echo: shell built-in command
> % time echo foo
> foo
> 
>     The alert eye will notice that there is no output of 'time' for that
> command.

This is a long-standing gripe which we really must fix sometime.


> 2.  Time in subshells -- Only linux 1.2.9, but with betas 8 and 10, the
> only versions I have tested
> % which time
> time: shell reserved word
> % ( time /bin/echo foo )
> foo
> 0.139s real  -11786.160s user  -1171.120s system  -9329435%
> 
>     The alert eye will notice that the user and system time taken by this
> 'echo' are less than trustworthy.  The 'real' time seems to be accurate,
> however.

There are actually two problems, both of which are fixed by the patch
(to 2.6-beta11-test4):

1) The obvious one.  This was very easy to fix:  the extra line in
entersubsh() resetting the totals for the time spent in the shell and
its children does this.  (Before, zsh was subtracting the total time
spent in children of the parent shell from the total time spent in
children of the subshell.)

2) I don't know if you'd noticed, but there's no text either (it
should say "/bin/echo foo" on the report line).  This is also a
problem when the MONITOR option is unset, in which case you never get
the name of the command being timed.  To fix this I restructured the
status flags that get passed around between execpline and execcmd so
that the latter now knows if the pipeline is being timed.  The easiest
way to allow this was to turn the Z_* flags determining the type of
pipeline into an or-able set in zsh.h.  Now execcmd() and entersubsh()
get the full pipeline type passed, not just the flag saying whether
they are in the background.  This makes the code a bit clearer and
more consistent, but does require more tests of the form 'how &
Z_ASYNC' instead of simply 'bkg': that's why the patch is so long.

*** Src/exec.c.job	Fri Sep 15 04:22:38 1995
--- Src/exec.c	Mon Sep 18 15:37:49 1995
***************
*** 588,597 ****
      initjob();
      jobtab[newjob].filelist = last_file_list;
      last_file_list = NULL;
!     if (how == Z_TIMED) {
  	jobtab[thisjob].stat |= STAT_TIMED;
- 	how = Z_SYNC;
-     }
      if (l->flags & PFLAG_COPROC) {
  	how = Z_ASYNC;
  	if (coprocin >= 0) {
--- 588,595 ----
      initjob();
      jobtab[newjob].filelist = last_file_list;
      last_file_list = NULL;
!     if (how & Z_TIMED)
  	jobtab[thisjob].stat |= STAT_TIMED;
      if (l->flags & PFLAG_COPROC) {
  	how = Z_ASYNC;
  	if (coprocin >= 0) {
***************
*** 612,618 ****
  	simple_pline = (l->left->type == END);
      execpline2(l->left, how, opipe[0], ipipe[1], last1);
      pline_level--;
!     if (how == Z_ASYNC) {
  	lastwj = newjob;
  	if (l->flags & PFLAG_COPROC)
  	    close(ipipe[1]);
--- 610,616 ----
  	simple_pline = (l->left->type == END);
      execpline2(l->left, how, opipe[0], ipipe[1], last1);
      pline_level--;
!     if (how & Z_ASYNC) {
  	lastwj = newjob;
  	if (l->flags & PFLAG_COPROC)
  	    close(ipipe[1]);
***************
*** 703,709 ****
  		    }
  		    else {
  			close(synch[0]);
! 			entersubsh(1, 0);
  			setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader);
  			close(synch[1]);
  			kill(getpid(), SIGSTOP);
--- 701,707 ----
  		    }
  		    else {
  			close(synch[0]);
! 			entersubsh(Z_ASYNC, 0);
  			setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader);
  			close(synch[1]);
  			kill(getpid(), SIGSTOP);
***************
*** 756,768 ****
      if (pline_level == 1)
  	strcpy(list_pipe_text, getjobtext((void *) pline->left));
      if (pline->type == END) {
! 	execcmd(pline->left, input, output, how == Z_ASYNC, last1);
  	pline->left = NULL;
      } else {
  	int old_list_pipe = list_pipe;
  
  	mpipe(pipes);
! 	if (pline->left->type >= CURSH && how == Z_SYNC) {
  	    int synch[2];
  
  	/* if we are doing "foo | bar" where foo is a current *
--- 754,766 ----
      if (pline_level == 1)
  	strcpy(list_pipe_text, getjobtext((void *) pline->left));
      if (pline->type == END) {
! 	execcmd(pline->left, input, output, how, last1);
  	pline->left = NULL;
      } else {
  	int old_list_pipe = list_pipe;
  
  	mpipe(pipes);
! 	if (pline->left->type >= CURSH && (how & Z_SYNC)) {
  	    int synch[2];
  
  	/* if we are doing "foo | bar" where foo is a current *
***************
*** 773,781 ****
  	    if (!(pid = fork())) {
  		close(pipes[0]);
  		close(synch[0]);
! 		entersubsh(how == Z_ASYNC, 1);
  		close(synch[1]);
! 		execcmd(pline->left, input, pipes[1], how == Z_ASYNC, 0);
  		_exit(lastval);
  	    } else if (pid == -1) {
  		close(synch[0]);
--- 771,779 ----
  	    if (!(pid = fork())) {
  		close(pipes[0]);
  		close(synch[0]);
! 		entersubsh(how, 1);
  		close(synch[1]);
! 		execcmd(pline->left, input, pipes[1], how, 0);
  		_exit(lastval);
  	    } else if (pid == -1) {
  		close(synch[0]);
***************
*** 792,798 ****
  	} else {
  	/* otherwise just do the pipeline normally. */
  	    subsh_close = pipes[0];
! 	    execcmd(pline->left, input, pipes[1], how == Z_ASYNC, 0);
  	}
  	pline->left = NULL;
  	close(pipes[1]);
--- 790,796 ----
  	} else {
  	/* otherwise just do the pipeline normally. */
  	    subsh_close = pipes[0];
! 	    execcmd(pline->left, input, pipes[1], how, 0);
  	}
  	pline->left = NULL;
  	close(pipes[1]);
***************
*** 1048,1054 ****
  
  /**/
  void
! execcmd(Cmd cmd, int input, int output, int bkg, int last1)
  {
      HashNode hn = NULL;
      Redir fn;
--- 1046,1052 ----
  
  /**/
  void
! execcmd(Cmd cmd, int input, int output, int how, int last1)
  {
      HashNode hn = NULL;
      Redir fn;
***************
*** 1100,1114 ****
      /* 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((bkg) ? "bg" : "fg"));
! 	bkg = 0;
      }
  
      /* If AUTORESUME is set, the command is SIMPLE, and doesn't have *
       * any redirections, then check if it matches as a prefix of a   *
       * job currently in the job table.  If it does, then we treat it *
       * as a command to resume this job.                              */
!     if (isset(AUTORESUME) && !bkg && empty(cmd->redir) && nonempty(args) &&
  	!input && type == SIMPLE && !nextnode(firstnode(args))) {
  	if (unset(NOTIFY))
  	    scanjobs();
--- 1098,1113 ----
      /* 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;
      }
  
      /* If AUTORESUME is set, the command is SIMPLE, and doesn't have *
       * any redirections, then check if it matches as a prefix of a   *
       * job currently in the job table.  If it does, then we treat it *
       * as a command to resume this job.                              */
!     if (isset(AUTORESUME) && (how & Z_SYNC) &&
! 	empty(cmd->redir) && nonempty(args) &&
  	!input && type == SIMPLE && !nextnode(firstnode(args))) {
  	if (unset(NOTIFY))
  	    scanjobs();
***************
*** 1117,1123 ****
      }
  
      /* Get the text associated with this command. */
!     if (jobbing)
  	text = getjobtext((void *) cmd);
      else
  	text = NULL;
--- 1116,1122 ----
      }
  
      /* Get the text associated with this command. */
!     if (jobbing || (how & Z_TIMED))
  	text = getjobtext((void *) cmd);
      else
  	text = NULL;
***************
*** 1234,1246 ****
       * going into the background, or if we need to trap EXIT or    *
       * ZERR, fork.                                                 */
  
!     if (bkg || !(is_cursh || (cmd->flags & CFLAG_EXEC)) ||
  	((is_builtin | is_shfunc) && output)) {
  	int synch[2];
  
  	child_block();
  	pipe(synch);
! 	pid = (last1 && !bkg && !sigtrapped[SIGZERR]
  	       && !sigtrapped[SIGEXIT] && execok()) ? 0 : phork();
  	if (pid == -1) {
  	    close(synch[0]);
--- 1233,1245 ----
       * going into the background, or if we need to trap EXIT or    *
       * ZERR, fork.                                                 */
  
!     if ((how & Z_ASYNC) || !(is_cursh || (cmd->flags & CFLAG_EXEC)) ||
  	((is_builtin | is_shfunc) && output)) {
  	int synch[2];
  
  	child_block();
  	pipe(synch);
! 	pid = (last1 && (how & Z_SYNC) && !sigtrapped[SIGZERR]
  	       && !sigtrapped[SIGEXIT] && execok()) ? 0 : phork();
  	if (pid == -1) {
  	    close(synch[0]);
***************
*** 1254,1260 ****
  	    if (pid == -1)
  		zerr("%e", NULL, errno);
  	    else {
! 		if (bkg)
  		    lastpid = pid;
  		else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars))
  		    while (nonempty(cmd->vars))	/* search for STTY=... */
--- 1253,1259 ----
  	    if (pid == -1)
  		zerr("%e", NULL, errno);
  	    else {
! 		if (how & Z_ASYNC)
  		    lastpid = pid;
  		else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars))
  		    while (nonempty(cmd->vars))	/* search for STTY=... */
***************
*** 1267,1287 ****
  	    return;
  	}
  	close(synch[0]);
! 	entersubsh(bkg, 1);
  	close(synch[1]);
  	forked = 1;
  
  	if (sigtrapped[SIGINT] == 2)
  	    holdintr();
      } else if ((cmd->flags & CFLAG_EXEC) && !nullexec) {
! 	entersubsh(bkg, 1);
      } else {
      /* Job is running in current shell. */
  	jobtab[thisjob].stat |= STAT_CURSH;
      }
  
      /* background jobs run at lower priority if BGNICE is set */
!     if (bkg && isset(BGNICE))
  	nice(5);
  
      /* Perform postfork substitutions */
--- 1266,1286 ----
  	    return;
  	}
  	close(synch[0]);
! 	entersubsh(how, 1);
  	close(synch[1]);
  	forked = 1;
  
  	if (sigtrapped[SIGINT] == 2)
  	    holdintr();
      } else if ((cmd->flags & CFLAG_EXEC) && !nullexec) {
! 	entersubsh(how, 1);
      } else {
      /* Job is running in current shell. */
  	jobtab[thisjob].stat |= STAT_CURSH;
      }
  
      /* background jobs run at lower priority if BGNICE is set */
!     if ((how & Z_ASYNC) && isset(BGNICE))
  	nice(5);
  
      /* Perform postfork substitutions */
***************
*** 1586,1597 ****
  
  /**/
  void
! entersubsh(int bkg, int cl)
  {
      if (sigtrapped[SIGEXIT])
  	unsettrap(SIGEXIT);
      if (!jobbing) {
! 	if (bkg) {
  	    sigtrapped[SIGINT] = 2;
  	    signal_ignore(SIGINT);
  	    sigtrapped[SIGQUIT] = 2;
--- 1585,1596 ----
  
  /**/
  void
! entersubsh(int how, int cl)
  {
      if (sigtrapped[SIGEXIT])
  	unsettrap(SIGEXIT);
      if (!jobbing) {
! 	if (how & Z_ASYNC) {
  	    sigtrapped[SIGINT] = 2;
  	    signal_ignore(SIGINT);
  	    sigtrapped[SIGQUIT] = 2;
***************
*** 1612,1618 ****
  		    jobtab[thisjob].gleader = mypgrp;
  		setpgrp(0L, mypgrp);
  
! 		if (!bkg)
  		    attachtty(jobtab[thisjob].gleader);
  	    }
  	}
--- 1611,1617 ----
  		    jobtab[thisjob].gleader = mypgrp;
  		setpgrp(0L, mypgrp);
  
! 		if (how & Z_SYNC)
  		    attachtty(jobtab[thisjob].gleader);
  	    }
  	}
***************
*** 1622,1628 ****
  		!jobtab[list_pipe_job].gleader)
  		jobtab[list_pipe_job].gleader = jobtab[thisjob].gleader;
  	    setpgrp(0L, jobtab[thisjob].gleader);
! 	    if (!bkg)
  		attachtty(jobtab[thisjob].gleader);
  	} else
  	    setpgrp(0L, jobtab[thisjob].gleader);
--- 1621,1627 ----
  		!jobtab[list_pipe_job].gleader)
  		jobtab[list_pipe_job].gleader = jobtab[thisjob].gleader;
  	    setpgrp(0L, jobtab[thisjob].gleader);
! 	    if (how & Z_SYNC)
  		attachtty(jobtab[thisjob].gleader);
  	} else
  	    setpgrp(0L, jobtab[thisjob].gleader);
***************
*** 1649,1654 ****
--- 1648,1654 ----
      opts[USEZLE] = OPT_UNSET;
      if (cl)
  	clearjobtab();
+     times(&shtms);
  }
  
  /* close all internal shell fds */
***************
*** 1883,1889 ****
      subsh = 1;
      close(pipes[0]);
      redup(pipes[1], 1);
!     entersubsh(0, 1);
      signal_ignore(SIGTSTP);
      execlist(list, 1);
      close(1);
--- 1883,1889 ----
      subsh = 1;
      close(pipes[0]);
      redup(pipes[1], 1);
!     entersubsh(Z_SYNC, 1);
      signal_ignore(SIGTSTP);
      execlist(list, 1);
      close(1);
***************
*** 1981,1987 ****
      }
      subsh = 1;
      close(1);
!     entersubsh(0, 1);
      signal_ignore(SIGTSTP);
      (void)creat(nam, 0600);
      execlist(list, 1);
--- 1981,1987 ----
      }
      subsh = 1;
      close(1);
!     entersubsh(Z_SYNC, 1);
      signal_ignore(SIGTSTP);
      (void)creat(nam, 0600);
      execlist(list, 1);
***************
*** 2047,2053 ****
  	popheap();
  	return pnam;
      }
!     entersubsh(1, 1);
      closem();
      fd = open(pnam, O_WRONLY);
      if (fd == -1) {
--- 2047,2053 ----
  	popheap();
  	return pnam;
      }
!     entersubsh(Z_ASYNC, 1);
      closem();
      fd = open(pnam, O_WRONLY);
      if (fd == -1) {
***************
*** 2099,2105 ****
  	popheap();
  	return pnam;
      }
!     entersubsh(1, 1);
      closem();
      fd = open(pnam, O_RDONLY);
      redup(fd, 0);
--- 2099,2105 ----
  	popheap();
  	return pnam;
      }
!     entersubsh(Z_ASYNC, 1);
      closem();
      fd = open(pnam, O_RDONLY);
      redup(fd, 0);
***************
*** 2133,2139 ****
      }
      close(pipes[0]);
      closem();
!     entersubsh(1, 1);
      redup(pipes[1], 1);
      execlist(list, 1);
      _exit(lastval);
--- 2133,2139 ----
      }
      close(pipes[0]);
      closem();
!     entersubsh(Z_ASYNC, 1);
      redup(pipes[1], 1);
      execlist(list, 1);
      _exit(lastval);
***************
*** 2164,2170 ****
  	return pipes[1];
      }
      close(pipes[1]);
!     entersubsh(1, 1);
      redup(pipes[0], 0);
      closem();
      execlist(list, 1);
--- 2164,2170 ----
  	return pipes[1];
      }
      close(pipes[1]);
!     entersubsh(Z_ASYNC, 1);
      redup(pipes[0], 0);
      closem();
      execlist(list, 1);
***************
*** 2240,2246 ****
  	shelltime();
  	return 0;
      }
!     execpline(cmd->u.pline, Z_TIMED, 0);
      thisjob = jb;
      return lastval;
  }
--- 2240,2246 ----
  	shelltime();
  	return 0;
      }
!     execpline(cmd->u.pline, Z_TIMED|Z_SYNC, 0);
      thisjob = jb;
      return lastval;
  }
*** Src/text.c.job	Fri Sep 15 04:23:07 1995
--- Src/text.c	Mon Sep 18 14:21:05 1995
***************
*** 164,177 ****
      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)
  		taddnl();
  	    else
! 		taddstr((_List(n)->type == Z_ASYNC) ? " " : "; ");
  	    gt2(_List(n)->right);
  	}
  	break;
--- 164,177 ----
      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)
  		taddnl();
  	    else
! 		taddstr((_List(n)->type & Z_ASYNC) ? " " : "; ");
  	    gt2(_List(n)->right);
  	}
  	break;
*** Src/utils.c.job	Fri Sep 15 04:23:08 1995
--- Src/utils.c	Mon Sep 18 14:20:41 1995
***************
*** 1631,1637 ****
  	    List l = (List) n;
  
  	    l->left = (Sublist) simplifystruct((struct node *)l->left);
! 	    if (l->type == Z_SYNC && !l->right)
  		return (struct node *)l->left;
  	}
  	break;
--- 1631,1637 ----
  	    List l = (List) n;
  
  	    l->left = (Sublist) simplifystruct((struct node *)l->left);
! 	    if ((l->type & Z_SYNC) && !l->right)
  		return (struct node *)l->left;
  	}
  	break;
*** Src/zsh.h.job	Mon Sep 18 14:17:52 1995
--- Src/zsh.h	Mon Sep 18 14:17:32 1995
***************
*** 326,334 ****
      List right;
  };
  
! #define Z_SYNC  0		/* ; */
! #define Z_ASYNC 1		/* & */
! #define Z_TIMED 2
  
  /* tree element for sublists */
  
--- 326,334 ----
      List right;
  };
  
! #define Z_SYNC  1		/* ; */
! #define Z_ASYNC 2		/* & */
! #define Z_TIMED 4
  
  /* tree element for sublists */
  

-- 
Peter Stephenson <P.Stephenson@swansea.ac.uk>  Tel: +44 1792 205678 extn. 4461
WWW:  http://python.swan.ac.uk/~pypeters/      Fax: +44 1792 295324
Department of Physics, University of Wales, Swansea,
Singleton Park, Swansea, SA2 8PP, U.K.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1995-09-18 14:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-09-16 13:07 Zsh 2.6-beta10 problem: builtin time/other builtin jepler
1995-09-18 14:45 ` P.Stephenson

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).