aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-09-04 12:47:03 +0100
committerRon Yorston <rmy@pobox.com>2024-09-04 12:47:03 +0100
commitcbfa58d56c3ca59538bf23e30105ce27ed5ef948 (patch)
tree29c88182b7ff243931d5956121e23cd877112b16
parent13a2b505b3fd7abcb4b4516d6745df870d7aee64 (diff)
downloadbusybox-w32-cbfa58d56c3ca59538bf23e30105ce27ed5ef948.tar.gz
busybox-w32-cbfa58d56c3ca59538bf23e30105ce27ed5ef948.tar.bz2
busybox-w32-cbfa58d56c3ca59538bf23e30105ce27ed5ef948.zip
ash: optimise running of scripts (2)
Commit 4b7b4a960 (ash: optimise running of scripts) avoided creation of a process when running a script. There's another case where we can do the same: if the script is being run from a FS_SHELLEXEC shell. - Check the necessary conditions for this to happen. - Allocate two extra slots in the argv array for FS_SHELLEXEC. - Set the index of the script file in the argv array. Without this the test 'pidof this' failed because the command name hadn't been correctly set. Adds 80-96 bytes.
-rw-r--r--include/mingw.h1
-rw-r--r--libbb/appletlib.c7
-rw-r--r--shell/ash.c26
3 files changed, 26 insertions, 8 deletions
diff --git a/include/mingw.h b/include/mingw.h
index ed7884e39..65940b40b 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -667,3 +667,4 @@ enum {
667 ADMIN_ENABLED = 2 667 ADMIN_ENABLED = 2
668}; 668};
669int elevation_state(void); 669int elevation_state(void);
670void set_interp(int i) FAST_FUNC;
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 97dfb3df8..1ff7fe6c8 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -394,6 +394,13 @@ bool re_execed;
394static int interp = 0; 394static int interp = 0;
395char bb_comm[COMM_LEN]; 395char bb_comm[COMM_LEN];
396char bb_command_line[128]; 396char bb_command_line[128];
397
398# if ENABLE_FEATURE_SH_STANDALONE
399void FAST_FUNC set_interp(int i)
400{
401 interp = i;
402}
403# endif
397#endif 404#endif
398 405
399 406
diff --git a/shell/ash.c b/shell/ash.c
index 2e4181b3f..d9a7bee83 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9099,6 +9099,7 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9099#endif 9099#endif
9100{ 9100{
9101#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE 9101#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE
9102 struct forkshell *fs = (struct forkshell *)sticky_mem_start;
9102 interp_t interp; 9103 interp_t interp;
9103#endif 9104#endif
9104#if ENABLE_FEATURE_SH_STANDALONE 9105#if ENABLE_FEATURE_SH_STANDALONE
@@ -9106,7 +9107,6 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9106# if ENABLE_PLATFORM_MINGW32 9107# if ENABLE_PLATFORM_MINGW32
9107 /* Treat all applets as NOEXEC, including the shell itself if 9108 /* Treat all applets as NOEXEC, including the shell itself if
9108 * this is a FS_SHELLEXEC shell. */ 9109 * this is a FS_SHELLEXEC shell. */
9109 struct forkshell *fs = (struct forkshell *)sticky_mem_start;
9110 if (applet_main[applet_no] != ash_main || 9110 if (applet_main[applet_no] != ash_main ||
9111 (fs && fs->fpid == FS_SHELLEXEC)) { 9111 (fs && fs->fpid == FS_SHELLEXEC)) {
9112 run_noexec: 9112 run_noexec:
@@ -9152,21 +9152,28 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9152 add_win32_extension((char *)cmd); 9152 add_win32_extension((char *)cmd);
9153 9153
9154# if ENABLE_FEATURE_SH_STANDALONE 9154# if ENABLE_FEATURE_SH_STANDALONE
9155 /* If nfpath is non-NULL, evalcommand() has determined this 9155 /* If nfpath is non-NULL evalcommand() has determined this
9156 * command doesn't need a fork(). If the command is a script 9156 * command doesn't need a fork(). Even it's NULL we can
9157 * with an interpreter which is an applet we can run it as if 9157 * possibly avoid a fork if this is a FS_SHELLEXEC shell. */
9158 * it were a noexec applet. */ 9158 if (nfpath == NULL && (fs && fs->fpid == FS_SHELLEXEC))
9159 nfpath = pathval();
9160
9161 /* If nfpath is non-NULL and the command is a script with an
9162 * interpreter which is an applet, we can run it as if it
9163 * were a noexec applet. */
9159 if (nfpath && parse_interpreter(cmd, &interp)) { 9164 if (nfpath && parse_interpreter(cmd, &interp)) {
9160 applet_no = find_applet_by_name_for_sh(interp.name, nfpath); 9165 applet_no = find_applet_by_name_for_sh(interp.name, nfpath);
9161 if (applet_no >= 0) { 9166 if (applet_no >= 0) {
9162 argv[0] = (char *)cmd; 9167 argv[0] = (char *)cmd;
9163 /* evalcommand() has added two elements before argv */ 9168 /* evalcommand()/spawn_forkshell() add two elements before argv */
9164 if (interp.opts) { 9169 if (interp.opts) {
9165 argv--; 9170 argv--;
9166 argv[0] = (char *)interp.opts; 9171 argv[0] = (char *)interp.opts;
9167 } 9172 }
9168 argv--; 9173 argv--;
9169 cmd = argv[0] = (char *)interp.name; 9174 cmd = argv[0] = (char *)interp.name;
9175 /* Identify the index of the script file in argv */
9176 set_interp(1 + (interp.opts != NULL));
9170 goto run_noexec; 9177 goto run_noexec;
9171 } 9178 }
9172 } 9179 }
@@ -16842,7 +16849,8 @@ argv_size(struct datasize ds, char **p)
16842 ds.funcstringsize += align_len(*p); 16849 ds.funcstringsize += align_len(*p);
16843 p++; 16850 p++;
16844 } 16851 }
16845 ds.funcblocksize += sizeof(char *); 16852 // Allow two extra elements for tryexec().
16853 ds.funcblocksize += 3 * sizeof(char *);
16846 } 16854 }
16847 return ds; 16855 return ds;
16848} 16856}
@@ -16856,6 +16864,8 @@ argv_copy(char **p)
16856#endif 16864#endif
16857 16865
16858 if (p) { 16866 if (p) {
16867 // Allow two extra elements for tryexec().
16868 funcblock = (char *) funcblock + 2 * sizeof(char *);
16859 while (*p) { 16869 while (*p) {
16860 new = funcblock; 16870 new = funcblock;
16861 funcblock = (char *) funcblock + sizeof(char *); 16871 funcblock = (char *) funcblock + sizeof(char *);
@@ -16866,7 +16876,7 @@ argv_copy(char **p)
16866 new = funcblock; 16876 new = funcblock;
16867 funcblock = (char *) funcblock + sizeof(char *); 16877 funcblock = (char *) funcblock + sizeof(char *);
16868 *new = NULL; 16878 *new = NULL;
16869 return start; 16879 return start + 2;
16870 } 16880 }
16871 return NULL; 16881 return NULL;
16872} 16882}