Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Jun 2010 17:33:00 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Jilles Tjoelker <jilles@stack.nl>
Cc:        Ed Schouten <ed@80386.nl>, freebsd-bugs@freebsd.org, Guy Yur <guyyur@gmail.com>, Bruce Evans <brde@optusnet.com.au>, brucec@freebsd.org
Subject:   Re: bin/146916: [patch] sh(1) uses dumb terminal in single-user mode
Message-ID:  <20100603155927.X27626@delplex.bde.org>
In-Reply-To: <20100602204246.GC19165@stack.nl>
References:  <201005281033.o4SAXjlv078228@freefall.freebsd.org> <20100528103618.GJ56080@hoeg.nl> <20100528103830.GK56080@hoeg.nl> <20100528124557.GA50785@stack.nl> <20100529013419.D22843@delplex.bde.org> <20100602204246.GC19165@stack.nl>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 2 Jun 2010, Jilles Tjoelker wrote:

> On Sat, May 29, 2010 at 02:35:34AM +1000, Bruce Evans wrote:
>> On Fri, 28 May 2010, Jilles Tjoelker wrote:
>>> On Fri, May 28, 2010 at 12:38:30PM +0200, Ed Schouten wrote:
>>>> * Ed Schouten <ed@80386.nl> wrote:
>>>>> Why should the shell be responsible for this? Shouldn't we put stuff
>>>>> like this in /sbin/init?
>
>> Of course not.  This belongs in root's dotfiles.  Although login.conf
>> supports setting TERM in 2 different ways, this is so useful that the
>> default login.conf doesn't even provide a bad example of how to use it.
>> Here are 2 bad examples:
>
>> % --- login.conf~	Mon Jun  7 02:19:08 2004
>> % +++ login.conf	Sat May 29 01:31:01 2010
>> % @@ -22,5 +22,6 @@
>> %  	:copyright=/etc/COPYRIGHT:\
>> %  	:welcome=/etc/motd:\
>> % -	:setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES:\
>> % +	:setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES,XXTERM=foo:\
>> % +	:term=bar:\
>> %  	:path=/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin /usr/X11R6/bin ~/bin:\
>> %  	:nologin=/var/run/nologin:\
>
>> Defaulting this in the wrong place login.conf is a littler further
>> away for init than for login, since init only calls setusercontext()
>> with a limited set of flags not including ones that set the environment.
>
> Hmm? login.conf seems the wrong place to set TERM, as the terminal type
> is either already set correctly by whatever is making the connection, or
> it depends on what is connected to the port (dialin has almost died out,

Yes, but but this mistake is already implemented, and my main point is that
this it is less wrong than setting it in init (where it is not set now) or
in login (where it is set now, if the mistake of having it it login.conf is
used).

> and even if it is used, the shell startup file seems a better place for
> setting the terminal type in that case).

I think better in all cases.

>>>> Oh wait. Never mind. I understand the issue. Jilles, what do you think
>>>> about this?
>
>>> Yes, I think init(8) should attempt to pass a suitable TERM to the
>>> single-user shell. This value could be hard-coded (TERM=xterm will
>>> usually be close enough) or taken from /etc/ttys somehow.
>
>> I disagree.  Hard coding it is bad and login.conf bloat belongs in a
>> shell even less than it does in login (login.conf doesn't infect sh
>> now).  Everyone knows that they should edit their dotfiles for things
>> this, but editing /etc/login.conf requires privilege and what it can
>> do is less well known.  However, I'd prefer the default settings to
>> ...

>> The bug seems to be mainly that sh calls libedit before sourcing the
>> dotfiles.
>
> Likely. This may make the code a bit uglier, but I have done a similar
> thing to avoid touching the initial MAIL in non-interactive shells or if
> it is changed in a startup file.
>
>>> I do not plan to revert r206182, putting 'set -o emacs' in root's shell
>>> startup files instead. I did 'set -o emacs' in the shell itself so that
>>> it works even if there are no startup files at all, such as 'make
>>> buildenv' and chroot shells.
>
>> Why not?  Non-interactive shells shouldn't even be initializing libedit.
>
> And they don't. Libedit is only initialized implicitly in interactive
> shells with terminals.
>
>> chroot shells are more interesting.  Is there a single-user mode for
>> chroot shells?  logins in chrooted environments may have other problems
>> if there is no login.conf and/or no dotfiles.
>
> Certainly, but it appears that libedit is not crippled much by a dumb
> TERM.

I now wonder if that is mainly because a subsequent `set -o emacs/vi' in
a dotfile, when placed after a setting of TERM in the same or a previous
dotfile, reinitializes libedit (*).

>> I used to type 'set -E' a lot (this is easier to type than "set -o
>> emacs").  A few years ago I put 'set -o emacs' in /root/.profile.  I
>> thought that this was standard in -current, but it seems that I copied
>> it from a system supplied by obrien@.  This works well, even with TERM
>> uninitialized when it probably shouldn't, and even with TERM initialized
>> wrong when it certainly shouldn't, provided the actual terminal is
>> sufficiently like cons25 (ANSI?).  I keep ignoring the message about
>> the terminal being dumb, and didn't notice before that it is supposed
>> to be non-dumb.  ed works with dumb terminals and using other editors
>> requires more than setting TERM.  The setting of TERM in root's .profile
>> was added in 1994, but apparently never really worked due to this bug.
>> First it was pc3, then unconditionally cons25, then conditionally
>> cons25, then conditionally xterm.
>
> The TERM change is passed to processes started from the shell.

However, the -o settings are not passed to interactive subshells.
Perhaps this is supposed to be handled by dotfiles, but this is not
convenient.  You changed the behaviour in this area recently, so the
behaviour is now to default to emacs mode, and you also changed the
man page to document this in one place, but another place still
emphasizes vi mode and is unclear about the default:

%%%
    Commandline Editing
      When sh is being used interactively from a terminal, the current command
      and the command history (see fc in Built-in Commands) can be edited using
      vi-mode command line editing.  This mode uses commands similar to a sub-
      set of those described in the vi(1) man page.  The command ``set -o vi''
      (or ``set -V'') enables vi-mode editing and places sh into vi insert
      mode.  With vi-mode enabled, sh can be switched between insert mode and
      command mode by typing <ESC>.  Hitting <return> while in command mode
      will pass the line to the shell.
%%%

The first sentence in this seems to say that vi mode is the default, and
the rest emphasizes the rarely used (and now non-default) mode.

I thought that vi mode was the default, but it was broken and/or I didn't
know it well enough to use it.  (I use vi(1) a lot but had never used vi
mode in the shell and prefer to use the arrow keys to the old vi cursor
motion keys hjkl, partly because I don't like modes and the arrow keys
work in all modes.)  Testing it now shows:
(*) `set -o vi' in a dotfile works almost as well as `set -o emacs'.  The
     arrow keys work in vi mode too.  Apparently there is no problem
     with TERM since TERM was set earlier.
- the shell cannot be switched between the modes using <ESC> as claimed in
   the above quote.  There are various bugs: starting always at the shell
   prompt:
   - insert mode to command mode:
     - type "kkkkk<ESC>".  Switches right.
     - type "kkkkk<left arrow>".  This goes left 2 positions and switches to
       command mode.  So the arrow keys don't actually work right.  Apparently
       sh is confused by the ESC at the start of <left arrow>.  This works
       right in vi(1) (starting with "i" to enter insert mode).
     - type "kkkkk<left arrow><ESC>".  The ESC doesn't seem to work, but
       that's because the left arrow messed up the mode.
    - command mode to insert mode: the above quote says that <ESC> works
      for switching _between_ the modes, so it says that switching this way
      works too, but it never did in vi(1) and it doesn't in sh(1) either.
      My fingers haven't read the man page, so they never try this ESC after
      normal entry to command mode, but they do try ESC after left arrow in
      the previous example and are surprised by the mode already being
      command mode.
    - command mode: "kkkk<ESC>p": the `p' inserts garbage (1 k and 3 NULs)
      with a 6 year old sh.  No problem with a 3 month old shell.

>> /etc/skel/dot.profile is more careful about this.
>
> That's /usr/share/skel/dot.profile these days.

Oops, always was.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100603155927.X27626>