Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10 5/3/83; site cbosgd.UUCP Path: utzoo!linus!decvax!harpo!floyd!clyde!ihnp4!cbosgd!mark From: mark@cbosgd.UUCP (Mark Horton) Newsgroups: net.bugs.4bsd,net.unix-wizards Subject: signal handling in 4.2 Message-ID: <651@cbosgd.UUCP> Date: Sun, 27-Nov-83 19:13:02 EST Article-I.D.: cbosgd.651 Posted: Sun Nov 27 19:13:02 1983 Date-Received: Mon, 28-Nov-83 23:02:22 EST Organization: AT&T Bell Laboratories, Columbus Lines: 51 In 4.2BSD, if a signal interrupts a system call, the system call is resumed once the signal handler exits. While it can be argued that this behavior makes more sense, it breaks a lot of programs. Some programs have code that looks like do { printf("prompt"); caught = 0; osig = signal(SIGxxx, catch); read(0, buf, num); signal(SIGxxx, osig); } while (caught); catch(signum) { signal(SIGxxx, catch); caught = signum; } In 4.1 and all other versions of UNIX, this arranges that when SIGxxx (e.g. SIGINT or SIGCONT) comes in, the read terminates early and the prompt is printed on the next trip through the loop. in 4.2, the read resumes and only one prompt is printed, or in this case you go into a loop. I'm looking for a nice way to write clean portable code that will work with this new system and still work with the old system. ifdefs are acceptable but it would be nice to keep the number down. One way might be to use setjmp and have the signal routine longjmp to the caller, replacing the loop. Thus, you get #include jump_buf sigjmpbuf; setjmp(sigjmpbuf); caught = 0; printf("prompt"); osig = signal(SIGxxx, catch); read(0, buf, num); signal(SIGxxx, osig); catch(signum) { signal(SIGxxx, catch); longjmp(sigjmpbuf); caught = signum; } This strikes me as considerably less clear and more error-prone than the old method. Can anyone suggest a better way - perhaps a way to make 4.2 go into "4.1 mode" without modifying the kernel or C library?