NetBSD Problem Report #10879

Received: (qmail 23381 invoked from network); 22 Aug 2000 15:04:26 -0000
Message-Id: <20000822150424.EF04C7E7@terry.sophos.com>
Date: Tue, 22 Aug 2000 16:04:24 +0100 (BST)
From: Ian.Fry@sophos.com
Reply-To: Ian.Fry@sophos.com
To: gnats-bugs@gnats.netbsd.org
Subject: su does not reset terminal settings after Ctrl-C
X-Send-Pr-Version: 3.95

>Number:         10879
>Category:       bin
>Synopsis:       su does not reset terminal settings after Ctrl-C
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Aug 22 15:05:00 +0000 2000
>Closed-Date:    Mon May 02 12:18:15 +0000 2016
>Last-Modified:  Mon May 02 12:18:15 +0000 2016
>Originator:     Ian Fry
>Release:        Aug 20, 2000
>Organization:

>Environment:
System: NetBSD terry 1.5E NetBSD 1.5E (TERRY) #65: Wed Aug 16 13:34:23 BST 2000 ief@terry:/usr/src/sys/arch/i386/compile/TERRY i386


>Description:
   If you type Ctrl-C at the password prompt issued by 'su', the terminal
settings are not correctly restored.
>How-To-Repeat:
	Attempt to 'su' to another user (e.g. root), and press Ctrl-C at the
password prompt. Terminal echo setting remains off, and requires resetting
manually.
   This only seems to affect bash (I've also tried sh and csh). However, with
sh and csh, you need to press return after the Ctrl-C to get back to a shell
prompt.
>Fix:
	Enter an invalid password to abort the su attempt.
>Release-Note:
>Audit-Trail:

From: James Chacon <jchacon@genuity.net>
To: Ian.Fry@sophos.com
Cc: gnats-bugs@gnats.netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Wed, 23 Aug 2000 02:52:01 -0400 (EDT)

 This is actually not a su bug per se, but a behavior that occurs because
 getpass(3) blocks signals which working with the tty and then unblocks
 afterwards. This causes the interrupt to not actually occur while in non-echo
 mode, but I do agree having to hit the extra return is odd.

 James

 >
 >
 >>Number:         10879
 >>Category:       bin
 >>Synopsis:       su does not reset terminal settings after Ctrl-C
 >>Confidential:   no
 >>Severity:       non-critical
 >>Priority:       medium
 >>Responsible:    bin-bug-people
 >>State:          open
 >>Class:          sw-bug
 >>Submitter-Id:   net
 >>Arrival-Date:   Tue Aug 22 08:05:00 PDT 2000
 >>Closed-Date:
 >>Last-Modified:
 >>Originator:     Ian Fry
 >>Release:        Aug 20, 2000
 >>Organization:
 >	
 >>Environment:
 >System: NetBSD terry 1.5E NetBSD 1.5E (TERRY) #65: Wed Aug 16 13:34:23 BST 2000 ief@terry:/usr/src/sys/arch/i386/compile/TERRY i386
 >
 >
 >>Description:
 >   If you type Ctrl-C at the password prompt issued by 'su', the terminal
 >settings are not correctly restored.
 >>How-To-Repeat:
 >	Attempt to 'su' to another user (e.g. root), and press Ctrl-C at the
 >password prompt. Terminal echo setting remains off, and requires resetting
 >manually.
 >   This only seems to affect bash (I've also tried sh and csh). However, with
 >sh and csh, you need to press return after the Ctrl-C to get back to a shell
 >prompt.
 >>Fix:
 >	Enter an invalid password to abort the su attempt.
 >>Release-Note:
 >>Audit-Trail:
 >>Unformatted:
 >
 >
 >
 >


From: James Chacon <jchacon@genuity.net>
To: jchacon@genuity.net (jchacon)
Cc: Ian.Fry@sophos.com, gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 00:46:04 -0400 (EDT)

 (This is a long email for a rather dull subject but the implications 
 intrigued me to a point....:-)

 Ok, this is gonna require some thinking to fix the behavior.

 The reason the control-C doesn't appear to take effect is because getpass
 blocks SIGINT and SIGTSTP while it's processing. However it doesn't stop
 processing until it either gets EOF or \n. So what you're seeing is not the
 shell misbehaving but it not seeing the process exit until then.

 i.e.

 1. You run su
 2. You type some stuff and hit ^C.
 3. That's currently blocked so nothing happens
 4. You eventually hit return.
 5. getpass(3) cleans up, turns back on echo and unblocks the signal
 6. Now the SIGINT gets delivered and the code exits immediately
 7. The shell see the exit and prints a new prompt.

 Fixing this isn't as simple though. The reasons for blocking the signals
 are good..We're mucking with the terminal (in this case throwing it into
 no echo mode), and before returning everything should be cleaned up. 
 Now, having a library routine catch the signals is quite messy and doing 
 something other than blocking (like setting them to ignore) is just as bad.

 There is no good middle ground here that I can tell, but this behavior is
 non obvious to someone trying to abort a su(1). Especially since I can abort
 it with other signals like SIGQUIT (^\). That behaves exactly like you'd
 expect a SIGINT to work (it exits right away without the return), but depending
 on your shell you might get left in no-echo mode (sh/csh do for instance but
 bash resets my terminal).

 I think one of the follwing need to occur:

 1. Block all signals in getpass so everything is consistant across the board
    and document that code using getpass(3) needs to expect the non-obvious
    SIGINT + return == exit behaviour.

 2. Put signal handlers in getpass(3) which catch everything, reset the 
    terminal settings and then pass off to either the default or a previously
    installed handler. (YUCK)

 3. Don't block anything and let the terminal/shell do their thing on exit.
    Expect the application code to catch relevant signals and possibly have
    to deal with resetting echo mode on the terminal. (i.e. updating the
    man page to getpass(3) to include "If aborted by a signal the terminal will
    be left in non-echo mode."

 4. Ignore all the issues related around this and just fix su to use it's own
    getpass implementation and catch the signals itself. (Still update 
    the getpass(3) man page at a minimum to explain what's occuring here).

 I actually think #3 is the most reasonable but it will require any userland
 code relying on getpass to accomodate change. (24 files today)

 James



 >
 >This is actually not a su bug per se, but a behavior that occurs because
 >getpass(3) blocks signals which working with the tty and then unblocks
 >afterwards. This causes the interrupt to not actually occur while in non-echo
 >mode, but I do agree having to hit the extra return is odd.
 >
 >James
 >
 >>
 >>
 >>>Number:         10879
 >>>Category:       bin
 >>>Synopsis:       su does not reset terminal settings after Ctrl-C
 >>>Confidential:   no
 >>>Severity:       non-critical
 >>>Priority:       medium
 >>>Responsible:    bin-bug-people
 >>>State:          open
 >>>Class:          sw-bug
 >>>Submitter-Id:   net
 >>>Arrival-Date:   Tue Aug 22 08:05:00 PDT 2000
 >>>Closed-Date:
 >>>Last-Modified:
 >>>Originator:     Ian Fry
 >>>Release:        Aug 20, 2000
 >>>Organization:
 >>	
 >>>Environment:
 >>System: NetBSD terry 1.5E NetBSD 1.5E (TERRY) #65: Wed Aug 16 13:34:23 BST 2000 ief@terry:/usr/src/sys/arch/i386/compile/TERRY i386
 >>
 >>
 >>>Description:
 >>   If you type Ctrl-C at the password prompt issued by 'su', the terminal
 >>settings are not correctly restored.
 >>>How-To-Repeat:
 >>	Attempt to 'su' to another user (e.g. root), and press Ctrl-C at the
 >>password prompt. Terminal echo setting remains off, and requires resetting
 >>manually.
 >>   This only seems to affect bash (I've also tried sh and csh). However, with
 >>sh and csh, you need to press return after the Ctrl-C to get back to a shell
 >>prompt.
 >>>Fix:
 >>	Enter an invalid password to abort the su attempt.
 >>>Release-Note:
 >>>Audit-Trail:
 >>>Unformatted:
 >>
 >>
 >>
 >>
 >
 >
 >


From: Lucio De Re <lucio@proxima.alt.za>
To: James Chacon <jchacon@genuity.net>
Cc: Ian.Fry@sophos.com, gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 16:54:23 +0200

 On Thu, Aug 24, 2000 at 12:46:04AM -0400, James Chacon wrote:
 > 
 > Ok, this is gonna require some thinking to fix the behavior.
 > 
 You left out one possible option: block signals in getpass only if
 they are default.  Let su do its own intercept, and getpass can then
 assume that if the signals are being handled, it does not have to do
 so itself.  Su will have to include both a signal handler and a term
 setting restore, but that seems like a reasonable expectation.

 ++L

From: James Chacon <jchacon@genuity.net>
To: lucio@proxima.alt.za
Cc: jchacon@genuity.net (James Chacon), Ian.Fry@sophos.com,
        gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 10:58:23 -0400 (EDT)

 Ok, it's been a while since I wrote lots of signal code, but how exactly would
 you query the current signal handler without changing it? sigaction/signal
 only return the previous handler after you change it which is definitly not
 what I'd want a library routine doing (race conditions, etc).

 James

 >
 >On Thu, Aug 24, 2000 at 12:46:04AM -0400, James Chacon wrote:
 >> 
 >> Ok, this is gonna require some thinking to fix the behavior.
 >> 
 >You left out one possible option: block signals in getpass only if
 >they are default.  Let su do its own intercept, and getpass can then
 >assume that if the signals are being handled, it does not have to do
 >so itself.  Su will have to include both a signal handler and a term
 >setting restore, but that seems like a reasonable expectation.
 >
 >++L
 >
 >
 >
 >


From: Lucio De Re <lucio@proxima.alt.za>
To: James Chacon <jchacon@genuity.net>
Cc: Ian.Fry@sophos.com, gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 17:39:19 +0200

 On Thu, Aug 24, 2000 at 10:58:23AM -0400, James Chacon wrote:
 > 
 > Ok, it's been a while since I wrote lots of signal code, but how exactly would
 > you query the current signal handler without changing it? sigaction/signal
 > only return the previous handler after you change it which is definitly not
 > what I'd want a library routine doing (race conditions, etc).
 > 
 If you're willing to change in the first palce, just put it back if it
 wasn't what you expected.  From (bad) memory:

 	s = signal (SIGINT, SIG_IGN);
 	if (s != SIG_DFL)
 		signal (SIGINT, s);

 This isn't exactly worse than what you'd have done anyway, is it?
 There's a very small period during which the ^C may be ignored, but I
 really can't imagine it being long enough for anyone to race it, not
 even expect :-)

 Don't forget to put it back if it stays changed.

 I hope I'm not leading you up the garden path.

 ++L

From: woods@weird.com (Greg A. Woods)
To: James Chacon <jchacon@genuity.net>
Cc: Ian.Fry@sophos.com, gnats-bugs@gnats.netbsd.org,
	netbsd-bugs@netbsd.org, tech-userlevel@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 11:51:27 -0400 (EDT)

 [ On Thursday, August 24, 2000 at 00:46:04 (-0400), James Chacon wrote: ]
 > Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
 >
 > I think one of the follwing need to occur:
 > 
 > 1. Block all signals in getpass so everything is consistant across the board
 >    and document that code using getpass(3) needs to expect the non-obvious
 >    SIGINT + return == exit behaviour.
 > 
 > 2. Put signal handlers in getpass(3) which catch everything, reset the 
 >    terminal settings and then pass off to either the default or a previously
 >    installed handler. (YUCK)
 > 
 > 3. Don't block anything and let the terminal/shell do their thing on exit.
 >    Expect the application code to catch relevant signals and possibly have
 >    to deal with resetting echo mode on the terminal. (i.e. updating the
 >    man page to getpass(3) to include "If aborted by a signal the terminal will
 >    be left in non-echo mode."
 > 
 > 4. Ignore all the issues related around this and just fix su to use it's own
 >    getpass implementation and catch the signals itself. (Still update 
 >    the getpass(3) man page at a minimum to explain what's occuring here).
 > 
 > I actually think #3 is the most reasonable but it will require any userland
 > code relying on getpass to accomodate change. (24 files today)

 You missed another posible solution....

   5. have getpass(3) put the terminal in raw mode and emulate all of the
      character processing within itself.

 BTW #4 is completely the wrong approach and probably shouldn't even be
 listed as a potential solution.

 #2 is possible, but a little yucky as you say.  It's also probably about
 as hard to get right as my #5 too.

 #1 is more or less wrong too, and is what taught me to use ^D (i.e. the
 EOF character) to abort 'su' etc.

 In reality though #3 is the only correct solution, and is the one that's
 been chosen by Unix for a long time now (I'm not sure since exactly
 when, though I do note from the sources I have that up to System III
 that SIGINT is simply ignored until after a '\n' or EOF is returned and
 that only echo processing is modifed, however all of the AT&T Unix
 manuals I have, including the System V Release 2.2 manual page from
 about 1986, state explicitly that "An interrupt will terminate input and
 send an interrupt signal to the calling program before returning." with
 the implication being that echoing is not re-enabled in that case).

 Of course users of getpass() must be fixed up to catch SIGINT and to
 properly reset the terminal modes when it is triggered....  We can't be
 relying on interactive shells to restore the terminal modes!

 The code in 4.3BSD-Reno has the comment:

         /*
          * note - blocking signals isn't necessarily the
          * right thing, but we leave it for now.
          */

 I can assure you that I was very happy with the behaviour of System V
 'su' w.r.t. interrupts during the getpass() call, and I've been rather
 disappointed by the return of the broken behaviour in even modern BSDs.

 My remaining problem with *BSD tty behaviour, which is demonstrated by
 getpass(), is the mis-handling of EOF.  Traditionally I recall ^D
 working at any point on a line.  In BSD it only has the effect of
 generating EOF when entered at the beginning of a line.  This frustrates
 me almost every time I want to abort 'su' as I have to remember that: a)
 BSD's version still blocks SIGINT; and b) that EOF only works at the
 beginning of the line so now I have to use ^U^D instead.

 -- 
 							Greg A. Woods

 +1 416 218-0098      VE3TCP      <gwoods@acm.org>      <robohack!woods>
 Planix, Inc. <woods@planix.com>; Secrets of the Weird <woods@weird.com>

From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org,
        tech-userlevel@netbsd.org
Cc:  
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C 
Date: Fri, 25 Aug 2000 02:19:59 +1000

     Date:        Thu, 24 Aug 2000 11:51:27 -0400 (EDT)
     From:        woods@weird.com (Greg A. Woods)
     Message-ID:  <20000824155127.4453E98@proven.weird.com>

   | #2 is possible, but a little yucky as you say.  It's also probably about
   | as hard to get right as my #5 too.

 It shouldn't be, that way (have getpass() catch signals and DTRT) is
 the correct solution.

 Anything which is messing with the terminal state should be doing that.

   | In reality though #3 is the only correct solution, and is the one that's
   | been chosen by Unix for a long time now

 I don't think so.    The difference that is probably causing the
 different behaviour is that a read() will be restarted after a signal
 in *BSD, without the application noticing it.  Perviously the signal
 would have caused the read() to return an error (EINTR) which could
 then be treated as a "clean up and get out" indicator by getpass().

 That and that getpass() is just blocking signals now, instead of
 catch, cleanup, and return.

   | Of course users of getpass() must be fixed up to catch SIGINT and to
   | properly reset the terminal modes when it is triggered....

 No, if getpass() is going to meddle it is getpass()'s job to unmeddle.

   | We can't be
   | relying on interactive shells to restore the terminal modes!

 That's true.

   | The code in 4.3BSD-Reno has the comment:
   | 
   |         /*
   |          * note - blocking signals isn't necessarily the
   |          * right thing, but we leave it for now.
   |          */

 That's also true - it is just the easy way, and close enough...

   | My remaining problem with *BSD tty behaviour, which is demonstrated by
   | getpass(), is the mis-handling of EOF.  Traditionally I recall ^D
   | working at any point on a line.

 Never.   Not ever, not even once.   ^D has always meant "end the current
 input line here, without including the ^D character".   If there's nothing
 in the line, that results in a 0 length read, which is EOF.  If there's
 anything already in the line, the program gets it without a \n on the end.

 That is truly ancient behaviour (like 5th edition unix, and probably 1st)>

   | beginning of the line so now I have to use ^U^D instead.

 Or ^D^D perhaps.   But ^C\n works for me (it is certainly close enough).

 kre

From: James Chacon <jchacon@genuity.net>
To: lucio@proxima.alt.za
Cc: jchacon@genuity.net (James Chacon), Ian.Fry@sophos.com,
        gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 12:21:09 -0400 (EDT)

 It's just bad practice IMO to introduce a race condition like this in the
 middle of library code. Granted signals are a poor way to catch some conditions
 but if I'm writing code I really don't want library routines causing 
 unexpected behaviour.

 What's really needed is a util routine which returns a list of function 
 pointers for all signals.

 James

 >
 >On Thu, Aug 24, 2000 at 10:58:23AM -0400, James Chacon wrote:
 >> 
 >> Ok, it's been a while since I wrote lots of signal code, but how exactly would
 >> you query the current signal handler without changing it? sigaction/signal
 >> only return the previous handler after you change it which is definitly not
 >> what I'd want a library routine doing (race conditions, etc).
 >> 
 >If you're willing to change in the first palce, just put it back if it
 >wasn't what you expected.  From (bad) memory:
 >
 >	s = signal (SIGINT, SIG_IGN);
 >	if (s != SIG_DFL)
 >		signal (SIGINT, s);
 >
 >This isn't exactly worse than what you'd have done anyway, is it?
 >There's a very small period during which the ^C may be ignored, but I
 >really can't imagine it being long enough for anyone to race it, not
 >even expect :-)
 >
 >Don't forget to put it back if it stays changed.
 >
 >I hope I'm not leading you up the garden path.
 >
 >++L
 >
 >
 >
 >


From: James Chacon <jchacon@genuity.net>
To: kre@munnari.OZ.AU (Robert Elz)
Cc: gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org,
        tech-userlevel@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 12:37:22 -0400 (EDT)

 >
 >  | #2 is possible, but a little yucky as you say.  It's also probably about
 >  | as hard to get right as my #5 too.
 >
 >It shouldn't be, that way (have getpass() catch signals and DTRT) is
 >the correct solution.
 >
 >Anything which is messing with the terminal state should be doing that.

 Actually I disagee that any library routine should start engaging signal
 handlers. Absolutely nothing in the libary does so today (that I could find
 with a quick scan) so this would be a pretty radical departure to start doing.

 Plus, what are you going to do with a SIGINT? Clean up and then either call
 the old handler or exit? Exiting from a library routine is even worse. That's
 a prime example generally of bad bad design.

 >
 >  | Of course users of getpass() must be fixed up to catch SIGINT and to
 >  | properly reset the terminal modes when it is triggered....
 >
 >No, if getpass() is going to meddle it is getpass()'s job to unmeddle.

 I agree from a high level view, but if there's no clean way to do that without
 getpass replacing signal handlers for every possible interrupt case then
 that's no better. A *lot* of library functions when SIGINT'd will leave things
 in an indeterminate state. In this case it's been identified and documenting
 it would be a huge step forward.

 >  | The code in 4.3BSD-Reno has the comment:
 >  | 
 >  |         /*
 >  |          * note - blocking signals isn't necessarily the
 >  |          * right thing, but we leave it for now.
 >  |          */
 >
 >That's also true - it is just the easy way, and close enough...

 Actaully no. By blocking it creates behavior that I've never seen on any 
 other system I've tried to run su on. Everything else either su catches the
 signal and fixes stuff or it leaves the terminal in non-echo mode. But, it
 doesn't require ^C\n anywhere else I've seen to abort.


From: Greywolf <greywolf@starwolf.com>
To: gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org,
        tech-userlevel@netbsd.org
Cc: James Chacon <jchacon@genuity.net>, Ian.Fry@sophos.com
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 10:12:15 -0700 (PDT)

 On Thu, 24 Aug 2000, Greg A. Woods wrote:

 [okay, so maybe I agreed too soon! :-)]

 # [ On Thursday, August 24, 2000 at 00:46:04 (-0400), James Chacon wrote: ]
 # > Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
 # >
 # > I think one of the follwing need to occur:
 # > 
 # > 1. Block all signals in getpass so everything is consistant across the board
 # >    and document that code using getpass(3) needs to expect the non-obvious
 # >    SIGINT + return == exit behaviour.

 This is the easiest case to program, but it's not correct.

 # > 2. Put signal handlers in getpass(3) which catch everything, reset the 
 # >    terminal settings and then pass off to either the default or a previously
 # >    installed handler. (YUCK)

 This is easy to program but shouldn't be left in a library routine.

 # > 3. Don't block anything and let the terminal/shell do their thing on exit.
 # >    Expect the application code to catch relevant signals and possibly have
 # >    to deal with resetting echo mode on the terminal. (i.e. updating the
 # >    man page to getpass(3) to include "If aborted by a signal the terminal will
 # >    be left in non-echo mode."

 This looks like a reasonable default and seems to be what I remember as well.

 # > 
 # > 4. Ignore all the issues related around this and just fix su to use it's own
 # >    getpass implementation and catch the signals itself. (Still update 
 # >    the getpass(3) man page at a minimum to explain what's occuring here).

 This would be silly as it would encourage other programs to use THEIR own
 getpass() routines, bypassing the system implementation altogether, which
 would leave us with a potentially decrepit (by comparison) getpass().

 # > I actually think #3 is the most reasonable but it will require any userland
 # > code relying on getpass to accomodate change. (24 files today)

 Not bad.

 # You missed another posible solution....
 # 
 #   5. have getpass(3) put the terminal in raw mode and emulate all of the
 #      character processing within itself.

 That is, as you note, tricky to get right.

 # BTW #4 is completely the wrong approach and probably shouldn't even be
 # listed as a potential solution.
 # 
 # #2 is possible, but a little yucky as you say.  It's also probably about
 # as hard to get right as my #5 too.

 No, #5 is harder.  The signal handling code would add about 3 lines per
 signal, I think.

 # In reality though #3 is the only correct solution, and is the one that's
 # been chosen by Unix for a long time now (I'm not sure since exactly
 # when, though I do note from the sources I have that up to System III
 # that SIGINT is simply ignored until after a '\n' or EOF is returned and
 # that only echo processing is modifed, however all of the AT&T Unix
 # manuals I have, including the System V Release 2.2 manual page from
 # about 1986, state explicitly that "An interrupt will terminate input and
 # send an interrupt signal to the calling program before returning." with
 # the implication being that echoing is not re-enabled in that case).

 I don't remember sigint being ignored at all for a long time!

 # Of course users of getpass() must be fixed up to catch SIGINT and to
 # properly reset the terminal modes when it is triggered....  We can't be
 # relying on interactive shells to restore the terminal modes!

 No, but if the shell happens to do it, so much the better :-).  And
 more of them do this these days.

 # I can assure you that I was very happy with the behaviour of System V
 # 'su' w.r.t. interrupts during the getpass() call, and I've been rather
 # disappointed by the return of the broken behaviour in even modern BSDs.

 To ignore SIGINT is broken, IMHO.  Why was this done?

 Shouldn't the signal(SIGINT, SIG_IGN)/signal(SIGINT, SIG_DFL) pair
 nestle around the getpass() call?

 # My remaining problem with *BSD tty behaviour, which is demonstrated by
 # getpass(), is the mis-handling of EOF.  Traditionally I recall ^D
 # working at any point on a line.

 It *does* work at any point in a line.  But if you type anything BEFORE
 the EOF, you have to hit it twice.  The second EOF will cause everything
 typed before the FIRST EOF to be sent.

 It just doesn't work the way you want/expect it to work!

 # In BSD it only has the effect of
 # generating EOF when entered at the beginning of a line.  This frustrates
 # me almost every time I want to abort 'su' as I have to remember that: a)
 # BSD's version still blocks SIGINT; and b) that EOF only works at the
 # beginning of the line so now I have to use ^U^D instead.

 Just hit two EOFs in a row and it'll abort (or if you do "CorrectPasswd^D^D"
 it will succeed).

 [tangent:  EOF was never meant as an abort char; it's an indication that
  input is finished, i.e. "I'm done, take what I gave you."

  Of course it doesn't help that 'sh' does the following:

   %
   $ ls^D^D
   [output from ls]
   $ %

   and 'csh' does the following

   % ls^D^Dexit

   Hmmm.  Is this broken?  I don't know; I always considered the older tty
   driver from AT&T to be broken (backspacing over the prompt?  No word
   erase, no nice line kill and no job control.  Gotta love it :/]

 				--*greywolf;
 --
 BSD: Mach 3 stealthOS, undetectable by media radar.


From: Greywolf <greywolf@starwolf.com>
To: Robert Elz <kre@munnari.OZ.AU>
Cc: gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org,
        tech-userlevel@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C 
Date: Thu, 24 Aug 2000 10:29:01 -0700 (PDT)

 On Fri, 25 Aug 2000, Robert Elz wrote:
 #     From:        woods@weird.com (Greg A. Woods)
 # 
 #   | #2 is possible, but a little yucky as you say.  It's also probably about
 #   | as hard to get right as my #5 too.
 # 
 # It shouldn't be, that way (have getpass() catch signals and DTRT) is
 # the correct solution.
 # 
 # Anything which is messing with the terminal state should be doing that.

 For some reason, I'm inclined to disagree.  On a normal exit, yes it will
 be restoring terminal modes, but not on a signal.  I think that's the
 responsibility of the caller.  You could see that as a PITA, but right now,
 libraries don't handle signals like that, not even curses.

 # That and that getpass() is just blocking signals now, instead of
 # catch, cleanup, and return.

 ...which seems to this dinosaur-by-osmosis to be completely wrong.

 For me it was pretty much a fact of life whenever I aborted 'su' with
 an interrupt or quit that I would have to reset my terminal.  I didn't
 even see this nonsense in the mtXINU 4.3/more distribution (of which
 the last distribution we received was just pre 4.3-reno :-).

 #   | Of course users of getpass() must be fixed up to catch SIGINT and to
 #   | properly reset the terminal modes when it is triggered....
 # 
 # No, if getpass() is going to meddle it is getpass()'s job to unmeddle.

 Not in the case of signals.  It clutters up the code.  getpass() should
 be a clean quick manner of getting a password.  I mean, okay, I've
 written getpass() from scratch before (because I didn't know about
 getpass() :-).  I didn't even take signal handling into account inside
 getpass().

 #   | The code in 4.3BSD-Reno has the comment:
 #   | 
 #   |         /*
 #   |          * note - blocking signals isn't necessarily the
 #   |          * right thing, but we leave it for now.
 #   |          */
 # 
 # That's also true - it is just the easy way, and close enough...

 It's annoying as hell, though.

 #   | beginning of the line so now I have to use ^U^D instead.
 # 
 # Or ^D^D perhaps.   But ^C\n works for me (it is certainly close enough).

 See notes on csh, sh.  ^D^D does different things there.

 [but then, that's not exactly the tty driver at work, there; cat and grep
 and sed and awk are probably better examples of this...]

 				--*greywolf;
 --
 "Never mind the bollocks, here's BSD!"


From: woods@weird.com (Greg A. Woods)
To: James Chacon <jchacon@genuity.net>
Cc: kre@munnari.OZ.AU (Robert Elz), gnats-bugs@gnats.netbsd.org,
	netbsd-bugs@netbsd.org, tech-userlevel@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 15:15:59 -0400 (EDT)

 [ On Thursday, August 24, 2000 at 12:37:22 (-0400), James Chacon wrote: ]
 > Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
 >
 > >
 > >  | #2 is possible, but a little yucky as you say.  It's also probably about
 > >  | as hard to get right as my #5 too.
 > >
 > >It shouldn't be, that way (have getpass() catch signals and DTRT) is
 > >the correct solution.
 > >
 > >Anything which is messing with the terminal state should be doing that.
 > 
 > Actually I disagee that any library routine should start engaging signal
 > handlers. Absolutely nothing in the libary does so today (that I could find
 > with a quick scan) so this would be a pretty radical departure to start doing.

 That's partly why I didn't like the idea, and the way you say it makes
 it an even more powerful reason.

 > Plus, what are you going to do with a SIGINT? Clean up and then either call
 > the old handler or exit? Exiting from a library routine is even worse. That's
 > a prime example generally of bad bad design.

 For the purpose of academic discussion I think that in the case of
 getpass() the best thing to do would be to clean up and then call the
 old handler, or if there was no old handler to just return NULL.

 > Actaully no. By blocking it creates behavior that I've never seen on any 
 > other system I've tried to run su on. Everything else either su catches the
 > signal and fixes stuff or it leaves the terminal in non-echo mode. But, it
 > doesn't require ^C\n anywhere else I've seen to abort.

 I don't even remember encountering any version that didn't restore the
 terminal modes, certainly not of the AT&T derrived variants subsequent
 to System V Release 3 or so.  I've just experimented with SunOS-5.6 and
 it seems to restore terminal modes just fine.  Someday I should
 re-install my 3B2 so it's handy for such tests....

 -- 
 							Greg A. Woods

 +1 416 218-0098      VE3TCP      <gwoods@acm.org>      <robohack!woods>
 Planix, Inc. <woods@planix.com>; Secrets of the Weird <woods@weird.com>

From: James Chacon <jchacon@genuity.net>
To: woods@weird.com
Cc: jchacon@genuity.net (James Chacon), kre@munnari.OZ.AU (Robert Elz),
        gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org,
        tech-userlevel@netbsd.org
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Thu, 24 Aug 2000 15:59:45 -0400 (EDT)

 In any case it sounds like the theme of "stop blocking any signals, fix
 the man page and except userland code to cope if they want to worry about
 terminal state" is the way to go.

 Any other solution involves signal handlers in library code which is
 disgusting or just plain non-obvious behavior when trying to abort from su.

 Patching this (and the relevant userland code) shouldn't take more than a
 couple of hours so I'll take a crack at a patch sometime this weekend and
 send it in.

 James

 >
 >[ On Thursday, August 24, 2000 at 12:37:22 (-0400), James Chacon wrote: ]
 >> Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
 >>
 >> >
 >> >  | #2 is possible, but a little yucky as you say.  It's also probably about
 >> >  | as hard to get right as my #5 too.
 >> >
 >> >It shouldn't be, that way (have getpass() catch signals and DTRT) is
 >> >the correct solution.
 >> >
 >> >Anything which is messing with the terminal state should be doing that.
 >> 
 >> Actually I disagee that any library routine should start engaging signal
 >> handlers. Absolutely nothing in the libary does so today (that I could find
 >> with a quick scan) so this would be a pretty radical departure to start doing.
 >
 >That's partly why I didn't like the idea, and the way you say it makes
 >it an even more powerful reason.
 >
 >> Plus, what are you going to do with a SIGINT? Clean up and then either call
 >> the old handler or exit? Exiting from a library routine is even worse. That's
 >> a prime example generally of bad bad design.
 >
 >For the purpose of academic discussion I think that in the case of
 >getpass() the best thing to do would be to clean up and then call the
 >old handler, or if there was no old handler to just return NULL.
 >
 >> Actaully no. By blocking it creates behavior that I've never seen on any 
 >> other system I've tried to run su on. Everything else either su catches the
 >> signal and fixes stuff or it leaves the terminal in non-echo mode. But, it
 >> doesn't require ^C\n anywhere else I've seen to abort.
 >
 >I don't even remember encountering any version that didn't restore the
 >terminal modes, certainly not of the AT&T derrived variants subsequent
 >to System V Release 3 or so.  I've just experimented with SunOS-5.6 and
 >it seems to restore terminal modes just fine.  Someday I should
 >re-install my 3B2 so it's handy for such tests....
 >
 >-- 
 >							Greg A. Woods
 >
 >+1 416 218-0098      VE3TCP      <gwoods@acm.org>      <robohack!woods>
 >Planix, Inc. <woods@planix.com>; Secrets of the Weird <woods@weird.com>
 >
 >
 >
 >


From: woods@weird.com (Greg A. Woods)
To: gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org,
	tech-userlevel@netbsd.org
Cc:  
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C 
Date: Thu, 24 Aug 2000 16:02:02 -0400 (EDT)

 [ On Friday, August 25, 2000 at 02:19:59 (+1000), Robert Elz wrote: ]
 > Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C 
 >
 >   | My remaining problem with *BSD tty behaviour, which is demonstrated by
 >   | getpass(), is the mis-handling of EOF.  Traditionally I recall ^D
 >   | working at any point on a line.
 > 
 > Never.   Not ever, not even once.   ^D has always meant "end the current
 > input line here, without including the ^D character".   If there's nothing
 > in the line, that results in a 0 length read, which is EOF.  If there's
 > anything already in the line, the program gets it without a \n on the end.
 > 
 > That is truly ancient behaviour (like 5th edition unix, and probably 1st)>

 No doubt you're right.

 My fingers seem to remember otherwise, but they've possibly been
 confused by intervening misadventures....

 -- 
 							Greg A. Woods

 +1 416 218-0098      VE3TCP      <gwoods@acm.org>      <robohack!woods>
 Planix, Inc. <woods@planix.com>; Secrets of the Weird <woods@weird.com>
From: coypu@SDF.ORG
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
Date: Mon, 2 May 2016 12:12:42 +0000

 Amusingly, this is the same bug as bin/50695 (although it was fixed
 for some time between the two bug reports :)

 bin/50695 is already fixed.

 Close please!

State-Changed-From-To: open->closed
State-Changed-By: wiz@NetBSD.org
State-Changed-When: Mon, 02 May 2016 12:18:15 +0000
State-Changed-Why:
Fixed in the meantime, thanks.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.