From 6c3fd20e67cab2331b1e862c03eeb95a70625454 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 9 Dec 2018 15:15:05 +0000 Subject: win32: special treatment for files with the '.sh' extension Files with the extension '.sh' are considered to be executable. Those that start with a '#!' line will be run using the specified interpreter. If no '#!' is present the script will be run by the shell. When searching for an executable the '.sh' extension will be tested in the same way as the standard extensions understood by spawnve(). '.sh' takes precedence over the standard extensions. --- win32/mingw.c | 19 ++++++++--------- win32/process.c | 63 ++++++++++++++++++++++++++++++++------------------------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/win32/mingw.c b/win32/mingw.c index 162fae45b..d1da4ee84 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -1155,16 +1155,17 @@ int mingw_rmdir(const char *path) return rmdir(path); } -static const char win_suffix[4][4] = { "com", "exe", "bat", "cmd" }; +#define NUMEXT 5 +static const char win_suffix[NUMEXT][4] = { "sh", "com", "exe", "bat", "cmd" }; static int has_win_suffix(const char *name, int start) { - const char *bname = bb_basename(name); - int i, len = strlen(bname); + const char *dot = strrchr(bb_basename(name), '.'); + int i; - if (len > 3 && bname[len-4] == '.') { - for (i=start; i<4; ++i) { - if (!strcasecmp(bname+len-3, win_suffix[i])) { + if (dot != NULL && strlen(dot) < 5) { + for (i=start; ibuf, sizeof(interp->buf)-1); - if (n < 4) /* at least '#!/x' and not error */ - return 0; - - /* - * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia - * relating to '#!'. - */ - if (interp->buf[0] != '#' || interp->buf[1] != '!') - return 0; - interp->buf[n] = '\0'; - if ((t=strchr(interp->buf, '\n')) == NULL) - return 0; - t[1] = '\0'; - - if ((path=strtok(interp->buf+2, " \t\r\n")) == NULL) - return 0; - - t = (char *)bb_basename(path); - if (*t == '\0') - return 0; - - interp->path = path; - interp->name = t; - interp->opts = strtok(NULL, "\r\n"); - - return 1; + while (TRUE) { + n = open_read_close(cmd, interp->buf, sizeof(interp->buf)-1); + if (n < 4) /* at least '#!/x' and not error */ + break; + + /* + * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia + * relating to '#!'. + */ + if (interp->buf[0] != '#' || interp->buf[1] != '!') + break; + interp->buf[n] = '\0'; + if ((t=strchr(interp->buf, '\n')) == NULL) + break; + t[1] = '\0'; + + if ((path=strtok(interp->buf+2, " \t\r\n")) == NULL) + break; + + t = (char *)bb_basename(path); + if (*t == '\0') + break; + + interp->path = path; + interp->name = t; + interp->opts = strtok(NULL, "\r\n"); + return 1; + } + + if (is_suffixed_with_case(cmd, ".sh")) { + interp->path = (char *)DEFAULT_SHELL; + interp->name = (char *)DEFAULT_SHELL_SHORT_NAME; + interp->opts = NULL; + return 1; + } + return 0; } /* -- cgit v1.2.3-55-g6feb