Subject: Re: bin/10879: su does not reset terminal settings after Ctrl-C
To: None <gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org,>
From: Robert Elz <kre@munnari.OZ.AU>
List: netbsd-bugs
Date: 08/25/2000 02:19:59
    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