Changeset 3434 in kBuild
- Timestamp:
- Sep 2, 2020 8:19:25 PM (5 years ago)
- Location:
- trunk/src/kash
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/Makefile.kmk
r3433 r3434 44 44 BSD YY_NO_UNISTD_H \ 45 45 SH_DEAL_WITH_CRLF PC_PATH_SEP PC_DRIVE_LETTERS PC_EXE_EXTS EXEC_HASH_BANG_SCRIPT \ 46 KASH_USE_FORKSHELL246 # KASH_USE_FORKSHELL2 47 47 kash_DEFS.os2 = \ 48 48 HAVE_SYS_SIGNAME HAVE_SYSCTL_H HAVE_SETPROGNAME PC_OS2_LIBPATHS \ -
trunk/src/kash/eval.c
r3433 r3434 768 768 } 769 769 770 771 /* 772 * The split up evalcommand code: 773 * evalcommand_out, evalcommand_parent, evalcommand_doit, evalcommand_child 774 */ 770 775 /*int vforked = 0;*/ 776 777 /* Both child and parent exits thru here. */ 778 STATIC void 779 evalcommand_out(shinstance *psh, int flags, char *lastarg, struct stackmark *smarkp) 780 { 781 if (lastarg) 782 /* dsl: I think this is intended to be used to support 783 * '_' in 'vi' command mode during line editing... 784 * However I implemented that within libedit itself. 785 */ 786 setvar(psh, "_", lastarg, 0); 787 popstackmark(psh, smarkp); 788 789 if (eflag(psh) && psh->exitstatus && !(flags & EV_TESTED)) 790 exitshell(psh, psh->exitstatus); 791 } 792 793 794 /* Called if we forkshell(). */ 795 STATIC void 796 evalcommand_parent(shinstance *psh, int flags, char *lastarg, struct stackmark *smarkp, 797 int mode, struct job *jp, int pip[2], struct backcmd *backcmd) 798 { 799 if (mode == FORK_FG) { /* argument to fork */ 800 psh->exitstatus = waitforjob(psh, jp); 801 } else if (mode == FORK_NOJOB) { 802 backcmd->fd = pip[0]; 803 shfile_close(&psh->fdtab, pip[1]); 804 backcmd->jp = jp; 805 } 806 FORCEINTON; 807 808 evalcommand_out(psh, flags, lastarg, smarkp); 809 } 810 811 struct evalcommanddoit 812 { 813 struct cmdentry cmdentry; 814 char *lastarg; 815 const char *path; 816 struct backcmd *backcmd; 817 int flags; 818 int argc; 819 char **argv; 820 struct arglist varlist; 821 struct stackmark smark; 822 }; 823 824 STATIC void 825 evalcommand_doit(shinstance *psh, union node *cmd, struct evalcommanddoit *args) 826 { 827 struct jmploc jmploc; 828 struct jmploc *volatile savehandler; 829 struct localvar *volatile savelocalvars; 830 831 /* This is the child process if a fork occurred. */ 832 /* Execute the command. */ 833 switch (args->cmdentry.cmdtype) { 834 case CMDFUNCTION: { 835 volatile struct shparam saveparam; 836 #ifdef DEBUG 837 trputs(psh, "Shell function: "); trargs(psh, args->argv); 838 #endif 839 redirect(psh, cmd->ncmd.redirect, REDIR_PUSH); 840 saveparam = psh->shellparam; 841 psh->shellparam.malloc = 0; 842 psh->shellparam.reset = 1; 843 psh->shellparam.nparam = args->argc - 1; 844 psh->shellparam.p = args->argv + 1; 845 psh->shellparam.optnext = NULL; 846 INTOFF; 847 savelocalvars = psh->localvars; 848 psh->localvars = NULL; 849 INTON; 850 if (setjmp(jmploc.loc)) { 851 if (psh->exception == EXSHELLPROC) { 852 freeparam(psh, (volatile struct shparam *) 853 &saveparam); 854 } else { 855 freeparam(psh, &psh->shellparam); 856 psh->shellparam = saveparam; 857 } 858 poplocalvars(psh); 859 psh->localvars = savelocalvars; 860 psh->handler = savehandler; 861 longjmp(psh->handler->loc, 1); 862 } 863 savehandler = psh->handler; 864 psh->handler = &jmploc; 865 listmklocal(psh, args->varlist.list, 0); 866 /* stop shell blowing its stack */ 867 if (++psh->funcnest > 1000) 868 error(psh, "too many nested function calls"); 869 evaltree(psh, args->cmdentry.u.func, args->flags & EV_TESTED); 870 psh->funcnest--; 871 INTOFF; 872 poplocalvars(psh); 873 psh->localvars = savelocalvars; 874 freeparam(psh, &psh->shellparam); 875 psh->shellparam = saveparam; 876 psh->handler = savehandler; 877 popredir(psh); 878 INTON; 879 if (psh->evalskip == SKIPFUNC) { 880 psh->evalskip = 0; 881 psh->skipcount = 0; 882 } 883 if (args->flags & EV_EXIT) 884 exitshell(psh, psh->exitstatus); 885 break; 886 } 887 888 case CMDBUILTIN: 889 case CMDSPLBLTIN: { 890 volatile int temp_path = 0; 891 char *volatile savecmdname; 892 volatile int e; 893 int mode; 894 #ifdef DEBUG 895 trputs(psh, "builtin command: "); trargs(psh, args->argv); 896 #endif 897 mode = (args->cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH; 898 if (args->flags == EV_BACKCMD) { 899 psh->memout.nleft = 0; 900 psh->memout.nextc = psh->memout.buf; 901 psh->memout.bufsize = 64; 902 mode |= REDIR_BACKQ; 903 } 904 e = -1; 905 savehandler = psh->handler; 906 savecmdname = psh->commandname; 907 psh->handler = &jmploc; 908 if (!setjmp(jmploc.loc)) { 909 /* We need to ensure the command hash table isn't 910 * corruped by temporary PATH assignments. 911 * However we must ensure the 'local' command works! 912 */ 913 if (args->path != pathval(psh) && (args->cmdentry.u.bltin == hashcmd || 914 args->cmdentry.u.bltin == typecmd)) { 915 savelocalvars = psh->localvars; 916 psh->localvars = 0; 917 mklocal(psh, args->path - 5 /* PATH= */, 0); 918 temp_path = 1; 919 } else 920 temp_path = 0; 921 redirect(psh, cmd->ncmd.redirect, mode); 922 923 /* exec is a special builtin, but needs this list... */ 924 psh->cmdenviron = args->varlist.list; 925 /* we must check 'readonly' flag for all builtins */ 926 listsetvar(psh, args->varlist.list, 927 args->cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET); 928 psh->commandname = args->argv[0]; 929 /* initialize nextopt */ 930 psh->argptr = args->argv + 1; 931 psh->optptr = NULL; 932 /* and getopt */ 933 #if 0 /** @todo fix getop usage! */ 934 #if defined(__FreeBSD__) || defined(__EMX__) || defined(__APPLE__) 935 optreset = 1; 936 optind = 1; 937 #else 938 optind = 0; /* init */ 939 #endif 940 #endif 941 942 psh->exitstatus = args->cmdentry.u.bltin(psh, args->argc, args->argv); 943 } else { 944 e = psh->exception; 945 psh->exitstatus = e == EXINT ? SIGINT + 128 : 946 e == EXEXEC ? psh->exerrno : 2; 947 } 948 psh->handler = savehandler; 949 output_flushall(psh); 950 psh->out1 = &psh->output; 951 psh->out2 = &psh->errout; 952 freestdout(psh); 953 if (temp_path) { 954 poplocalvars(psh); 955 psh->localvars = savelocalvars; 956 } 957 psh->cmdenviron = NULL; 958 if (e != EXSHELLPROC) { 959 psh->commandname = savecmdname; 960 if (args->flags & EV_EXIT) 961 exitshell(psh, psh->exitstatus); 962 } 963 if (e != -1) { 964 if ((e != EXERROR && e != EXEXEC) 965 || args->cmdentry.cmdtype == CMDSPLBLTIN) 966 exraise(psh, e); 967 FORCEINTON; 968 } 969 if (args->cmdentry.u.bltin != execcmd) 970 popredir(psh); 971 if (args->flags == EV_BACKCMD) { 972 args->backcmd->buf = psh->memout.buf; 973 args->backcmd->nleft = (int)(psh->memout.nextc - psh->memout.buf); 974 psh->memout.buf = NULL; 975 } 976 break; 977 } 978 979 default: { 980 struct strlist *sp; 981 char **envp; 982 #ifdef DEBUG 983 trputs(psh, "normal command: "); trargs(psh, args->argv); 984 #endif 985 clearredir(psh, psh->vforked); 986 redirect(psh, cmd->ncmd.redirect, psh->vforked ? REDIR_VFORK : 0); 987 if (!psh->vforked) 988 for (sp = args->varlist.list ; sp ; sp = sp->next) 989 setvareq(psh, sp->text, VEXPORT|VSTACK); 990 envp = environment(psh); 991 shellexec(psh, args->argv, envp, args->path, args->cmdentry.u.index, psh->vforked); 992 break; 993 } 994 } 995 996 evalcommand_out(psh, args->flags, args->lastarg, &args->smark); 997 } 771 998 772 999 /* … … 777 1004 evalcommand(shinstance *psh, union node *cmd, int flags, struct backcmd *backcmd) 778 1005 { 779 struct stackmark smark; 780 union node *argp; 781 struct arglist arglist; 782 struct arglist varlist; 1006 struct evalcommanddoit args; 783 1007 char **argv; 784 1008 int argc; 785 char **envp; 1009 1010 union node *argp; 786 1011 int numvars; 1012 struct arglist arglist; 787 1013 struct strlist *sp; 788 int mode = 0;789 int pip[2];790 struct cmdentry cmdentry;791 struct job *jp;792 struct jmploc jmploc;793 struct jmploc *volatile savehandler;794 char *volatile savecmdname;795 volatile struct shparam saveparam;796 struct localvar *volatile savelocalvars;797 volatile int e;798 char *lastarg;799 1014 const char *path = pathval(psh); 800 volatile int temp_path;801 #if __GNUC__802 /* Try avoid longjmp clobbering */803 (void) &argv;804 (void) &argc;805 (void) &lastarg;806 (void) &flags;807 (void) &path;808 (void) &mode;809 #endif810 1015 811 1016 psh->vforked = 0; 812 1017 /* First expand the arguments. */ 813 1018 TRACE((psh, "evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); 814 setstackmark(psh, & smark);1019 setstackmark(psh, &args.smark); 815 1020 psh->back_exitstatus = 0; 816 1021 … … 835 1040 836 1041 /* Now do the initial 'name=value' ones we skipped above */ 837 varlist.lastp = &varlist.list;1042 args.varlist.lastp = &args.varlist.list; 838 1043 for (argp = cmd->ncmd.args ; numvars > 0 && argp ; argp = argp->narg.next, numvars--) 839 expandarg(psh, argp, & varlist, EXP_VARTILDE);840 * varlist.lastp = NULL;1044 expandarg(psh, argp, &args.varlist, EXP_VARTILDE); 1045 *args.varlist.lastp = NULL; 841 1046 842 1047 argc = 0; 843 1048 for (sp = arglist.list ; sp ; sp = sp->next) 844 1049 argc++; 845 argv = stalloc(psh, sizeof (char *) * (argc + 1)); 1050 args.argc = argc; 1051 args.argv = argv = stalloc(psh, sizeof (char *) * (argc + 1)); 846 1052 847 1053 for (sp = arglist.list ; sp ; sp = sp->next) { … … 850 1056 } 851 1057 *argv = NULL; 852 lastarg = NULL;1058 args.lastarg = NULL; 853 1059 if (iflag(psh) && psh->funcnest == 0 && argc > 0) 854 lastarg = argv[-1];1060 args.lastarg = argv[-1]; 855 1061 argv -= argc; 856 1062 … … 859 1065 char sep = 0; 860 1066 out2str(psh, ps4val(psh)); 861 for (sp = varlist.list ; sp ; sp = sp->next) {1067 for (sp = args.varlist.list ; sp ; sp = sp->next) { 862 1068 if (sep != 0) 863 1069 outc(sep, &psh->errout); … … 877 1083 /* Now locate the command. */ 878 1084 if (argc == 0) { 879 cmdentry.cmdtype = CMDSPLBLTIN;880 cmdentry.u.bltin = bltincmd;1085 args.cmdentry.cmdtype = CMDSPLBLTIN; 1086 args.cmdentry.u.bltin = bltincmd; 881 1087 } else { 882 1088 static const char PATH[] = "PATH="; … … 887 1093 * is present 888 1094 */ 889 for (sp = varlist.list; sp; sp = sp->next)1095 for (sp = args.varlist.list; sp; sp = sp->next) 890 1096 if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) 891 1097 path = sp->text + sizeof(PATH) - 1; … … 893 1099 do { 894 1100 int argsused, use_syspath; 895 find_command(psh, argv[0], & cmdentry, cmd_flags, path);896 if ( cmdentry.cmdtype == CMDUNKNOWN) {1101 find_command(psh, argv[0], &args.cmdentry, cmd_flags, path); 1102 if (args.cmdentry.cmdtype == CMDUNKNOWN) { 897 1103 psh->exitstatus = 127; 898 1104 flushout(&psh->errout); 899 goto out; 1105 evalcommand_out(psh, flags, args.lastarg, &args.smark); 1106 return; 900 1107 } 901 1108 902 1109 /* implement the 'command' builtin here */ 903 if ( cmdentry.cmdtype != CMDBUILTIN ||904 cmdentry.u.bltin != bltincmd)1110 if (args.cmdentry.cmdtype != CMDBUILTIN || 1111 args.cmdentry.u.bltin != bltincmd) 905 1112 break; 906 1113 cmd_flags |= DO_NOFUNC; … … 908 1115 if (argsused == 0) { 909 1116 /* use 'type' builting to display info */ 910 cmdentry.u.bltin = typecmd;1117 args.cmdentry.u.bltin = typecmd; 911 1118 break; 912 1119 } … … 916 1123 path = syspath(psh) + 5; 917 1124 } while (argc != 0); 918 if ( cmdentry.cmdtype == CMDSPLBLTIN && cmd_flags & DO_NOFUNC)1125 if (args.cmdentry.cmdtype == CMDSPLBLTIN && cmd_flags & DO_NOFUNC) 919 1126 /* posix mandates that 'command <splbltin>' act as if 920 1127 <splbltin> was a normal builtin */ 921 cmdentry.cmdtype = CMDBUILTIN;1128 args.cmdentry.cmdtype = CMDBUILTIN; 922 1129 } 923 1130 924 1131 /* Fork off a child process if necessary. */ 925 1132 if (cmd->ncmd.backgnd 926 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) 927 || ((flags & EV_BACKCMD) != 0 928 && ((cmdentry.cmdtype != CMDBUILTIN && cmdentry.cmdtype != CMDSPLBLTIN) 929 || cmdentry.u.bltin == dotcmd 930 || cmdentry.u.bltin == evalcmd))) { 1133 || (args.cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) 1134 || ( (flags & EV_BACKCMD) != 0 1135 && ( (args.cmdentry.cmdtype != CMDBUILTIN && args.cmdentry.cmdtype != CMDSPLBLTIN) 1136 || args.cmdentry.u.bltin == dotcmd 1137 || args.cmdentry.u.bltin == evalcmd))) { 1138 struct job *jp; 1139 int pip[2]; 1140 int mode; 931 1141 INTOFF; 932 1142 jp = makejob(psh, cmd, 1); … … 937 1147 error(psh, "Pipe call failed"); 938 1148 } 939 #ifdef DO_SHAREDVFORK 940 /* It is essential that if DO_SHAREDVFORK is defined that the 941 * child's address space is actually shared with the parent as 942 * we rely on this. 943 */ 944 if (cmdentry.cmdtype == CMDNORMAL) { 945 pid_t pid; 946 947 savelocalvars = psh->localvars; 948 psh->localvars = NULL; 949 psh->vforked = 1; 950 switch (pid = vfork()) { 951 case -1: 952 TRACE((psh, "Vfork failed, errno=%d\n", errno)); 953 INTON; 954 error(psh, "Cannot vfork"); 955 break; 956 case 0: 957 /* Make sure that exceptions only unwind to 958 * after the vfork(2) 959 */ 960 if (setjmp(jmploc.loc)) { 961 if (psh->exception == EXSHELLPROC) { 962 /* We can't progress with the vfork, 963 * so, set vforked = 2 so the parent 964 * knows, and _exit(); 965 */ 966 psh->vforked = 2; 967 sh__exit(psh, 0); 968 } else { 969 sh__exit(psh, psh->exerrno); 970 } 971 } 972 savehandler = psh->handler; 973 psh->handler = &jmploc; 974 listmklocal(psh, varlist.list, VEXPORT | VNOFUNC); 975 forkchild(psh, jp, cmd, mode, psh->vforked); 976 break; 977 default: 978 psh->handler = savehandler; /* restore from vfork(2) */ 979 poplocalvars(psh); 980 psh->localvars = savelocalvars; 981 if (psh->vforked == 2) { 982 psh->vforked = 0; 983 984 (void)sh_waitpid(psh, pid, NULL, 0); 985 /* We need to progress in a normal fork fashion */ 986 goto normal_fork; 987 } 988 psh->vforked = 0; 989 forkparent(psh, jp, cmd, mode, pid); 990 goto parent; 991 } 992 } else { 993 normal_fork: 994 #endif 995 if (forkshell(psh, jp, cmd, mode) != 0) 996 goto parent; /* at end of routine */ 997 FORCEINTON; 998 #ifdef DO_SHAREDVFORK 999 } 1000 #endif 1149 if (forkshell(psh, jp, cmd, mode) != 0) { 1150 evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp, pip, backcmd); 1151 return; /* at end of routine */ 1152 } 1153 1001 1154 if (flags & EV_BACKCMD) { 1002 1155 if (!psh->vforked) { … … 1009 1162 } 1010 1163 flags |= EV_EXIT; 1011 } 1012 1013 /* This is the child process if a fork occurred. */ 1014 /* Execute the command. */ 1015 switch (cmdentry.cmdtype) { 1016 case CMDFUNCTION: 1017 #ifdef DEBUG 1018 trputs(psh, "Shell function: "); trargs(psh, argv); 1019 #endif 1020 redirect(psh, cmd->ncmd.redirect, REDIR_PUSH); 1021 saveparam = psh->shellparam; 1022 psh->shellparam.malloc = 0; 1023 psh->shellparam.reset = 1; 1024 psh->shellparam.nparam = argc - 1; 1025 psh->shellparam.p = argv + 1; 1026 psh->shellparam.optnext = NULL; 1027 INTOFF; 1028 savelocalvars = psh->localvars; 1029 psh->localvars = NULL; 1030 INTON; 1031 if (setjmp(jmploc.loc)) { 1032 if (psh->exception == EXSHELLPROC) { 1033 freeparam(psh, (volatile struct shparam *) 1034 &saveparam); 1035 } else { 1036 freeparam(psh, &psh->shellparam); 1037 psh->shellparam = saveparam; 1038 } 1039 poplocalvars(psh); 1040 psh->localvars = savelocalvars; 1041 psh->handler = savehandler; 1042 longjmp(psh->handler->loc, 1); 1043 } 1044 savehandler = psh->handler; 1045 psh->handler = &jmploc; 1046 listmklocal(psh, varlist.list, 0); 1047 /* stop shell blowing its stack */ 1048 if (++psh->funcnest > 1000) 1049 error(psh, "too many nested function calls"); 1050 evaltree(psh, cmdentry.u.func, flags & EV_TESTED); 1051 psh->funcnest--; 1052 INTOFF; 1053 poplocalvars(psh); 1054 psh->localvars = savelocalvars; 1055 freeparam(psh, &psh->shellparam); 1056 psh->shellparam = saveparam; 1057 psh->handler = savehandler; 1058 popredir(psh); 1059 INTON; 1060 if (psh->evalskip == SKIPFUNC) { 1061 psh->evalskip = 0; 1062 psh->skipcount = 0; 1063 } 1064 if (flags & EV_EXIT) 1065 exitshell(psh, psh->exitstatus); 1066 break; 1067 1068 case CMDBUILTIN: 1069 case CMDSPLBLTIN: 1070 #ifdef DEBUG 1071 trputs(psh, "builtin command: "); trargs(psh, argv); 1072 #endif 1073 mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH; 1074 if (flags == EV_BACKCMD) { 1075 psh->memout.nleft = 0; 1076 psh->memout.nextc = psh->memout.buf; 1077 psh->memout.bufsize = 64; 1078 mode |= REDIR_BACKQ; 1079 } 1080 e = -1; 1081 savehandler = psh->handler; 1082 savecmdname = psh->commandname; 1083 psh->handler = &jmploc; 1084 if (!setjmp(jmploc.loc)) { 1085 /* We need to ensure the command hash table isn't 1086 * corruped by temporary PATH assignments. 1087 * However we must ensure the 'local' command works! 1088 */ 1089 if (path != pathval(psh) && (cmdentry.u.bltin == hashcmd || 1090 cmdentry.u.bltin == typecmd)) { 1091 savelocalvars = psh->localvars; 1092 psh->localvars = 0; 1093 mklocal(psh, path - 5 /* PATH= */, 0); 1094 temp_path = 1; 1095 } else 1096 temp_path = 0; 1097 redirect(psh, cmd->ncmd.redirect, mode); 1098 1099 /* exec is a special builtin, but needs this list... */ 1100 psh->cmdenviron = varlist.list; 1101 /* we must check 'readonly' flag for all builtins */ 1102 listsetvar(psh, varlist.list, 1103 cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET); 1104 psh->commandname = argv[0]; 1105 /* initialize nextopt */ 1106 psh->argptr = argv + 1; 1107 psh->optptr = NULL; 1108 /* and getopt */ 1109 #if 0 /** @todo fix getop usage! */ 1110 #if defined(__FreeBSD__) || defined(__EMX__) || defined(__APPLE__) 1111 optreset = 1; 1112 optind = 1; 1113 #else 1114 optind = 0; /* init */ 1115 #endif 1116 #endif 1117 1118 psh->exitstatus = cmdentry.u.bltin(psh, argc, argv); 1119 } else { 1120 e = psh->exception; 1121 psh->exitstatus = e == EXINT ? SIGINT + 128 : 1122 e == EXEXEC ? psh->exerrno : 2; 1123 } 1124 psh->handler = savehandler; 1125 output_flushall(psh); 1126 psh->out1 = &psh->output; 1127 psh->out2 = &psh->errout; 1128 freestdout(psh); 1129 if (temp_path) { 1130 poplocalvars(psh); 1131 psh->localvars = savelocalvars; 1132 } 1133 psh->cmdenviron = NULL; 1134 if (e != EXSHELLPROC) { 1135 psh->commandname = savecmdname; 1136 if (flags & EV_EXIT) 1137 exitshell(psh, psh->exitstatus); 1138 } 1139 if (e != -1) { 1140 if ((e != EXERROR && e != EXEXEC) 1141 || cmdentry.cmdtype == CMDSPLBLTIN) 1142 exraise(psh, e); 1143 FORCEINTON; 1144 } 1145 if (cmdentry.u.bltin != execcmd) 1146 popredir(psh); 1147 if (flags == EV_BACKCMD) { 1148 backcmd->buf = psh->memout.buf; 1149 backcmd->nleft = (int)(psh->memout.nextc - psh->memout.buf); 1150 psh->memout.buf = NULL; 1151 } 1152 break; 1153 1154 default: 1155 #ifdef DEBUG 1156 trputs(psh, "normal command: "); trargs(psh, argv); 1157 #endif 1158 clearredir(psh, psh->vforked); 1159 redirect(psh, cmd->ncmd.redirect, psh->vforked ? REDIR_VFORK : 0); 1160 if (!psh->vforked) 1161 for (sp = varlist.list ; sp ; sp = sp->next) 1162 setvareq(psh, sp->text, VEXPORT|VSTACK); 1163 envp = environment(psh); 1164 shellexec(psh, argv, envp, path, cmdentry.u.index, psh->vforked); 1165 break; 1166 } 1167 goto out; 1168 1169 parent: /* parent process gets here (if we forked) */ 1170 if (mode == FORK_FG) { /* argument to fork */ 1171 psh->exitstatus = waitforjob(psh, jp); 1172 } else if (mode == FORK_NOJOB) { 1173 backcmd->fd = pip[0]; 1174 shfile_close(&psh->fdtab, pip[1]); 1175 backcmd->jp = jp; 1176 } 1177 FORCEINTON; 1178 1179 out: 1180 if (lastarg) 1181 /* dsl: I think this is intended to be used to support 1182 * '_' in 'vi' command mode during line editing... 1183 * However I implemented that within libedit itself. 1184 */ 1185 setvar(psh, "_", lastarg, 0); 1186 popstackmark(psh, &smark); 1187 1188 if (eflag(psh) && psh->exitstatus && !(flags & EV_TESTED)) 1189 exitshell(psh, psh->exitstatus); 1164 1165 args.backcmd = backcmd; 1166 args.flags = flags; 1167 args.path = path; 1168 evalcommand_doit(psh, cmd, &args); 1169 } 1170 else { 1171 args.backcmd = backcmd; 1172 args.flags = flags; 1173 args.path = path; 1174 evalcommand_doit(psh, cmd, &args); 1175 } 1190 1176 } 1191 1177 -
trunk/src/kash/jobs.c
r3433 r3434 84 84 STATIC void cmdlist(shinstance *, union node *, int); 85 85 STATIC void cmdputs(shinstance *, const char *); 86 #ifdef KASH_USE_FORKSHELL2 87 static int forkparent(shinstance *psh, struct job *jp, union node *n, int mode, pid_t pid); 88 static void forkchild(shinstance *psh, struct job *jp, union node *n, int mode, int vforked); 89 #endif 86 90 87 91 … … 780 784 */ 781 785 786 #ifndef KASH_USE_FORKSHELL2 782 787 int 783 788 forkshell(shinstance *psh, struct job *jp, union node *n, int mode) … … 799 804 } 800 805 } 801 806 #else /* KASH_USE_FORKSHELL2 */ 802 807 int forkshell2(struct shinstance *psh, struct job *jp, union node *n, int mode, 803 808 int (*child)(struct shinstance *, void *, union node *), … … 825 830 return -1; /* won't get here */ 826 831 } 827 832 #endif 833 834 #ifdef KASH_USE_FORKSHELL2 835 static 836 #endif 828 837 int 829 838 forkparent(shinstance *psh, struct job *jp, union node *n, int mode, pid_t pid) … … 853 862 } 854 863 864 #ifdef KASH_USE_FORKSHELL2 865 static 866 #endif 855 867 void 856 868 forkchild(shinstance *psh, struct job *jp, union node *n, int mode, int vforked) -
trunk/src/kash/jobs.h
r3433 r3434 95 95 union node; 96 96 struct job *makejob(struct shinstance *, union node *, int); 97 int forkshell(struct shinstance *, struct job *, union node *, int);98 97 #ifdef KASH_USE_FORKSHELL2 99 98 int forkshell2(struct shinstance *, struct job *, union node *, int, 100 99 int (*child)(struct shinstance *, void *, union node *), 101 100 union node *, void *, size_t); 102 #endif 101 #else 102 int forkshell(struct shinstance *, struct job *, union node *, int); 103 103 void forkchild(struct shinstance *, struct job *, union node *, int, int); 104 104 int forkparent(struct shinstance *, struct job *, union node *, int, pid_t); 105 #endif 105 106 int waitforjob(struct shinstance *, struct job *); 106 107 int stoppedjobs(struct shinstance *); -
trunk/src/kash/shinstance.h
r3409 r3434 180 180 181 181 /* eval.c */ 182 int vforked; 182 int vforked; /** @todo remove this */ 183 183 184 184 /* expand.c */
Note:
See TracChangeset
for help on using the changeset viewer.