Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 238419 - app-shells/dash: closing error stream (erroneously), where no /dev/tty is existant
Summary: app-shells/dash: closing error stream (erroneously), where no /dev/tty is exi...
Status: RESOLVED NEEDINFO
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All All
: High normal (vote)
Assignee: Gentoo Linux bug wranglers
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-09-22 20:33 UTC by David
Modified: 2008-09-24 08:47 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David 2008-09-22 20:33:40 UTC
In the package app-shells/dash, in the function setjobctl (src/jobs.c) there exists code to gracefully handle situations, where no /dev/tty node exists. However in such situations the file descriptor 2 will be closed unintentionally (after mapping it to a higher file descriptor). This is probably a bug as a lot of routines (e.g. in output.c rely on the open file descriptors 0-2) The consequence is that on systems where /dev/tty is missing, no shell prompt can be seen (dash uses the error stream to output the prompt). For comparison: The busybox shell "sh" neither does close fd 2 when /dev/tty is missing, nor does it output the prompt on fd=2, so it is robust in that sense.

The solution would be to only close a file descriptor, if it is greater than 2 (file redir.c):
# diff redir_old.c redir.c
410c410,411
<               close(from);
---
>               if(from > 2 )
>                       close(from);


Here some straces for clarification:

strace for current dash (/dev/tty does not exist):
--------------------------------------------------
[...]
open("/dev/tty", O_RDWR)                = -1 ENOENT (No such file or directory)
ioctl(2, SNDCTL_TMR_TIMEBASE or TCGETS, {B115200 opost isig icanon echo ...}) = 0
fcntl(2, F_DUPFD, 10)                   = 10
close(2)                                = 0    <<== This should not happen!
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
ioctl(10, TIOCGPGRP, [859])             = 0
getpgrp()                               = 859
rt_sigaction(SIGTSTP, NULL, {SIG_DFL}, 8) = 0
rt_sigaction(SIGTSTP, {SIG_IGN}, NULL, 8) = 0
rt_sigaction(SIGTTOU, NULL, {SIG_IGN}, 8) = 0
rt_sigaction(SIGTTIN, NULL, {SIG_IGN}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_DFL}, NULL, 8) = 0
setpgid(0, 860)                         = 0
ioctl(10, TIOCSPGRP, [860])             = 0
wait4(-1, 0xbfca82e8, WNOHANG|WUNTRACED, NULL) = -1 ECHILD (No child processes)
write(2, "# ", 2)                       = -1 EBADF (Bad file descriptor)  <== Writing the prompt fails.
read(0, 0x80595e0, 4096)                = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---

strace for busybox-sh (/dev/tty) does not exist):
-------------------------------------------------
[...]
open("/dev/tty", O_RDWR|O_LARGEFILE)    = -1 ENOENT (No such file or directory)
ioctl(2, SNDCTL_TMR_TIMEBASE or TCGETS, {B115200 opost isig icanon echo ...}) = 0
fcntl64(2, F_DUPFD, 10)                 = 10
close(-1)                               = -1 EBADF (Bad file descriptor)
fcntl64(10, F_SETFD, FD_CLOEXEC)        = 0
ioctl(10, TIOCGPGRP, [861])             = 0
getpgrp()                               = 861
rt_sigaction(SIGTSTP, NULL, {SIG_DFL}, 8) = 0
rt_sigaction(SIGTSTP, {SIG_IGN}, NULL, 8) = 0
rt_sigaction(SIGTTOU, NULL, {SIG_IGN}, 8) = 0
rt_sigaction(SIGTTIN, NULL, {SIG_IGN}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_DFL}, NULL, 8) = 0
setpgid(0, 862)                         = 0
ioctl(10, TIOCSPGRP, [862])             = 0
brk(0x80fa000)                          = 0x80fa000
ioctl(2147483647, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfb21cc4) = -1 EBADF (Bad file descriptor)
brk(0x80fb000)                          = 0x80fb000
wait4(-1, 0xbfb21d98, WNOHANG|WUNTRACED, NULL) = -1 ECHILD (No child processes)
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B115200 opost isig icanon echo ...}) = 0
open("/root/.ash_history", O_RDONLY|O_LARGEFILE) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfb21c34) = -1 ENOTTY (Inappropriate ioctl for device)
read(3, "echo Hallo >&2\necho Hallo\ndash\nd"..., 4096) = 156
close(3)                                = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B115200 opost -isig -icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B115200 opost -isig -icanon -echo ...}) = 0
rt_sigaction(SIGWINCH, {0x80cb7cd, [WINCH], SA_RESTORER|SA_RESTART, 0xb7eef338}, {SIG_DFL}, 8) = 0
ioctl(0, TIOCGWINSZ, {ws_row=0, ws_col=0, ws_xpixel=0, ws_ypixel=0}) = 0
geteuid()                               = 0
open("/etc/passwd", O_RDONLY|O_LARGEFILE) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfb21bc4) = -1 ENOTTY (Inappropriate ioctl for device)
read(3, "root:x:0:0:root:/root:/bin/sh\nbi"..., 4096) = 515
close(3)                                = 0
getcwd("/", 192)                        = 2
geteuid()                               = 0
write(1, "/ # ", 4/ # )                     = 4
read(0, "\4", 1)                        = 1


strace of current dash startup with /dev/tty
--------------------------------------------
[...]
open("/dev/tty", O_RDWR)                = 3
fcntl(3, F_DUPFD, 10)                   = 10
close(3)                                = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
ioctl(10, TIOCGPGRP, [894])             = 0
getpgrp()                               = 894
rt_sigaction(SIGTSTP, NULL, {SIG_DFL}, 8) = 0
rt_sigaction(SIGTSTP, {SIG_IGN}, NULL, 8) = 0
rt_sigaction(SIGTTOU, NULL, {SIG_IGN}, 8) = 0
rt_sigaction(SIGTTIN, NULL, {SIG_IGN}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_DFL}, NULL, 8) = 0
setpgid(0, 895)                         = 0
ioctl(10, TIOCSPGRP, [895])             = 0
wait4(-1, 0xbfc3a838, WNOHANG|WUNTRACED, NULL) = -1 ECHILD (No child processes)
write(2, "root@ellipseC $ ", 16root@ellipseC $ )        = 16
read(0, 0x80595e0, 4096)                = ? ERESTARTSYS (To be restarted)
[...]



Reproducible: Always

Steps to Reproduce:
1. Install app-shells/dash on a system, where no /dev/tty exists (e.g. Gentoo embedded)
2.
3.

Actual Results:  
The prompt cannot be seen. (Everything else works)

Expected Results:  
Prompt should be shown
Comment 1 Peter Alfredsen (RETIRED) gentoo-dev 2008-09-22 20:54:18 UTC
We are going to copy upstream on this bugreport and if they acknowledge a bug, we will import the patch. Please tell us which version of dash you're using.
Comment 2 David 2008-09-24 08:47:11 UTC
Sorry for the delay, the verion is 0.5.4.11