From 2bef526331a194da199993ec747598f625a5a9a8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 16 Dec 2011 00:25:17 +0100 Subject: ash: add comment about bash's ENOEXEC handling. No code changes Signed-off-by: Denys Vlasenko --- shell/ash.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 14472cb61..d02b74a4c 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7435,6 +7435,12 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char ** * * That is, do not use $SHELL, user's shell, or /bin/sh; * just call ourselves. + * + * Note that bash reads ~80 chars of the file, and if it sees + * a zero byte before it sees newline, it doesn't try to + * interpret it, but fails with "cannot execute binary file" + * message. For one, it prevents atempts to interpret + * foreign ELF binaries as shell scripts. */ char **ap; char **new; -- cgit v1.2.3-55-g6feb From cda6ea905d448e2a2058b5eb44db50b256659b50 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 16 Dec 2011 00:44:36 +0100 Subject: ash: document bash's exit code too. No code changes Signed-off-by: Denys Vlasenko --- shell/ash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index d02b74a4c..b4ed8e578 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7439,8 +7439,8 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char ** * Note that bash reads ~80 chars of the file, and if it sees * a zero byte before it sees newline, it doesn't try to * interpret it, but fails with "cannot execute binary file" - * message. For one, it prevents atempts to interpret - * foreign ELF binaries as shell scripts. + * message and exit code 126. For one, this prevents attempts + * to interpret foreign ELF binaries as shell scripts. */ char **ap; char **new; -- cgit v1.2.3-55-g6feb From 83f103b30e41ab038e45661df97625f655abe491 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 20 Dec 2011 06:10:35 +0100 Subject: ash: in standalone mode, search in $PATH if /proc/self/exe doesn't exist Signed-off-by: Denys Vlasenko --- shell/ash.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index b4ed8e578..d197fa19a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7471,9 +7471,7 @@ shellexec(char **argv, const char *path, int idx) int e; char **envp; int exerrno; -#if ENABLE_FEATURE_SH_STANDALONE - int applet_no = -1; -#endif + int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ clearredir(/*drop:*/ 1); envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL); @@ -7483,8 +7481,16 @@ shellexec(char **argv, const char *path, int idx) #endif ) { tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp); + if (applet_no >= 0) { + /* We tried execing ourself, but it didn't work. + * Maybe /proc/self/exe doesn't exist? + * Try $PATH search. + */ + goto try_PATH; + } e = errno; } else { + try_PATH: e = ENOENT; while ((cmdname = path_advance(&path, argv[0])) != NULL) { if (--idx < 0 && pathopt == NULL) { -- cgit v1.2.3-55-g6feb From 7ce209b9d4f6053b7e6d07dec66e382bc3614c35 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 15 Jan 2012 22:58:06 +0100 Subject: shell_builtin_read: set cc[VMIN] to 1; lineedit: don't clear c_cc[VINTR] First change fixes "read -n NUM". Apparently poll() won't report data availability if cc[VMIN] > 1 until there are at least cc[VMIN] bytes. function old new delta read_line_input 3885 3877 -8 shell_builtin_read 1097 1087 -10 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-18) Total: -18 bytes Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 15 +++++++++------ shell/shell_common.c | 8 +++++++- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'shell') diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 1390ed62d..460e27fed 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -2206,14 +2206,17 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman #define command command_must_not_be_used new_settings = initial_settings; - new_settings.c_lflag &= ~ICANON; /* unbuffered input */ - /* Turn off echoing and CTRL-C, so we can trap it */ - new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); - /* Hmm, in linux c_cc[] is not parsed if ICANON is off */ + /* ~ICANON: unbuffered input (most c_cc[] are disabled, VMIN/VTIME are enabled) */ + /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */ + /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */ + new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG); + /* reads would block only if < 1 char is available */ new_settings.c_cc[VMIN] = 1; + /* no timeout (reads block forever) */ new_settings.c_cc[VTIME] = 0; - /* Turn off CTRL-C, so we can trap it */ - new_settings.c_cc[VINTR] = _POSIX_VDISABLE; + /* Should be not needed if ISIG is off: */ + /* Turn off CTRL-C */ + /* new_settings.c_cc[VINTR] = _POSIX_VDISABLE; */ tcsetattr_stdin_TCSANOW(&new_settings); #if ENABLE_USERNAME_OR_HOMEDIR diff --git a/shell/shell_common.c b/shell/shell_common.c index bbc22ed34..51c92d60e 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -138,7 +138,13 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), old_tty = tty; if (nchars) { tty.c_lflag &= ~ICANON; - tty.c_cc[VMIN] = nchars < 256 ? nchars : 255; + // Setting it to more than 1 breaks poll(): + // it blocks even if there's data. !?? + //tty.c_cc[VMIN] = nchars < 256 ? nchars : 255; + /* reads would block only if < 1 char is available */ + tty.c_cc[VMIN] = 1; + /* no timeout (reads block forever) */ + tty.c_cc[VTIME] = 0; } if (read_flags & BUILTIN_READ_SILENT) { tty.c_lflag &= ~(ECHO | ECHOK | ECHONL); -- cgit v1.2.3-55-g6feb From 6e9d047c1558f92531ea12b9e3206023ab77cf51 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 4 Feb 2012 21:55:01 +0100 Subject: cttyhack: handle multiple consoles found in sysfs If multiple consoles are found from the sysfs file, cttyhack fails: cttyhack: can't open '/dev/tty0 ttyS0': No such file or directory In such cases take the last one as the kernel will use that one for /dev/console. Signed-off-by: Aaro Koskinen Signed-off-by: Denys Vlasenko --- shell/cttyhack.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'shell') diff --git a/shell/cttyhack.c b/shell/cttyhack.c index 6ff867413..f9b59c263 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c @@ -123,15 +123,22 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) * TIOCGSERIAL check, which assumes that all * serial lines follow /dev/ttySn convention - * which is not always the case. - * Therefore, we use this methos first: + * Therefore, we use this method first: */ int s = open_read_close("/sys/class/tty/console/active", console + 5, sizeof(console) - 5); if (s > 0) { - /* found active console via sysfs (Linux 2.6.38+) - * sysfs string looks like "ttyS0\n" so zap the newline: + char *last; + /* Found active console via sysfs (Linux 2.6.38+). + * It looks like "[tty0 ]ttyS0\n" so zap the newline: */ console[4 + s] = '\0'; + /* If there are multiple consoles, + * take the last one: + */ + last = strrchr(console + 5, ' '); + if (last) + overlapping_strcpy(console + 5, last + 1); break; } -- cgit v1.2.3-55-g6feb