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