aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2009-04-23 00:26:07 +1000
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2009-04-23 04:44:46 +1000
commit580765e16aca68132babc09a02b4ea6c220c1988 (patch)
tree9ca6ea68145b108064c6a4c97899bb1ade075428 /shell
parente0ef52d2fabdb4772aaa87a417d841fe58d04e0d (diff)
downloadbusybox-w32-580765e16aca68132babc09a02b4ea6c220c1988.tar.gz
busybox-w32-580765e16aca68132babc09a02b4ea6c220c1988.tar.bz2
busybox-w32-580765e16aca68132babc09a02b4ea6c220c1988.zip
shell/ash: replace shellexec() with shellspawn()
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c5
-rw-r--r--shell/ash_mingw.c148
-rw-r--r--shell/ash_mingw.h3
3 files changed, 156 insertions, 0 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 284f49303..7c97e72e2 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -8453,6 +8453,10 @@ evalcommand(union node *cmd, int flags)
8453 /* Execute the command. */ 8453 /* Execute the command. */
8454 switch (cmdentry.cmdtype) { 8454 switch (cmdentry.cmdtype) {
8455 default: 8455 default:
8456#ifdef __MINGW32__
8457 shellspawn((const char**)argv, path, cmdentry.u.index, varlist.list);
8458 break;
8459#else
8456 /* Fork off a child process if necessary. */ 8460 /* Fork off a child process if necessary. */
8457 if (!(flags & EV_EXIT) || trap[0]) { 8461 if (!(flags & EV_EXIT) || trap[0]) {
8458 INT_OFF; 8462 INT_OFF;
@@ -8467,6 +8471,7 @@ evalcommand(union node *cmd, int flags)
8467 listsetvar(varlist.list, VEXPORT|VSTACK); 8471 listsetvar(varlist.list, VEXPORT|VSTACK);
8468 shellexec(argv, path, cmdentry.u.index); 8472 shellexec(argv, path, cmdentry.u.index);
8469 /* NOTREACHED */ 8473 /* NOTREACHED */
8474#endif
8470 8475
8471 case CMDBUILTIN: 8476 case CMDBUILTIN:
8472 cmdenviron = varlist.list; 8477 cmdenviron = varlist.list;
diff --git a/shell/ash_mingw.c b/shell/ash_mingw.c
index a412b7210..c36973164 100644
--- a/shell/ash_mingw.c
+++ b/shell/ash_mingw.c
@@ -893,3 +893,151 @@ subshell_run()
893 893
894 die("subshell ended unexpectedly"); 894 die("subshell ended unexpectedly");
895} 895}
896
897static int
898tryspawn(const char *cmd, const char **argv, const char * const*envp)
899{
900 struct child_process cp;
901
902 memset(&cp, 0, sizeof(cp));
903
904 cp.env = envp;
905#if ENABLE_FEATURE_SH_STANDALONE
906 if (strchr(cmd, '/') == NULL) {
907 const struct bb_applet *a;
908
909 a = find_applet_by_name(cmd);
910 if (a) {
911 const char **new_argv;
912 const char **argp;
913 int retval;
914
915 for (argp = argv;*argp;argp++);
916 new_argv = xmalloc(sizeof(const char *)*(argp - argv + 2));
917 new_argv[0] = CONFIG_BUSYBOX_EXEC_PATH;
918 memcpy(&new_argv[1], &argv[0], (argp - argv + 1)*sizeof(const char*));
919 cp.argv = new_argv;
920 trace_argv_printf(new_argv, "git-box: applet:");
921 retval = set_exitstatus(run_command(&cp), new_argv, NULL);
922 free(new_argv);
923 return retval;
924 }
925 }
926#endif
927
928 /* FIXME
929 * Need to copy vartab atab cmdtable localvars to the subshell
930 */
931 cp.argv = argv;
932 trace_argv_printf(argv, "git-box: spawn:");
933 return set_exitstatus(run_command(&cp), argv, NULL);
934}
935
936static const char * const*
937shellspawn_getenv(const struct strlist *newvars)
938{
939 struct var **vpp;
940 struct var *vp;
941 const struct strlist *vlp;
942 char **ep;
943 int mask;
944 int on = VEXPORT;
945 int off = VUNSET;
946
947 STARTSTACKSTR(ep);
948 vpp = vartab;
949 mask = on | off;
950 do {
951 for (vp = *vpp; vp; vp = vp->next) {
952 if ((vp->flags & mask) == on) {
953 if (ep == stackstrend())
954 ep = growstackstr();
955 for (vlp = newvars;vlp;vlp = vlp->next)
956 if (varequal(vlp->text, vp->text))
957 break;
958 if (!vlp)
959 *ep++ = (char *) vp->text;
960 }
961 }
962 } while (++vpp < vartab + VTABSIZE);
963 for (vlp = newvars;vlp;vlp = vlp->next) {
964 if (ep == stackstrend())
965 ep = growstackstr();
966 *ep++ = vlp->text;
967 }
968 if (ep == stackstrend())
969 ep = growstackstr();
970 *ep++ = NULL;
971 return grabstackstr(ep);
972}
973
974static int
975shellspawn(const char **argv, const char *path, int idx, struct strlist *varlist)
976{
977 char *cmdname;
978 int e;
979 const char* const* envp;
980
981 /*clearredir(1);*/
982 /*listsetvar(varlist.list, VEXPORT|VSTACK);*/
983 /*envp = listvars(VEXPORT, VUNSET, 0);*/
984 envp = shellspawn_getenv(varlist);
985 if (strchr(argv[0], '/')
986#if ENABLE_FEATURE_SH_STANDALONE
987 || find_applet_by_name(argv[0])
988#endif
989 ) {
990 e = tryspawn(argv[0], argv, envp);
991 } else {
992 e = ENOENT;
993 while ((cmdname = padvance(&path, argv[0])) != NULL) {
994 if (--idx < 0 && pathopt == NULL) {
995 e = tryspawn(cmdname, argv, envp);
996 if (e != -1) break;
997 }
998 stunalloc(cmdname);
999 }
1000 }
1001
1002 if (e == -1) {
1003 e = errno;
1004 switch (e) {
1005 case EACCES:
1006 exitstatus = 126;
1007 break;
1008 case ENOENT:
1009 exitstatus = 127;
1010 break;
1011 default:
1012 exitstatus = 2;
1013 break;
1014 }
1015 ash_msg_and_raise(EXEXEC, "%s: %s", argv[0], errmsg(e, "not found"));
1016 }
1017 return e;
1018}
1019
1020static int set_exitstatus(int val, const char **argv,int *out)
1021{
1022 if (!out)
1023 out = &exitstatus;
1024 switch (val) {
1025 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
1026 if (argv)
1027 ash_msg_and_raise_error("%s: Waitpid on wrong PID",argv[0]);
1028 else
1029 ash_msg_and_raise_error("Waitpid on wrong PID");
1030 break;
1031
1032 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
1033 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
1034 *out = -val + 128;
1035 return 0;
1036
1037 default:
1038 *out = -val;
1039 return 0;
1040 }
1041 return -1;
1042}
1043
diff --git a/shell/ash_mingw.h b/shell/ash_mingw.h
index 658c7dae2..b7c53e036 100644
--- a/shell/ash_mingw.h
+++ b/shell/ash_mingw.h
@@ -12,6 +12,9 @@ static void forkshell_transfer_done(struct forkshell *fs);
12static void forkshell_cleanup(struct forkshell *fs); 12static void forkshell_cleanup(struct forkshell *fs);
13static int forkshell(const char *fp, union node *n, int flags); 13static int forkshell(const char *fp, union node *n, int flags);
14static void subshell_run(); 14static void subshell_run();
15struct strlist;
16static int set_exitstatus(int retval, const char **argv, int *out);
17static int shellspawn(const char **argv, const char *path, int idx, struct strlist *varlist);
15 18
16static int subash_fd = -1; 19static int subash_fd = -1;
17static char subash_entry[16]; 20static char subash_entry[16];