From d0dd867542cda649a3b31a2f5d915a959c49ba24 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 14 Dec 2014 22:37:12 -0600 Subject: [PATCH] Fix problem where trying to run a program on a nonexistent volume gave an unescapable 'insert disk' dialog. This also gives more sensible error messages when trying to execute nonexistent files. --- libbb/exec.gno.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/libbb/exec.gno.c b/libbb/exec.gno.c index 686457f27..6e455fe8b 100644 --- a/libbb/exec.gno.c +++ b/libbb/exec.gno.c @@ -140,6 +140,29 @@ int execve(const char *path, char *const *argv, char *const *envp) if (buildEnv(envp) != 0) goto error_ret; } + + /* Check that the file exists before we try to _execve it. + * We must do this now, because if we give _execve a path on + * a non-existent volume, it will put up an unescapable GS/OS + * dialog asking for that volume to be inserted. */ + pathlen = strlen(path); + path_gs = malloc(strlen(path) + offsetof(GSString255, text) + 1); + if (path_gs == NULL) { + errno = ENOMEM; + goto error_ret; + } + strcpy(path_gs->text, path); + path_gs->length = pathlen; + fileInfoRec.pCount = 4; + fileInfoRec.pathname = path_gs; + GetFileInfoGS(&fileInfoRec); + /* If it's not an EXEC file, error out. */ + if (toolerror()) { + errno = ENOENT; + goto error_ret; + } + free(path_gs); + path_gs = NULL; /* This will close the close-on-exec fds even if the exec * ultimately fails. This should be OK for our uses, because @@ -153,26 +176,11 @@ int execve(const char *path, char *const *argv, char *const *envp) /* If _execve kernel call failed, consider trying to execute * the file as a script. */ - pathlen = strlen(path); - path_gs = malloc(strlen(path) + offsetof(GSString255, text) + 1); - if (path_gs == NULL) { - errno = ENOMEM; - goto error_ret; - } - strcpy(path_gs->text, path); - path_gs->length = pathlen; - fileInfoRec.pCount = 4; - fileInfoRec.pathname = path_gs; - GetFileInfoGS(&fileInfoRec); - /* If it's not an EXEC file, error out. */ - if (toolerror() || fileInfoRec.fileType != 0xB0 || fileInfoRec.auxType != 0x0006) { + if (fileInfoRec.fileType != 0xB0 || fileInfoRec.auxType != 0x0006) { errno = EACCES; goto error_ret; } - free(path_gs); - path_gs = NULL; - script_fd = open(path, O_RDONLY); if (script_fd == -1) goto error_ret;