cak@Purdue.ARPA (01/12/84)
From: Christopher A Kent <cak@Purdue.ARPA> I think it's wonderful from a purely pragmatic standpoint. I probably won't write any new code that uses it (I'm a true believer), but we have so much old code that uses it that things have been a real pain around here trying to convert it all and leave it portable (one program system in particular, which we distribute, needs to be able to run on 4.1 and 4.2 and has to do timeouts of reads). By leaving the default behaviour as restartable system calls, "new" programmers will be encouraged to use that model, especially if they have only read as much as they need to know and haven't seen the manual page for sigrestartable yet. I think it's a win all around. Cheers, chris ----------
mike%rice@sri-unix.UUCP (01/12/84)
From: Mike Caplinger <mike@rice> [This message has a possibly worthwhile suggestion at the bottom. Readers interested in skipping the rest can feel free to do so. - Mike Caplinger] First, as I understand them 4.2 restarting is exactly like 4.1 restarting after a new signal feature has been used. This is already a compatibility problem. Most 4.1 programs I've written have used the new interface. I'm really scared of making any changes to 4.2 that don't make it into ALL the distribution tapes that are going to be sent out. I like Mike's solution, but do you really think it's worthwhile trying to do such things in the name of portability? I believe the following things: 1) There will be many 4.2 programs that will never run under Sys V. 2) There will be many Sys V programs that will never run under 4.2. 3) Most educational sites will never run Sys V on VAXen. We would only run Sys V on any machine if we were stuck with it. Experience with the millions of local hacks that ran around under v7, and trying to cope with /usr/group and Usenix software that used them, has made me very wary of local hacks. I suspect there will always be purists who refuse to implement local hacks; I even think I'm one of them. I wonder if, now that rumors say Berkeley isn't really doing development work, we might get people there to listen to improvements like yours. How about Ultrix? Will DEC listen? Also, it has always bothered me that the terminal driver in 4.1 made it necessary to do as many as 4 ioctls in order to do logically-connected things. That was a compatibility move too... Of course, this change doesn't using the new semantics clumsy. I guess what I would like is for the change to be added, but controlled by the COMPAT #ifdef. Good luck lobbying for it! - Mike ps. If signal() was kept as a COMPAT system call, and a front-end was written to go in a special library (liboldsig?) then use of that system call (as opposed to the signal(3) library call) could detect whether new or old behavior was wanted, obviating the sigrestartable syscall, just as 4.1 detected the use of a new feature and set SOUSIG accordingly. I think...
gwyn%brl-vld@sri-unix.UUCP (01/12/84)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> I think perhaps you are attempting to bundle too many things together that should be orthogonally selectable. I would much prefer that the state of the u_eosys flag bit RESTARTSYS be available to the signal handler and that there be a way to turn off this bit before resuming after the signal handler. As with your proposal, any program not using this added feature would obtain the distributed 4.2BSD behavior. This addition would permit the machine dependencies to be removed from the signal(2) emulation that I previously posted, so that "old style" UNIX signal behavior would be available simply by using the signal() library routine, with no extra BSD-specific kludge calls needed in user source code.
guy@rlgvax.UUCP (Guy Harris) (01/14/84)
First, as I understand them 4.2 restarting is exactly like 4.1 restarting after a new signal feature has been used. This is already a compatibility problem. Most 4.1 programs I've written have used the new interface. I believe this is correct; the "vnews" we ran on 4.1 used the new signal mechanism so that it could be suspended, and it turned out that typing one's interrupt character didn't work like it was supposed to because the read didn't get EINTR, so I had to stick in a (surprise, surprise) "setjmp"/ "longjmp" pair. Also, it has always bothered me that the terminal driver in 4.1 made it necessary to do as many as 4 ioctls in order to do logically-connected things. That was a compatibility move too... Of course, this change doesn't using the new semantics clumsy. This was actually somewhat inherited from V7; the System III/System V handler cleans this up, although if 4.3BSD or whatever picked up the USG tty driver and then re-Berkeleyized it they might have to introduce a second "ioctl" to turn on the local flags and supply the local control characters, which would bring us back to where we started from... ps. If signal() was kept as a COMPAT system call, and a front-end was written to go in a special library (liboldsig?) then use of that system call (as opposed to the signal(3) library call) could detect whether new or old behavior was wanted, obviating the sigrestartable syscall, just as 4.1 detected the use of a new feature and set SOUSIG accordingly. I think... "signal()" is already kept around in 4.2 as part of the 4.1 binary compatibility feature, and if you issue the "old signal" system call it does, indeed, set SOUSIG (in fact, that's the *only* place SOUSIG gets set), so your suggestion has already been implemented in vanilla 4.2BSD if you define COMPAT when you build your system. Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy
tjt@kobold.UUCP (01/15/84)
Actually, this is a follow-on to: Also, it has always bothered me that the terminal driver in 4.1 made it necessary to do as many as 4 ioctls in order to do logically-connected things. That was a compatibility move too... Of course, this change doesn't using the new semantics clumsy. This was actually somewhat inherited from V7; the System III/System V handler cleans this up, although if 4.3BSD or whatever picked up the USG tty driver and then re-Berkeleyized it they might have to introduce a second "ioctl" to turn on the local flags and supply the local control characters, which would bring us back to where we started from... If you "re-Berkeleyize" the USG tty driver, any additional ioctl should work in the spirit of the USG ioctl's, and let you set *all* the flag words/special characters with a single ioctl. I thought part of the reason for all them ioctl's in the 4BSD tty driver (actually from IIASA) was leftover from V6 days when the stty/gtty entry point was passed *exactly* three int's (or six char's) from user space, and this was carried over as a superstition. -- Tom Teixeira, Massachusetts Computer Corporation. Westford MA ...!{ihnp4,harpo,decvax}!masscomp!tjt (617) 692-6200 x275
mike%brl-vgr@sri-unix.UUCP (01/18/84)
From: Mike Muuss <mike@brl-vgr> REFRESHER. On 4.1 and earlier UNIX systems, signal handlers had several attributes: *) After a signal was caught, the handler was reset to SIG_DFL. *) If the process was executing a (kernel) sleep() at "low" priority, and a signal was processed, the system call would abort, returning an error code (-1), with errno = u.u_error = EINTR (interupted system call). On 4.2 BSD UNIX, these two aspects of signal handling were altered (along with some other, nice improvements, which are not germane). 1) The signal handler remains "installed" until explicitly changed. 2) System calls which may (kernel) sleep() at "low" priority will be silently restarted after processing an incomming signal. The signal handler will have no idea if this is happening or not. PROBLEM. Clearly, programs written for the old style signal interface will have a fair amount of difficulty coping with difference #2 above, if they depend on signals (especially timer signals) interrupting a system call. Network software which wishes to run timouts around network reads will have to longjmp() in the signal handler, rather than being able to depend on just returning, with an EINTR to be returned from the read/write sys-call that timed out. Editors and shells will have to expect their I/O to be restarted after SIGINT, etc. (You would not believe the crud that Berkeley had to do to /bin/sh to make it still capable of re-printing $PS1 after a SIGINT (^C, etc).). Certainly, change #1 is "mostly harmless"; the number of programs which will break is minimal -- the timing windows which this change fixes were something that no mortal programmer would dare depend on. However, change #2 is truely problematic: Certainly, there are advantages to the new style signal interface, and programs which are written with this style of operation in mind should work out well. However, no matter how hard we try, few of us will be able to afford the luxury of running 4.2 BSD on *all* our machines. Those of you planning on purchasing a Cray-2 (as we are), will have to contend with System-V UNIX (at least to start with). Many other vendors will be non-4.2 BSD, and it is too late to stomp them all out (pitty, no?). And somehow, those venerable old PDP-11s just keep on refusing to quit! THEREFORE, the problem of program portability rears it's ugly head. 4.2 people (true believers) will, of course, deisre to import quality software from elsewhere ("expensive, yes, extravagant, no"), without having to re-write all the signal code. Others may wish to be able to use 4.2 code on their own system ("rotsa-ruck"). Being in the former camp, I would like to offer the following solution: PROPOSED SOLUTION. In proc.h, SOUSIG (1 bit in p_flag) is defined to mean "this process is using the old signal mechanism". This piece of information is used in two ways: 1) To determine resetting of default signal handling after traps (in sys/kern_sig.c and sys/kern_xxx.c). 2) To determine restartability of interrupted ("slow") system calls (in kern_exit.c, sys_generic.c, sys_inode.c). By adding another bit to the p_flag word called SDFLSIG and assigning it function #1 (above) to this new bit, and then redefining the meaning of SOUSIG to JUST function #2 (above), +and+ by adding a new sys-call (#151, sigrestartable()) which permits the user to manipulate the state of the SOUSIG bit, then a solution can be achieved. For programs which do not use the new sys-call, standard 4.2 functionality occurs. Programs which wish to avoid having their sys-calls restarted may say: sigrestartable( 0 ); and get the 4.2 interface, with continuously installed signal handlers, but with sys-calls returning the old familiar EINTR. Calling sigrestartable() with a non-zero argument restores the 4.2 BSD style restartable sys-calls, so that one can "live in both worlds" by switching back and forth. The sys-call is as fast as getpid(), so pairs could reasonably be used around old-fashioned code if one desires to "blend" signaling style within a single program. STATUS. This evening, I installed the change I proposed above, into 2 of our 780s. Effort to change: h/proc.h 2 lines sys/init_sysent.c: 1 line sys/syscalls.c: 1 line sys/kern_sig.c 14 lines sys/kern_exec.c 1 line sys/kern_fork.c 1 line sys/kern_xxx.c 1 line To the best of my ability to test it, this new system call operates exactly as I have described above. QUESTION. What does the UNIX-community-at-large think of this strategy? If people feel that this is a reasonable solution to the 4.2 signal "problem", DPK and I will arrange to reproduce many copies of a 1-page document describing how to install this code into your 4.2 kernel, and distribute them at UNIFORvM in Washington DC next week. On the other hand, if a better proposal can be brought forth, I am willing to withdraw this proposal and implement something else, assuming that it offers a solution of similar generality, elegance, and simplicity (pardon the self-admiration). CREDIT. The motivation for addressing this problem at this time came from a program which Doug Kingston has been working on. His struggles, his requests, and his constructive feedback were instrumental in shaping the form of this solution. Together we evaluated 7 or 8 different solutions to this problem, before the present solution was arrived at. COMMENTS. Please mail your responses to this issue back to the full list. This issue is too important to discuss privately. Best, -Mike Muuss SOURCE CODE. Just in case you desire to try this change yourself, here is the code: h/proc.h (2 changes): change comment to: #define SOUSIG 0x0100000 /* old signal semantics: no restart (BRL) */ add at the bottom: #define SDFLSIG 0x2000000 /* reset signals to default handling (BRL) */ sys/init_sysent.c (2 lines from the bottom): 1, sigrestartable, /* 151 = sigrestartable (BRL) */ sys/syscalls.c (1 line from the bottom): "sigrestartable", /* 151 = sigrestartable */ sys/kern_xxx.c (3 lines from the bottom): from: p->p_flag |= SOUSIG; to: p->p_flag |= SOUSIG|SDFLSIG; sys/kern_exec.c (80% into the file): from: u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SOUSIG); to: u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SOUSIG|SDFLSIG); sys/kern_fork.c (50% into the file): from: rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SOUSIG)); to: rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SOUSIG|SDFLSIG)); sys/kern_sig.c (in psig(), 85% into the file): from: if (p->p_flag & SOUSIG) { to: if (p->p_flag & SDFLSIG) { and, after #define cantmask (mask(SIGKILL)|mask(SIGCONT)|mask(SIGSTOP)) near the front of the file, add this routine: sigrestartable() /* BRL-specific */ { register struct a { int restartable; } *uap = (struct a *)u.u_ap; /* BRL syscall to permit non-restartable signal behavior */ if( uap->restartable ) u.u_procp->p_flag &= ~SOUSIG; /* Restartable */ else u.u_procp->p_flag |= SOUSIG; /* Non-restartable */ } HAPPY HACKING!
guy@rlgvax.UUCP (Guy Harris) (01/22/84)
> If you "re-Berkeleyize" the USG tty driver, any additional ioctl should > work in the spirit of the USG ioctl's, and let you set *all* the flag > words/special characters with a single ioctl. I thought part of the > reason for all them ioctl's in the 4BSD tty driver (actually from > IIASA) was leftover from V6 days when the stty/gtty entry point was > passed *exactly* three int's (or six char's) from user space, and this > was carried over as a superstition. The multiple "ioctl"s to set the terminal modes in 4BSD comes from V7, where they also had multiple "ioctl"s. I suspect the reason was that the V7 driver was done, it was done by adding stuff to the V6 driver which did have to use only what the "stty/gtty" routines could handle, so instead of redoing the "ioctl" interface entirely they added new "ioctl"s, and Berkeley continued the tradition for compatibility (i.e., "stty/gtty" and the old "ioctl"s still worked). The people who did the 3.0 driver probably decided that, instead of taking the V6-like 2.0 driver and adding all the V7 "ioctl"s, they'd redo the whole thing right. In 4.1cBSD there was sort of a half-assed attempt at redoing the "ioctl"s - they added an "ioctl" to set the "sg_flags" and local flags words as one "long", and an "ioctl" to set all the special characters, but one still had to use the old "ioctl" to get/set the speeds - but that was backed out in 4.2BSD. My only concerns about extending TCGETA/TCSETA to include more special characters and flag bits would be: 1) Adding the flag bits to existing words might conflict with future extensions from Bell; adding a new word would be safe but slightly ugly (for instance, the "echo control characters as ^x" bit belongs in c_lflag but Bell may eventually use all 16 bits of that "short"). 2) Programs which do a TCSETA without first doing a TCGETA on the standard input/output/error deserve to break (the *only* right way to set the modes on a port whose modes have already been initialized is to read the current modes, change the "termio" structure, and set the modes), but some programs which do the first open on a line and set the modes directly (communication programs, for instance) might break because they set the new mode bits and control characters to zero without realizing that this may have an undesired effect. By and large, setting the bits to zero would be harmless, as leaving those bits off leaves the driver behaving like the standard USG tty driver, but setting the control characters to zero doesn't disable them. The latter is actually a misfeature of the driver to some degree; for example, "getty" under System III sets your "break" or "eol" character (V7 calls it the "break" character and USG UNIX calls it the "eol" character) to NUL (zero) rather than '\377'. The latter was guaranteed to disable the control character in V7, as the character was masked down to 7 bits before it was compared against the special characters, but may not do so in USG UNIX as the stripping of the eighth bit is an option which can be set independently of most other options (this is useful, for instance, if you have a terminal with a META key which turns the eighth bit on; you can use the META key without all the disadvantages, like disabling XON/XOFF, of the V7 "raw" mode). The UNIX 2.0 backward compatibility "ioctl" TIOCSETP (which several people may have made backward compatible with V7 instead) sets the EOL (and the S5 EOL2) characters to 0, also. I would vote for changing the USG driver to consider NUL not to ever be the erase, kill, interrupt, quit, EOF, EOL, EOL2, etc. character, so that setting that character in the "termio" structure to NUL would be the official way to disable them. This would mean that most (if not all) programs which initialized a terminal port would not enable those characters if what the program did was fill in a structure and do a TCSETA without first doing a TCGETA. Under these circumstances, changing the shape of "struct termio" would only break binary images of programs, and if that was really a problem TCSETA, etc. could be given different "ioctl" numbers and the old ones could be left around for backwards compatibility. Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy