kathyv@tektools.UUCP (Kathy Vineyard) (12/01/86)
Index: /usr/src/usr.lib/libcurses/cr_tty.c 4.3BSD Description: When running a program that uses curses, the user environment was sometimes getting stepped on. This resulted in getting the famed "x: is not an identifier" from /bin/sh when it was exec'd. This happened only when using a termcap which had multiple names ( > 2 ) for the termcap entry, the third name of the entry was the one being used by the user, and the length of that third name was at least 2 less than the length of the second name. Repeat-By: Use a termcap which has it's names set up like: Mc|aaa-c|aaa|aaa with separate scrolling and editing areas:\ The way I found it was to use initscr() (which calls the functions in cr_tty.c) and print out the environment just before and after the initscr. With a termcap entry set up as above (with the setups, of course) and your TERM variable set to the third name (in this case, the "aaa"), you can run this little program to duplicate the bug and see how it messes up the environment: #include <stdio.h> #include <curses.h> extern char **environ; printenv() { int n=1; char **c; c= environ; while (*c) { printf("%d. %s\n",n, *c); n++; *c++; } } main() { printenv(); initscr(); refresh(); printenv(); printf("\n"); execl("/bin/sh","sh","-c","ls"); } ( compile with "cc foo.c -lcurses -ltermlib" ) Fix: A fix is to send longname() a copy of the TERM variable, not the TERM variable itself, as longname replaces the variable it was sent with the second field of the termcap name. A context diff is included, numbering may be a few off: *** cr_tty.c.old Mon Dec 1 11:25:35 1986 --- cr_tty.c.new Mon Dec 1 11:25:09 1986 *************** *** 77,82 reg int unknown; static char genbuf[1024]; # ifdef TIOCGWINSZ struct winsize win; # endif --- 77,84 ----- reg int unknown; static char genbuf[1024]; + static char xtype[1024]; /* xtype should be the same size + as genbuf for longname(). */ # ifdef TIOCGWINSZ struct winsize win; # endif *************** *** 137,143 PC = _PC ? _PC[0] : FALSE; aoftspace = _tspace; ! strncpy(ttytype, longname(genbuf, type), sizeof(ttytype) - 1); ttytype[sizeof(ttytype) - 1] = '\0'; if (unknown) return ERR; --- 139,150 ----- PC = _PC ? _PC[0] : FALSE; aoftspace = _tspace; ! /* ! * longname() steps on the second variable it is passed, so copy type ! * into xtype so it isn't stepped on when you are least suspecting it. ! */ ! strcpy(xtype,type); ! strncpy(ttytype, longname(genbuf, xtype), sizeof(ttytype) - 1); ttytype[sizeof(ttytype) - 1] = '\0'; if (unknown) return ERR; ------------------------------------------------------------------------------- Kathy Vineyard kathyv@tektools.tek.com Unix Systems Support, Tektronix Inc.