diff options
author | Ron Yorston <rmy@pobox.com> | 2018-12-09 15:15:05 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-12-09 15:30:35 +0000 |
commit | 6c3fd20e67cab2331b1e862c03eeb95a70625454 (patch) | |
tree | e91aed5902c7b820549461e1ca4d48f43f0d035d | |
parent | 6691b2e8d230e1c85d1a31a752f9f5b6933edbb0 (diff) | |
download | busybox-w32-6c3fd20e67cab2331b1e862c03eeb95a70625454.tar.gz busybox-w32-6c3fd20e67cab2331b1e862c03eeb95a70625454.tar.bz2 busybox-w32-6c3fd20e67cab2331b1e862c03eeb95a70625454.zip |
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.
-rw-r--r-- | win32/mingw.c | 19 | ||||
-rw-r--r-- | 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) | |||
1155 | return rmdir(path); | 1155 | return rmdir(path); |
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | static const char win_suffix[4][4] = { "com", "exe", "bat", "cmd" }; | 1158 | #define NUMEXT 5 |
1159 | static const char win_suffix[NUMEXT][4] = { "sh", "com", "exe", "bat", "cmd" }; | ||
1159 | 1160 | ||
1160 | static int has_win_suffix(const char *name, int start) | 1161 | static int has_win_suffix(const char *name, int start) |
1161 | { | 1162 | { |
1162 | const char *bname = bb_basename(name); | 1163 | const char *dot = strrchr(bb_basename(name), '.'); |
1163 | int i, len = strlen(bname); | 1164 | int i; |
1164 | 1165 | ||
1165 | if (len > 3 && bname[len-4] == '.') { | 1166 | if (dot != NULL && strlen(dot) < 5) { |
1166 | for (i=start; i<4; ++i) { | 1167 | for (i=start; i<NUMEXT; ++i) { |
1167 | if (!strcasecmp(bname+len-3, win_suffix[i])) { | 1168 | if (!strcasecmp(dot+1, win_suffix[i])) { |
1168 | return 1; | 1169 | return 1; |
1169 | } | 1170 | } |
1170 | } | 1171 | } |
@@ -1174,7 +1175,7 @@ static int has_win_suffix(const char *name, int start) | |||
1174 | 1175 | ||
1175 | int has_bat_suffix(const char *name) | 1176 | int has_bat_suffix(const char *name) |
1176 | { | 1177 | { |
1177 | return has_win_suffix(name, 2); | 1178 | return has_win_suffix(name, 3); |
1178 | } | 1179 | } |
1179 | 1180 | ||
1180 | int has_exe_suffix(const char *name) | 1181 | int has_exe_suffix(const char *name) |
@@ -1200,8 +1201,8 @@ int add_win32_extension(char *p) | |||
1200 | int i, len = strlen(p); | 1201 | int i, len = strlen(p); |
1201 | 1202 | ||
1202 | p[len] = '.'; | 1203 | p[len] = '.'; |
1203 | for (i=0; i<4; ++i) { | 1204 | for (i=0; i<NUMEXT; ++i) { |
1204 | memcpy(p+len+1, win_suffix[i], 4); | 1205 | strcpy(p+len+1, win_suffix[i]); |
1205 | if (file_is_executable(p)) | 1206 | if (file_is_executable(p)) |
1206 | return TRUE; | 1207 | return TRUE; |
1207 | } | 1208 | } |
diff --git a/win32/process.c b/win32/process.c index 20e73baee..60fea01ad 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -57,33 +57,42 @@ parse_interpreter(const char *cmd, interp_t *interp) | |||
57 | char *path, *t; | 57 | char *path, *t; |
58 | int n; | 58 | int n; |
59 | 59 | ||
60 | n = open_read_close(cmd, interp->buf, sizeof(interp->buf)-1); | 60 | while (TRUE) { |
61 | if (n < 4) /* at least '#!/x' and not error */ | 61 | n = open_read_close(cmd, interp->buf, sizeof(interp->buf)-1); |
62 | return 0; | 62 | if (n < 4) /* at least '#!/x' and not error */ |
63 | 63 | break; | |
64 | /* | 64 | |
65 | * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia | 65 | /* |
66 | * relating to '#!'. | 66 | * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia |
67 | */ | 67 | * relating to '#!'. |
68 | if (interp->buf[0] != '#' || interp->buf[1] != '!') | 68 | */ |
69 | return 0; | 69 | if (interp->buf[0] != '#' || interp->buf[1] != '!') |
70 | interp->buf[n] = '\0'; | 70 | break; |
71 | if ((t=strchr(interp->buf, '\n')) == NULL) | 71 | interp->buf[n] = '\0'; |
72 | return 0; | 72 | if ((t=strchr(interp->buf, '\n')) == NULL) |
73 | t[1] = '\0'; | 73 | break; |
74 | 74 | t[1] = '\0'; | |
75 | if ((path=strtok(interp->buf+2, " \t\r\n")) == NULL) | 75 | |
76 | return 0; | 76 | if ((path=strtok(interp->buf+2, " \t\r\n")) == NULL) |
77 | 77 | break; | |
78 | t = (char *)bb_basename(path); | 78 | |
79 | if (*t == '\0') | 79 | t = (char *)bb_basename(path); |
80 | return 0; | 80 | if (*t == '\0') |
81 | 81 | break; | |
82 | interp->path = path; | 82 | |
83 | interp->name = t; | 83 | interp->path = path; |
84 | interp->opts = strtok(NULL, "\r\n"); | 84 | interp->name = t; |
85 | 85 | interp->opts = strtok(NULL, "\r\n"); | |
86 | return 1; | 86 | return 1; |
87 | } | ||
88 | |||
89 | if (is_suffixed_with_case(cmd, ".sh")) { | ||
90 | interp->path = (char *)DEFAULT_SHELL; | ||
91 | interp->name = (char *)DEFAULT_SHELL_SHORT_NAME; | ||
92 | interp->opts = NULL; | ||
93 | return 1; | ||
94 | } | ||
95 | return 0; | ||
87 | } | 96 | } |
88 | 97 | ||
89 | /* | 98 | /* |