On 2013-03-17 09:56, Denys Vlasenko wrote:
On Friday 15 March 2013 21:54, Joshua Judson Rosen wrote:
I just noticed that trying to source a nonexistent file from a script running
(non-interactively) through ash causes the shell to exit.
Debian's "dash" shell doesn't do this, and versions of bash before 4.2
apparently don't do this even when invoked with "--posix" (it looks like bash's
posix mode was always *supposed to* exit when trying to source non-existent
files, but was perhaps broken; bash's *default mode* doesn't exit when an
attempt is to source a nonexistent file, though).
Looking at the code in busybox, it looks like there's an obvious patch that I
can make (cf. attached) in order to change this behaviour; does this change
make sense upstream? If I do it, should I predicate it on ENABLE_ASH_COMPAT,
or should I just do it unconditionally (I notice that busybox's find_dot_file()
always searches in the current directory, which looks like a bashism)?
The patch is insufficient, it only cathes open errors,
not failures to find the file.
Oops. Well, I did say that it _looked_ like there was an obvious patch....
Attached to this message is a fixed version--which I actually tested.
I've made find_dot_file() just return NULL to dotcmd(), rather than
raising an error that could abort the whole shell.
I've added a new INPUT_NOFILE_NONFATAL flag to the `INPUT_' enums, so that
failure to dot/source a file can still result in an error-message without
making the shell quit. In order to do that, I had to slightly adjust
ash_vmsg_and_raise() so that its behaviour actually matches the descriptive
comments above it.
Is this all acceptable? Should I split the patch up?
--
"Don't be afraid to ask (λf.((λx.xx) (λr.f(rr))))."
diff --git a/shell/ash.c b/shell/ash.c
index fbbdb06..13bea66 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1218,8 +1218,8 @@ ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
TRACE(("\") pid=%d\n", getpid()));
} else
TRACE(("ash_vmsg_and_raise(%d, NULL) pid=%d\n", cond, getpid()));
- if (msg)
#endif
+ if (msg)
ash_vmsg(msg, ap);
flush_stdout_stderr();
@@ -9542,6 +9542,7 @@ breakcmd(int argc UNUSED_PARAM, char **argv)
enum {
INPUT_PUSH_FILE = 1,
INPUT_NOFILE_OK = 2,
+ INPUT_NOFILE_NONFATAL = 4,
};
static smallint checkkwd;
@@ -9982,9 +9983,13 @@ setinputfile(const char *fname, int flags)
INT_OFF;
fd = open(fname, O_RDONLY);
if (fd < 0) {
- if (flags & INPUT_NOFILE_OK)
+ if (!(flags & INPUT_NOFILE_OK))
+ ash_msg("can't open '%s'", fname);
+
+ if (flags & (INPUT_NOFILE_OK | INPUT_NOFILE_NONFATAL))
goto out;
- ash_msg_and_raise_error("can't open '%s'", fname);
+
+ ash_msg_and_raise_error(NULL);
}
if (fd < 10) {
fd2 = copyfd(fd, 10);
@@ -12236,8 +12241,9 @@ find_dot_file(char *name)
}
/* not found in the PATH */
- ash_msg_and_raise_error("%s: not found", name);
- /* NOTREACHED */
+ ash_msg("%s: not found", name);
+
+ return NULL;
}
static int FAST_FUNC
@@ -12246,6 +12252,7 @@ dotcmd(int argc, char **argv)
char *fullname;
struct strlist *sp;
volatile struct shparam saveparam;
+ int inputfd;
for (sp = cmdenviron; sp; sp = sp->next)
setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
@@ -12260,6 +12267,9 @@ dotcmd(int argc, char **argv)
fullname = find_dot_file(argv[1]);
+ if (fullname == NULL)
+ return EXIT_FAILURE;
+
argv += 2;
argc -= 2;
if (argc) { /* argc > 0, argv[0] != NULL */
@@ -12269,7 +12279,10 @@ dotcmd(int argc, char **argv)
shellparam.p = argv;
};
- setinputfile(fullname, INPUT_PUSH_FILE);
+ inputfd = setinputfile(fullname, INPUT_PUSH_FILE | INPUT_NOFILE_NONFATAL);
+ if (inputfd < 0)
+ return EXIT_FAILURE;
+
commandname = fullname;
cmdloop(0);
popfile();
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox