[comp.sys.3b1] tty kill_char

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.


=============================================================================