aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-12-09 15:15:05 +0000
committerRon Yorston <rmy@pobox.com>2018-12-09 15:30:35 +0000
commit6c3fd20e67cab2331b1e862c03eeb95a70625454 (patch)
treee91aed5902c7b820549461e1ca4d48f43f0d035d
parent6691b2e8d230e1c85d1a31a752f9f5b6933edbb0 (diff)
downloadbusybox-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.c19
-rw-r--r--win32/process.c63
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
1158static const char win_suffix[4][4] = { "com", "exe", "bat", "cmd" }; 1158#define NUMEXT 5
1159static const char win_suffix[NUMEXT][4] = { "sh", "com", "exe", "bat", "cmd" };
1159 1160
1160static int has_win_suffix(const char *name, int start) 1161static 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
1175int has_bat_suffix(const char *name) 1176int 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
1180int has_exe_suffix(const char *name) 1181int 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/*