Subject: u_long op= int bug, dirfd() collision, reset/setexit use (#196) Index: lib/ccom/optable,ucb/sccs.c,games/trek/.c 2.11BSD Description: 1) Another case was overlooked in the 'unsigned long' changes to the compiler. Code of the form "u_long /= int" would cause a "no code table" error in the compiler. 2) The recent addition of the macro 'dirfd()' to sys/dir.h caused a name collision with a local variable in sccs.c. 3) trek(6) made use of the obsolete 'reset' and 'setexit' functions. Those functions were removed from libc.a some time ago. Building trek results in undefined symbols. Repeat-By: 1) Compile the following test program: ----------------- unsigned long ul; int i; main() { ul /= i; ul *= i; } ---------------- Note the errors: 7: No code table for op: /=(125) type: 9 8: No code table for op: *=(124) type: 9 There were two cases (tcsh and named/tools/nslookup) in the system which exercised this bug. 2) Attempt to compile 'sccs'. Note the errors: sccs.c: 916: dirfd: argument mismatch sccs.c: 980: dirfd: argument mismatch sccs.c: 981: dirfd: argument mismatch sccs.c: 994: dirfd: argument mismatch sccs.c: 1043: dirfd: argument mismatch sccs.c: 707: NULL: unterminated macro call 3) cd /usr/src/games/trek; make Note that the linker complains that '_reset' and '_setexit' are undefined. Fix: Apply the following patch. These files are updated: /VERSION /usr/src/lib/ccom/optable /usr/src/ucb/sccs.c /usr/src/games/trek/main.c /usr/src/games/trek/lose.c /usr/src/games/trek/play.c /usr/src/games/trek/win.c The C compiler bug was fixed by adding two new rules to the code table for u_long operands. The 'sccs' problem fix was to change the name of the local variable to "dirp" from "dirfd". In 'trek' the reset()+setexit() calls were replaced with calls to 'setjmp'+'longjmp'. To apply this update: 1) save the patch below to a file, /tmp/foo 2) patch -p < /tmp/foo 3) cd /usr/src/lib/ccom make make install make clean 4) cd /usr/src/games/trek make make install make clean 5) cd /usr/src/ucb make sccs install -s -m 755 sccs /usr/ucb/sccs 5) rm /tmp/foo Thanks to Tom Helbekkmo (edb_tom@debet.nhh.no) for bringing these problems to my attention. As always all patches are available via anonymous FTP to ftp.iipo.gtegsc.com in the directory /pub/2.11BSD ----------------------cut here *** /VERSION.old Fri Nov 4 23:19:02 1994 --- /VERSION Sun Nov 20 19:00:13 1994 *************** *** 1,4 **** ! Current Patch Level: 195 2.11 BSD ============ --- 1,4 ---- ! Current Patch Level: 196 2.11 BSD ============ *** /usr/src/lib/ccom/optable.old Tue Oct 4 21:17:05 1994 --- /usr/src/lib/ccom/optable Sun Nov 20 17:55:14 1994 *************** *** 1169,1175 **** --- 1169,1177 ---- /* *=, /=, %= for unsigned long */ cr124: %n,nl + %n,nul %nl,n + %nul,n % [l86] /* *=, /=, %= for longs */ *** /usr/src/ucb/sccs.c.old Mon Jan 18 09:35:47 1993 --- /usr/src/ucb/sccs.c Sun Nov 20 18:52:02 1994 *************** *** 4,18 **** * specifies the terms and conditions for redistribution. */ ! #ifndef lint char copyright[] = "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; - #endif not lint ! #ifndef lint ! static char sccsid[] = "@(#)sccs.c 5.1 (Berkeley) 5/31/85"; ! #endif not lint # include # include --- 4,16 ---- * specifies the terms and conditions for redistribution. */ ! #if !defined(lint) && defined(DOSCCS) char copyright[] = "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)sccs.c 5.1.1 (2.11BSD GTE) 11/20/94"; ! #endif # include # include *************** *** 913,919 **** struct direct *dir; char buf[FBUFSIZ]; char *bufend; ! register DIR *dirfd; register char *basefile; bool gotedit; bool gotpfent; --- 911,917 ---- struct direct *dir; char buf[FBUFSIZ]; char *bufend; ! register DIR *dirp; register char *basefile; bool gotedit; bool gotpfent; *************** *** 977,984 **** gstrcat(buf, SccsPath, sizeof(buf)); bufend = &buf[strlen(buf)]; ! dirfd = opendir(buf); ! if (dirfd == NULL) { usrerr("cannot open %s", buf); return (EX_NOINPUT); --- 975,982 ---- gstrcat(buf, SccsPath, sizeof(buf)); bufend = &buf[strlen(buf)]; ! dirp = opendir(buf); ! if (dirp == NULL) { usrerr("cannot open %s", buf); return (EX_NOINPUT); *************** *** 991,997 **** */ gotedit = FALSE; ! while (dir = readdir(dirfd)) { if (strncmp(dir->d_name, "s.", 2) != 0) continue; --- 989,995 ---- */ gotedit = FALSE; ! while (dir = readdir(dirp)) { if (strncmp(dir->d_name, "s.", 2) != 0) continue; *************** *** 1040,1046 **** } /* cleanup & report results */ ! closedir(dirfd); if (!gotedit && mode == INFOC) { printf("Nothing being edited"); --- 1038,1044 ---- } /* cleanup & report results */ ! closedir(dirp); if (!gotedit && mode == INFOC) { printf("Nothing being edited"); *** /usr/src/games/trek/main.c.old Sat Feb 1 13:53:03 1986 --- /usr/src/games/trek/main.c Sun Nov 20 20:08:27 1994 *************** *** 4,22 **** * specifies the terms and conditions for redistribution. */ ! #ifndef lint char copyright[] = "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; - #endif not lint ! #ifndef lint ! static char sccsid[] = "@(#)main.c 5.1 (Berkeley) 1/29/86"; ! #endif not lint # include "trek.h" # include # include # define PRIO 00 /* default priority */ int Mother = 51 + (51 << 8); --- 4,22 ---- * specifies the terms and conditions for redistribution. */ ! #if !defined(lint) && defined(DOSCCS) char copyright[] = "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)main.c 5.1.1 (2.11BSD GTE) 11/20/94"; ! #endif # include "trek.h" # include # include + # include + # define PRIO 00 /* default priority */ int Mother = 51 + (51 << 8); *************** *** 118,123 **** --- 118,125 ---- *********************************************************************** */ + jmp_buf env; + main(argc, argv) int argc; char **argv; *************** *** 129,135 **** register int ac; register char **av; struct sgttyb argp; - int been_here = 0; av = argv; ac = argc; --- 131,136 ---- *************** *** 188,204 **** f_log = fopen(av[0], opencode); */ ! printf("\n * * * S T A R T R E K * * *\n\n"); ! ! play_with(stdin); ! ungetc('\n',stdin); ! setexit(); ! if ( been_here == 1 ) { if ( !getynpar("Another game") ) exit(0); } - been_here = 1; do { setup(); --- 189,201 ---- f_log = fopen(av[0], opencode); */ ! printf("\n * * * S T A R T R E K * * *\n\nPress return to continue.\n"); ! ! if (setjmp(env)) { if ( !getynpar("Another game") ) exit(0); } do { setup(); *************** *** 206,220 **** } while (getynpar("Another game")); fflush(stdout); - } - - play_with(iop) - register FILE *iop; - { - extern char _sibuf[]; - - iop->_cnt = 0; - iop->_base = _sibuf; - iop->_ptr = iop->_base; - iop->_bufsiz = BUFSIZ; } --- 203,206 ---- *** /usr/src/games/trek/lose.c.old Sat Feb 1 13:53:01 1986 --- /usr/src/games/trek/lose.c Sun Nov 20 19:48:12 1994 *************** *** 4,14 **** * specifies the terms and conditions for redistribution. */ ! #ifndef lint ! static char sccsid[] = "@(#)lose.c 5.1 (Berkeley) 1/29/86"; ! #endif not lint # include "trek.h" /* ** PRINT OUT LOSER MESSAGES --- 4,15 ---- * specifies the terms and conditions for redistribution. */ ! #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)lose.c 5.1.1 (2.11BSD GTE) 11/20/94"; ! #endif # include "trek.h" + # include /* ** PRINT OUT LOSER MESSAGES *************** *** 38,43 **** --- 39,46 ---- lose(why) int why; { + extern jmp_buf env; + Game.killed = 1; sleep(1); printf("\n%s\n", Losemsg[why - 1]); *************** *** 51,55 **** Move.endgame = -1; score(); skiptonl(0); ! reset(); } --- 54,58 ---- Move.endgame = -1; score(); skiptonl(0); ! longjmp(env, 1); } *** /usr/src/games/trek/play.c.old Sat Feb 1 13:53:07 1986 --- /usr/src/games/trek/play.c Sun Nov 20 19:50:36 1994 *************** *** 4,15 **** * specifies the terms and conditions for redistribution. */ ! #ifndef lint ! static char sccsid[] = "@(#)play.c 5.1 (Berkeley) 1/29/86"; ! #endif not lint # include "trek.h" # include "getpar.h" /* ** INSTRUCTION READ AND MAIN PLAY LOOP --- 4,16 ---- * specifies the terms and conditions for redistribution. */ ! #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)play.c 5.1.1 (2.11BSD GTE) 11/20/94"; ! #endif # include "trek.h" # include "getpar.h" + # include /* ** INSTRUCTION READ AND MAIN PLAY LOOP *************** *** 24,30 **** extern int abandon(), capture(), shield(), computer(), dcrept(), destruct(), dock(), help(), impulse(), lrscan(), warp(), dumpgame(), rest(), shell(), srscan(), ! reset(), torped(), visual(), setwarp(), undock(), phaser(); struct cvntab Comtab[] = { --- 25,31 ---- extern int abandon(), capture(), shield(), computer(), dcrept(), destruct(), dock(), help(), impulse(), lrscan(), warp(), dumpgame(), rest(), shell(), srscan(), ! myreset(), torped(), visual(), setwarp(), undock(), phaser(); struct cvntab Comtab[] = { *************** *** 47,53 **** "sh", "ield", shield, 0, "s", "rscan", srscan, 0, "st", "atus", srscan, -1, ! "terminate", "", reset, 0, "t", "orpedo", torped, 0, "u", "ndock", undock, 0, "v", "isual", visual, 0, --- 48,54 ---- "sh", "ield", shield, 0, "s", "rscan", srscan, 0, "st", "atus", srscan, -1, ! "terminate", "", myreset, 0, "t", "orpedo", torped, 0, "u", "ndock", undock, 0, "v", "isual", visual, 0, *************** *** 54,59 **** --- 55,67 ---- "w", "arp", setwarp, 0, 0 }; + + myreset() + { + extern jmp_buf env; + + longjmp(env, 1); + } play() { *** /usr/src/games/trek/win.c.old Thu May 30 09:06:30 1985 --- /usr/src/games/trek/win.c Sun Nov 20 19:52:33 1994 *************** *** 4,15 **** * specifies the terms and conditions for redistribution. */ ! #ifndef lint ! static char sccsid[] = "@(#)win.c 5.1 (Berkeley) 5/30/85"; ! #endif not lint # include "trek.h" # include "getpar.h" /* ** Signal game won --- 4,16 ---- * specifies the terms and conditions for redistribution. */ ! #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)win.c 5.1.1 (2.11BSD GTE) 11/20/94"; ! #endif # include "trek.h" # include "getpar.h" + # include /* ** Signal game won *************** *** 27,32 **** --- 28,34 ---- win() { long s; + extern jmp_buf env; extern long score(); extern struct cvntab Skitab[]; register struct cvntab *p; *************** *** 56,60 **** /* clean out input, and request new game */ skiptonl(0); ! reset(); } --- 58,62 ---- /* clean out input, and request new game */ skiptonl(0); ! longjmp(env, 1); }