Bash Version: 4.0
Patch Level: 28
Release Status: release
Description:
bash executes command without newline
This bug was assumed to be fixed with the intregation
of bash-4.0, but it is still reproducible.
Repeat-By:
- login to a system
- if your login shell is not bash, then enter bash shell
- do 'su -'
- once you are a super user, create a new user
- now, su to this new user.
- type 'date > /tmp/date.txt' (don't issue a carriage return)
- close the gnome-terminal/dtterm window
- login to the system again and ls /tmp/date.txt, and you
will find that the file is created.
Fix:
The above problem only occurs when the parent process is running su(1M) program. So, when this process running su is sent a HUP signal from another window, then init process becomes the parent of the bash process. This is because bash belonged to an orphaned process group and was immediately parented to the init process.
At this point, if the window running su program was closed, whatever characters that were accumulated in the buffer of the interactive bash program was sent for an I/O to the underlying file mapped to the stream. The problem here is that bash should check its buffer for a newline character, which is transferred by the tty driver (when it reads <CR>). If no newline was found, then the contents of the buffer should be discarded. The problem is with readline_internal_char()/readline_internal_charloop() which calls rl_read_key to fetch a key including pending input.
If the key is EOF, and length of the input line (i.e rl_end) was not 0, then this key is converted to a newline. Also rl_newline() should be called only if a newline has been detected
webrev location:
http://cr.opensolaris.org/~as158974/sfwnv/
This is not a bug. Shells dating back to v7 have interpreted EOF as a
token delimiter equivalent to newline. Posix standardizes this behavior.
Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU ch...@case.edu http://cnswww.cns.cwru.edu/~chet/
I had gone through the standard and found this:
There is one place in the "Token Recognition" section in the "Shell
Command Language" says:
-------------
If the end of input is recognized, the current token shall be delimited.
If there is no current token, the end-of-input indicator shall be
returned as the token.
-------------
So, the EOF is a delimitor and the token probably can be processed.
However, we are being hung up. There is another section in the
General Terminal interface says:
-------------
Modem Disconnect
If a modem disconnect is detected by the terminal interface for a
controlling terminal, and if CLOCAL is not set in the c_cflag field for
the terminal (see Control Modes ), the SIGHUP signal shall be sent to
the controlling process for which the terminal is the controlling
terminal. Unless other arrangements have been made, this shall cause the
controlling process to terminate (see exit()). Any subsequent read from
the terminal device shall return the value of zero, indicating
end-of-file; see read(). Thus, processes that read a terminal file and
test for end-of-file can terminate appropriately after a disconnect. If
the EIO condition as specified in read() also exists, it is unspecified
whether on EOF condition or [EIO] is returned. Any subsequent write() to
the terminal device shall return -1, with errno set to [EIO], until the
device is closed.
--------------
So the controlling process would be able to be terminated by SIGHUP.
Since EOF would be the consequence of a disconnect, I'd rather feel
that it would be okay to discard the pending characters. In fact,
if shell is reading terminal in ICANON mode, the pending characters
are discarded in the terminal driver when disconnected (ie read(2)
wouldn't read the pending characters but read(2) returns 0).
Could you let me know the rationale on the 'standardized' behavior that
you pointed and which exist in Posix ?
thanks
-Arindam
> Chet
>