Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!cbatt!cblpf!cbstr1!Karl.Kleinpaste From: Karl.Kleinpaste@cbstr1.UUCP Newsgroups: comp.unix.wizards Subject: Re: System V job control idea Message-ID: <229@cbstr1.att.com> Date: Wed, 13-May-87 09:58:53 EDT Article-I.D.: cbstr1.229 Posted: Wed May 13 09:58:53 1987 Date-Received: Sat, 16-May-87 04:57:27 EDT References: <337@tdi2.UUCP> <757@mcgill-vision.UUCP> <165@elan.UUCP> Sender: karl@cbstr1.att.com Lines: 50 Summary: I've done it, it works fine, but with limitations. In-reply-to: jlo@elan.UUCP's message of 12 May 87 17:34:28 GMT Posting-Front-End: GNU Emacs 18.41.1 of Mon Mar 30 1987 on cbstr1 (usg-unix-v) I really wish the original article had gotten here; I haven't any record of it at all in my history file. I implemented this job control emulation scheme in a SysV-compatible version of csh. It's been running on my dept's machines for over 2 years now. It is far from perfect; as has been mentioned, lack of SIGTTIN/OUT makes life difficult for fg/bg jobs competing for terminal input. I have not attempted to resolve that (and breakpointing every read(2) is not a thought which thrills me, sorry). However, for most general issues, it works quite well. Some other limitations which I have found include: Lots of programs don't cope with EINTR returns from system calls (especially read(2) and wait(2)) well. Cat(1) is the most obvious example - it just rolls over dead if it ever gets a non-positive result from read(2). If I have cat(1) reading from stdin, and I stop it using SIGQUIT as an emulated SIGTSTP on ^Z, it stops fine, but then on restart it just dies. Also, the entire job control concept in this implementation fails for processes which fork subprocesses. The shell can only control its immediate children. If those children create grandchildren, they are susceptible to SIGQUIT core dumps just as any ordinary process might be. This makes the use of make(1) difficult; I turn job control emulation off when using make(1). (Make(1) is also a program which doesn't cope with EINTR returns from wait(2) - "bad wait status.") Lastly, SIGCLD is not generated properly. There is a simple modification which I have made to our VAXen kernels to correct this (I consider it a bona fide bug), but the problem is that the stop() routine in os/ptrace.c doesn't actually issue a signal; rather, it just wakes up the parent, in the apparent hope that the parent is already doing something wake-able (presumably wait(2)) and will notice. I changed it to a psignal(pp, SIGCLD) call, which is The Right Way. The question of fraud-defense on setuid programs is very easy to conquer, though: When exec'ing the program, the last thing done before exec is to check for setuid-ness. If the setuid/setgid bits are on, no ptrace(2) call is made to "turn on job control" for the process, and then the process behaves just like any other setuid program, and is not stoppable. Su(1) and uucico(1) run just fine and don't lose their setuid attributes. The best part is that, when using GNU Emacs, when I hit ^Z, it doesn't just fork a subshell like GNU Emacs is supposed to under SysV - for me it actually stops. I like that an awful lot. (That's what the USG_JOBCTRL #ifdef in sysdep.c is for.) Karl