[comp.unix.wizards] Bug

hitz@mips.COM (David Hitz) (01/29/88)

I've found a bug in the BSD4.3 setitimer() system call, and I thought
I'd run it by the wizards.

Problem is, both the virtual timer and the profiling timer propagate
across fork system calls, but the real timer does not.  This is true on
both a VAX and a MIPS box.  (I've included a simple test case at the
end of this message.)

I looked at the code to see if this looked accidental or on purpose,
Since the real timer needs to be implemented differently from the other
two, the results were ambiguous.  

Real timer info must always be present so it goes into proc instead of
user, and it would be too inefficient to trigger it with an explicit
check in hardclock() as with the other two, so it's done with timeout()
instead.

But in newproc() kern_fork.c:

	timerclear(&rpp->p_realtimer.it_value);

This looks on purpose, but it may have been an incorrect fix added to
make getitimer() reflect that fact that the real timer wasn't getting
propogated.  Coping the values from the parent isn't enough to restart
the real timer, you also have to put:

	timeout(realitexpire, (caddr_t)p, hzto(&aitv.it_value));

somewhere in newproc().

So can I fix this?  It isn't documented in fork(), and I can't think of
any good reason for the real timer to be special.  On the other hand,
who knows what code will die when it suddenly has to deal with an extra
signal.

Yo?
------- Short test case --------------------------------------------------------
/*
 *  Prints messages on receipt of each of the three timer signals,
 *  both from parent and child.  (Parent on left, child on right.)
 */

#include <sys/param.h>
#include <sys/signal.h>
#include <sys/time.h>

int child, sigalrm(), sigvtalrm(), sigprof();

main()
{
	struct itimerval it;

	it.it_interval.tv_sec = 0;
	it.it_interval.tv_usec = 500000;
	it.it_value.tv_sec = 0;
	it.it_value.tv_usec = 1;

	signal(SIGALRM, sigalrm); 
	signal(SIGVTALRM, sigvtalrm);
	signal(SIGPROF, sigprof);

	setitimer(0, &it, 0); 
	setitimer(1, &it, 0);
	setitimer(2, &it, 0);

	child = fork();
	if (child == -1) {
		perror("fork");
		exit(1);
	}
	child = !child;		/* True if child */

	while (1);
}

sigalrm() {
	static int alrm;
	printf("\t%sR%d\n", child?"\t\t\t\t\t":"", alrm);
	++alrm;
}

sigprof() {
	static int prof;
	printf("\t\t%sP%d\n", child?"\t\t\t\t\t":"", prof);
	++prof;
}

sigvtalrm() {
	static int vtalrm;
	printf("\t\t\t%sV%d\n", child?"\t\t\t\t\t":"", vtalrm);
	++vtalrm;
}
--------------------------------------------------------------------------------
-- 
Dave Hitz
UUCP: {decvax,ucbvax,ihnp4}!decwrl!mips!hitz 	DDD: hitz@408-991-0345

guy@gorodish.Sun.COM (Guy Harris) (01/30/88)

> This looks on purpose, but it may have been an incorrect fix added to
> make getitimer() reflect that fact that the real timer wasn't getting
> propogated.

No.  I strongly suspect it was done on purpose.

A set of V7 source around here indicates that the "alarm()" timer was, in fact,
cleared on a "fork()"; this source is not from the original AT&T tape, though,
so I don't know that it was cleared in vanilla V7.

It is *definitely* done this way in S5; from the "fork" manual page for S5R3:

	The child process differs from the parent process in the following
	ways:

	     The child process's "utime", "stime", "cutime", and "cstime"
	     are set to 0.  The time left until an alarm clock signal is
	     reset to 0.

(The S5R2 manual page claims that the alarm clock value is inherited.  The S5R2
*code* claims that it isn't: "newproc" in "slp.c" clears "p_clktim" for the
child process.  The same is true for S5R1, or whatever the S5 release before
S5R2 is supposed to be called; the documentation claims that it is inherited,
but the implementation clears it.)

Furthermore, POSIX draft 12 also indicates that "Pending alarms are cleared for
the child process."

It's not a bug; don't change it.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

simmons@applga.uucp (Steve Simmons) (06/10/88)

Consider the following two scripts:

       OK                        Buggy
   #!/bin/csh           | #!/bin/csh
   if ( 1 ) then        | if ( 0 ) then
   cat << HERE          | cat << HERE
   else                 | else
   HERE                 | HERE
   else                 | else
   echo There           | echo There
   endif                | endif

Executing OK is fine -- it echos 'else'.  Executing Buggy gives an error
	HERE: Command not found.
It appears that in Buggy it is disregarding the here document *even though
it is syntactically correct*.

The Bourne and Korn shell equivalents to this script work fine, ie, buggy.sh
echos 'There'.  Bug in the C shell?  Or a wierdness of syntax that I can
use to convince people Korn is better?  :-)

-- 
+- Steve Simmons            UNIX Systems Mgr.         Schlumberger CAD/CAM -+
+  simmons@applga.uucp                              ...umix!applga!simmons  +
+- "Opinions expressed are all my own, etc, etc, etc, etc, etc, etc, etc." -+

ugfailau@sunybcs.UUCP (Fai Lau) (06/15/88)

In article <172@applga.UUCP> simmons@applga.uucp (Steve Simmons) writes:
>Consider the following two scripts:
>
>       OK                        Buggy
>   #!/bin/csh           | #!/bin/csh
>   if ( 1 ) then        | if ( 0 ) then
>   cat << HERE          | cat << HERE
>   else                 | else
>   HERE                 | HERE
>   else                 | else
>   echo There           | echo There
>   endif                | endif
>Executing OK is fine -- it echos 'else'.  Executing Buggy gives an error
>	HERE: Command not found.
  ....
>The Bourne and Korn shell equivalents to this script work fine, ie, buggy.sh
>echos 'There'.  Bug in the C shell?  Or a wierdness of syntax that I can
>use to convince people Korn is better?  :-)

Try

#!/bin/csh
if (0) then
cat << HETE; else; HERE
else
echo There
endif

	I don't particularly like writing shell script for C shell for the
very reason that I can never tell what kind of "weirdness" would
pop up where I least expected it.

	Oh, BTW, in my personal opinion, I would say that the Korn shell is
"somewhat" better than the C shell. 

Fai Lau
SUNY at Buffalo (The Arctic Wonderland)
UU: ..{rutgers,ames}!sunybcs!ugfailau
BI: ugfailau@sunybcs INT: ugfailau@joey.cs.buffalo.EDU