donlash@uncle.uucp (Donald Lashomb) (02/12/91)
unix-pc (er... 3b1 :-) folks, The following is a dissertation on the kill char problem that I wrote quite awhile ago. In it I tell how I fixed the kill char in my machine to be cntl-U instead of '@'. The bottom line is: patch the kernal and make sure you always specifically set kill=^u in all your dealings with stty and tset. Sorry, I never got around to figuring out how to patch stty and tset as was discussed below; but at least I do tell how to patch the kernal. Hope this helps those who have suffered long enough, Don ---- Donald Lashomb donlash@uncle.UUCP -or- Cranberry Lake, NY ...!uncle!crlake!{install,root,donny} ============================================================================= SUBJECT: tty kill char (@) problem SYNOPSIS: openning a window always makes the kill character == '@' "stty ek" makes erase char == cntl-H, kill char == '@' tset(1) makes kill char == '@' unless told differently DESCRIPTION: I like to have my kill character set to cntl-U EVERWHERE in my system. Using "stty kill ^u" works for most situations, but whenever a you open a new window, the kill character always gets set back to '@'. This happens, for example, while taking notes during a phone call. Here's the test: $ stty kill '^u' $ stty -a </dev/window << reports kill=@ >> Another inconsistency concerning the erase and kill characters is with the stty(1) command. The manual page for stty(1) states that the "ek" options sets the erase and kill characters to '#' and '@', ie. their historical defaults. Actually it sets them to cntl-H and '@', and does so regardless of the defaults in the kernal. There may be trouble lurking in "sane" option to stty(1) or getty(1M), tset(1), or other programs that deal with the terminal settings - I haven't checked into them real good. But, for example, if you use tset(1) (maybe stty too) for other reasons, it will override the kernal's default setting and make the kill char = @ unless you tell it specifically to make kill = ^U. Now what should be done about this problem? As I see it there are two ways to go: Make everything historically correct, or make it reasonably modern. Either way, it should be consistent! If we take the historical approach, then we must: * make erase == '#' and kill == '@' in the default c_cc[] array in the kernal. * make wind.o grab the settings from previous window whenever it opens a new window, so that if the user changes the settings with the stty or tset command those settings will be used for all new windows. This could be tougher than it sounds - what about windows that are openned on deamons like phone mgr! * fix the "stty ek" command so it really does make erase == '#' and kill == '@'. * make tset(1) assume the historical defaults of erase == '#' and kill == '@' * correct the manual pages to reflect the changes. If we take the reasonably modern approach, then we must: * make erase == cntl-H and kill == cntl-U in the default c_cc[] array in the kernal. * fix the "stty ek" command so that it sets the erase and kill characters to their system defaults - ie erase == cntl-H and kill == cntl-U. * make tset(1) assume the modern defaults of erase == cntl-H and kill == cntl-U. * correct the manual pages to reflect the changes. Well the manual page, termio(7), specifically states that erase char == '#' and kill char == '@'. In fact it inconsistantly names '#' as the erase char in the description, but shows cntl-H (backspace) as being the default for the c_cc[] array. And the default for the erase character IS cntl-H in the kernal. I know that '#' and '@' are the historical defaults, but nowadays cntl-H and cntl-U make a lot more sense. Seeing that the manual is wrong about the erase character, it might as well be wrong about the kill character too - IMHO, the second approach should be followed: the default c_cc[] array in the kernal should be patched and the stty(1) and tset(1) commands should be fixed so that erase == cntl-H and kill == cntl-U. Here is a excerp from a discussion I had with my freind John Milton about this problem: ------------ I finally solved my kill char problem! The kill char on my machine is now cntl-U *EVERYWHERE* !!! No more @ <--see! This may sound crazy, but I patched the kernal: # adb -w /unix @ ttcchar,2?X v ------------------------ ttcchar: 7f1c0840 4000000 | note: | ttcchar+2?x | hex 40 == ascii @ | ttcchar+2: 840 | hex 15 == ascii ^u | ttcchar+2?w 815 | adb on 3.51m kernal | swpulse+1a48: 840 = 815 | reports swpulse+1b80 | ttcchar,2?X ------------------------ ttcchar: 7f1c0815 4000000 $q # sync ; sync ; sync ; sync # reboot There is an alternate way, by patching wind and wind.o What happens is this: Whenever a new window is openned thru /dev/window, the wind driver checks win_cnt for the next available window device. It calls ttinit in the kernal to setup the default termio parameters incl the erase and kill characters. ttinit accesses ttcchar obviously. When wind regains control, it fixes up the input, output, control and local termio modes, but it leaves the control characters as defaulted by ttinit. There is plenty of room in the (compiler generated) wind code to patch in an instruction to set the kill character for windows. But be careful, the offset to the c_cc[] is not where you'd think. Here is short listing of the code in wdopen(): wdopen+1a4: jsr 1389c # call ttinit mova.l -18.w(%fp),%a0 # A0--> window setup area mov.w &526,36.w(%a0) # c_iflag @ offset 36 hex mova.l -18.w(%fp),%a0 # ..again mov.w &5,38.w(%a0) # c_oflag @ offset 38 hex mova.l -18.w(%fp),%a0 # ..again mov.w &3b,3c.w(%a0) # c_lflag @ offset 3c hex mova.l -18.w(%fp),%a0 # ..again mov.w &48bd,3a.w(%a0) # c_cflag @ offset 3a hex As you can see there is no need to keep setting A0 everytime, so you could substitute an instruction to fix-up the kill char in c_cc[]. c_cc[] is at offset 47 hex from A0 so: mov.w &815,49.w(%a0) # make erase=^H, kill=^U ****Caution**** I haven't tested this method, it was just TOO easy to patch the one byte in the kernal instead. As far as patching the kernal to get cntl-U as the kill char goes, you still should use tset '-k^U' and/or stty kill '^u'. Because if you use tset (maybe stty too) for other reasons, it will override the kernal's setting and make the kill char = @ again unless you tell it specifically to make kill = ^U. =============================================================================