Changeset 3438 in kBuild
- Timestamp:
- Sep 9, 2020 8:01:39 PM (4 years ago)
- Location:
- trunk/src/kash
- Files:
-
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/Makefile.kmk
r3434 r3438 26 26 SUB_DEPTH = ../.. 27 27 include $(KBUILD_PATH)/subheader.kmk 28 29 KASH_WIN_FORKED_MODE = 1 28 30 29 31 # … … 35 37 kash_ASTOOL = YASM 36 38 kash_DEFS = lint SHELL SMALL 39 if "$(KBUILD_TARGET)" != "win" || defined(KASH_WIN_FORKED_MODE) 37 40 kash_DEFS += SH_FORKED_MODE 41 endif 38 42 kash_DEFS.debug = DEBUG=2 39 43 kash_DEFS.haiku = BSD … … 44 48 BSD YY_NO_UNISTD_H \ 45 49 SH_DEAL_WITH_CRLF PC_PATH_SEP PC_DRIVE_LETTERS PC_EXE_EXTS EXEC_HASH_BANG_SCRIPT \ 46 #KASH_USE_FORKSHELL250 KASH_USE_FORKSHELL2 47 51 kash_DEFS.os2 = \ 48 52 HAVE_SYS_SIGNAME HAVE_SYSCTL_H HAVE_SETPROGNAME PC_OS2_LIBPATHS \ … … 67 71 endif 68 72 kash_CFLAGS.win.amd64 = -GS- 73 ifdef KASH_WIN_FORKED_MODE 69 74 kash_LDFLAGS.win = -DYNAMICBASE:NO 75 endif 70 76 kash_SOURCES = \ 71 77 main.c \ … … 125 131 $(kash_0_OUTDIR)/sys_signame.c \ 126 132 strsignal.c \ 127 strlcpy.c \ 133 strlcpy.c 134 ifdef KASH_WIN_FORKED_MODE 135 kash_SOURCES.win += \ 128 136 shfork-win.c \ 129 137 shforkA-win.asm 138 endif 130 139 131 140 kash_INTERMEDIATES = \ -
trunk/src/kash/alias.c
r2290 r3438 61 61 STATIC struct alias **hashalias(shinstance *, char *); 62 62 63 #ifndef SH_FORKED_MODE 64 void 65 subshellinitalias(shinstance *psh, shinstance *inherit) 66 { 67 unsigned i; 68 unsigned left = inherit->aliases; 69 if (left == 0) 70 return; 71 for (i = 0; i < K_ELEMENTS(inherit->atab); i++) 72 { 73 struct alias const *asrc = inherit->atab[i]; 74 if (asrc) 75 { 76 struct alias **ppdst = &psh->atab[i]; 77 do 78 { 79 if (*asrc->name) 80 { 81 struct alias *dst = (struct alias *)ckmalloc(psh, sizeof(*dst)); 82 dst->name = savestr(psh, asrc->name); 83 dst->val = savestr(psh, asrc->val); 84 dst->flag = asrc->flag; 85 *ppdst = dst; 86 ppdst = &dst->next; 87 } 88 left--; 89 asrc = asrc->next; 90 } while (asrc); 91 *ppdst = NULL; 92 if (left == 0) 93 break; 94 } 95 } 96 } 97 #endif /* !SH_FORKED_MODE */ 98 63 99 STATIC 64 100 void … … 111 147 ap->next = *app; 112 148 *app = ap; 149 psh->aliases++; 113 150 INTON; 114 151 } … … 138 175 ckfree(psh, ap->val); 139 176 ckfree(psh, ap); 177 psh->aliases--; 140 178 INTON; 141 179 } -
trunk/src/kash/alias.h
r1233 r3438 44 44 }; 45 45 46 #ifndef SH_FORKED_MODE 47 void subshellinitalias(shinstance *, shinstance *); 48 #endif 46 49 struct alias *lookupalias(struct shinstance *, char *, int); 47 50 char *get_alias_text(struct shinstance *, char *); -
trunk/src/kash/bltin/kill.c
r3409 r3438 61 61 killcmd(shinstance *psh, int argc, char *argv[]) 62 62 { 63 int errors, numsig , pid;63 int errors, numsig; 64 64 char *ep; 65 65 … … 131 131 132 132 for (errors = 0; argc; argc--, argv++) { 133 if (*argv[0] == '%') { 134 pid = getjobpgrp(psh, *argv); 133 const char * const strpid = argv[0]; 134 shpid pid; 135 if (*strpid == '%') { 136 pid = getjobpgrp(psh, strpid); 135 137 if (pid == 0) { 136 sh_warnx(psh, "illegal job id: %s", *argv);138 sh_warnx(psh, "illegal job id: %s", strpid); 137 139 errors = 1; 138 140 continue; 139 141 } 140 142 } else { 141 pid = strtol(*argv, &ep, 10); 142 if (!**argv || *ep) { 143 sh_warnx(psh, "illegal process id: %s", *argv); 143 #if !defined(SH_FORKED_MODE) && defined(_MSC_VER) 144 pid = _strtoi64(strpid, &ep, 10); 145 #elif !defined(SH_FORKED_MODE) 146 pid = strtoll(strpid, &ep, 10); 147 #else 148 pid = strtol(strpid, &ep, 10); 149 #endif 150 if (!*strpid || *ep) { 151 sh_warnx(psh, "illegal process id: %s", strpid); 144 152 errors = 1; 145 153 continue; … … 147 155 } 148 156 if (sh_kill(psh, pid, numsig) == -1) { 149 sh_warn(psh, "%s", *argv);157 sh_warn(psh, "%s", strpid); 150 158 errors = 1; 151 159 } -
trunk/src/kash/error.c
r2651 r3438 165 165 TRACEV((psh, msg, va2)); 166 166 va_end(va2); 167 TRACE((psh, "\") pid=% d\n", sh_getpid(psh)));167 TRACE((psh, "\") pid=%" SHPID_PRI "\n", sh_getpid(psh))); 168 168 } else 169 TRACE((psh, "exverror(%d, NULL) pid=% d\n", cond, sh_getpid(psh)));169 TRACE((psh, "exverror(%d, NULL) pid=%" SHPID_PRI "\n", cond, sh_getpid(psh))); 170 170 #endif 171 171 if (msg) -
trunk/src/kash/eval.c
r3437 r3438 225 225 psh->displayhist = 1; /* show history substitutions done with fc */ 226 226 #endif 227 TRACE((psh, "pid % d, evaltree(%p: %d, %d) called\n",227 TRACE((psh, "pid %" SHPID_PRI ", evaltree(%p: %d, %d) called\n", 228 228 sh_getpid(psh), n, n->type, flags)); 229 229 switch (n->type) { … … 458 458 args.backgnd = backgnd; 459 459 forkshell2(psh, jp, n, backgnd ? FORK_BG : FORK_FG, 460 460 evalsubshell_child, n, &args, sizeof(args), NULL); 461 461 } 462 462 #else … … 578 578 args.pip[1] = pip[1]; 579 579 forkshell2(psh, jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG, 580 580 evalpipe_child, lp->n, &args, sizeof(args), NULL); 581 581 } 582 582 #else … … 677 677 args.pip[1] = pip[1]; 678 678 forkshell2(psh, jp, n, FORK_NOJOB, 679 679 evalbackcmd_child, n, &args, sizeof(args), NULL); 680 680 } 681 681 #else … … 894 894 volatile int temp_path = 0; 895 895 char *volatile savecmdname; 896 int volatile savecmdnamemalloc; 896 897 volatile int e; 897 898 int mode; … … 909 910 savehandler = psh->handler; 910 911 savecmdname = psh->commandname; 912 savecmdnamemalloc = psh->commandnamemalloc; 911 913 psh->handler = &jmploc; 912 914 if (!setjmp(jmploc.loc)) { … … 930 932 listsetvar(psh, args->varlist.list, 931 933 args->cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET); 934 psh->commandnamemalloc = 0; 932 935 psh->commandname = args->argv[0]; 933 936 /* initialize nextopt */ … … 962 965 if (e != EXSHELLPROC) { 963 966 psh->commandname = savecmdname; 967 psh->commandnamemalloc = savecmdnamemalloc; 964 968 if (args->flags & EV_EXIT) 965 969 exitshell(psh, psh->exitstatus); 966 970 } 971 if (savecmdnamemalloc) 972 sh_free(psh, savecmdname); 967 973 if (e != -1) { 968 974 if ((e != EXERROR && e != EXEXEC) -
trunk/src/kash/exec.c
r3437 r3438 45 45 #include <stdio.h> 46 46 #include <stdlib.h> 47 #include <stddef.h> 47 48 48 49 /* … … 112 113 extern char *const parsekwd[]; 113 114 115 #ifndef SH_FORKED_MODE 116 void 117 subshellinitexec(shinstance *psh, shinstance *inherit) 118 { 119 unsigned i; 120 for (i = 0; i < K_ELEMENTS(inherit->cmdtable); i++) { 121 struct tblentry const *csrc = inherit->cmdtable[i]; 122 if (!csrc) { 123 } else { 124 struct tblentry **ppdst = &psh->cmdtable[i]; 125 do 126 { 127 size_t const namesize = strlen(csrc->cmdname) + 1; 128 size_t const entrysize = offsetof(struct tblentry, cmdname) + namesize; 129 struct tblentry *dst = (struct tblentry *)ckmalloc(psh, entrysize); 130 memcpy(dst->cmdname, csrc->cmdname, namesize); 131 dst->rehash = csrc->rehash; 132 dst->cmdtype = csrc->cmdtype; 133 134 dst->param.func = NULL; 135 switch (csrc->cmdtype) { 136 case CMDUNKNOWN: 137 case CMDNORMAL: 138 dst->param.index = csrc->param.index; 139 break; 140 case CMDFUNCTION: 141 dst->param.func = copyfunc(psh, csrc->param.func); /** @todo optimize function allocations */ 142 break; 143 case CMDBUILTIN: 144 case CMDSPLBLTIN: 145 dst->param.bltin = csrc->param.bltin; 146 break; 147 } 148 149 *ppdst = dst; 150 ppdst = &dst->next; 151 152 csrc = csrc->next; 153 } while (csrc); 154 *ppdst = NULL; 155 } 156 } 157 158 psh->builtinloc = inherit->builtinloc; 159 } 160 #endif /* SH_FORKED_MODE */ 161 162 114 163 /* 115 164 * Exec a program. Never returns. If you change this routine, you may … … 222 271 initshellproc(psh); 223 272 setinputfile(psh, cmd, 0); 273 if (psh->commandnamemalloc) { 274 sh_free(psh, psh->commandname); 275 psh->commandnamemalloc = 0; 276 } 277 if (psh->arg0malloc) 278 sh_free(psh, psh->arg0); 224 279 psh->commandname = psh->arg0 = savestr(psh, argv[0]); 280 psh->arg0malloc = 1; 225 281 #ifdef EXEC_HASH_BANG_SCRIPT 226 282 pgetc(psh); pungetc(psh); /* fill up input buffer */ -
trunk/src/kash/exec.h
r3435 r3438 71 71 #endif 72 72 73 #ifndef SH_FORKED_MODE 74 void subshellinitexec(shinstance *, shinstance *); 75 #endif 73 76 SH_NORETURN_1 void shellexec(struct shinstance *, char **, char **, const char *, int) SH_NORETURN_2; 74 77 char *padvance(struct shinstance *, const char **, const char *); -
trunk/src/kash/expand.c
r2653 r3438 89 89 90 90 STATIC void argstr(shinstance *, char *, int); 91 STATIC void expari(shinstance *, int); 91 92 STATIC char *exptilde(shinstance *, char *, int); 92 93 STATIC void expbackq(shinstance *, union node *, int, int); … … 106 107 STATIC int pmatch(char *, char *, int); 107 108 STATIC char *cvtnum(shinstance *, int, char *); 109 STATIC char *cvtnum64(shinstance *, KI64, char *); 108 110 109 111 /* … … 343 345 * evaluate, place result in (backed up) result, adjust string position. 344 346 */ 345 void347 STATIC void 346 348 expari(shinstance *psh, int flag) 347 349 { … … 869 871 switch (*name) { 870 872 case '$': 873 #ifndef SH_FORKED_MODE 874 psh->expdest = cvtnum64(psh, psh->rootpid, psh->expdest); 875 break; 876 #else 871 877 num = psh->rootpid; 872 878 goto numvar; 879 #endif 873 880 case '?': 874 881 num = psh->exitstatus; … … 876 883 case '#': 877 884 num = psh->shellparam.nparam; 878 goto numvar;879 case '!':880 num = psh->backgndpid;881 885 numvar: 882 886 psh->expdest = cvtnum(psh, num, psh->expdest); 883 887 break; 888 case '!': 889 #ifndef SH_FORKED_MODE 890 psh->expdest = cvtnum64(psh, psh->backgndpid, psh->expdest); 891 break; 892 #else 893 num = psh->backgndpid; 894 goto numvar; 895 #endif 884 896 case '-': 885 897 for (i = 0; psh->optlist[i].name; i++) { … … 1561 1573 } 1562 1574 1575 STATIC char * 1576 cvtnum64(shinstance *psh, KI64 num, char *buf) 1577 { 1578 char temp[32]; 1579 int neg = num < 0; 1580 char *p = temp + 31; 1581 1582 temp[31] = '\0'; 1583 1584 do { 1585 *--p = num % 10 + '0'; 1586 } while ((num /= 10) != 0); 1587 1588 if (neg) 1589 *--p = '-'; 1590 1591 while (*p) 1592 STPUTC(psh, *p++, buf); 1593 return buf; 1594 } 1595 1563 1596 /* 1564 1597 * Do most of the work for wordexp(3). -
trunk/src/kash/expand.h
r1233 r3438 65 65 void expandhere(struct shinstance *, union node *, int); 66 66 void expandarg(struct shinstance *, union node *, struct arglist *, int); 67 void expari(struct shinstance *, int);68 67 int patmatch(struct shinstance *, char *, char *, int); 69 68 void rmescapes(struct shinstance *, char *); -
trunk/src/kash/jobs.c
r3437 r3438 64 64 #include "error.h" 65 65 #include "mystring.h" 66 #include "init.h" 66 67 #include "shinstance.h" 67 68 … … 79 80 STATIC void freejob(shinstance *, struct job *); 80 81 STATIC struct job *getjob(shinstance *, const char *, int); 81 STATIC intdowait(shinstance *, int, struct job *);82 STATIC intwaitproc(shinstance *, int, struct job *, int *);82 STATIC shpid dowait(shinstance *, int, struct job *); 83 STATIC shpid waitproc(shinstance *, int, struct job *, int *); 83 84 STATIC void cmdtxt(shinstance *, union node *); 84 85 STATIC void cmdlist(shinstance *, union node *, int); 85 86 STATIC void cmdputs(shinstance *, const char *); 87 STATIC shpid forkparent(shinstance *psh, struct job *jp, union node *n, int mode, shpid pid); 88 STATIC void forkchild(shinstance *psh, shpid pgrp, union node *n, int mode); 86 89 #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); 90 # ifndef SH_FORKED_MODE 91 struct forkshell2args 92 { 93 shinstance *psh; 94 int mode; 95 shpid pgrp; /**< The forkchild() pgrp argument (-1 if not in group). */ 96 union node *n; 97 void *argp; /**< Points to child callback data following this structure. */ 98 int (* child)(shinstance *, union node *, void *); 99 struct stackmark smark; /* do we need this? */ 100 }; 101 static int forkshell2_thread(shinstance *psh, void *argp); 102 # endif 89 103 #endif 90 104 … … 328 342 if (mode & SHOW_PGID) { 329 343 /* just output process (group) id of pipeline */ 330 outfmt(out, "% ld\n", (long)jp->ps->pid);344 outfmt(out, "%" SHPID_PRI "\n", jp->ps->pid); 331 345 return; 332 346 } … … 382 396 col = strlen(s); 383 397 if (mode & SHOW_PID) { 384 fmtstr(s + col, 16, "% ld ", (long)ps->pid);398 fmtstr(s + col, 16, "%" SHPID_PRI " ", ps->pid); 385 399 col += strlen(s + col); 386 400 } … … 475 489 int jobno; 476 490 struct job *jp; 477 int silent = 0, gotpid; 491 int silent = 0; 492 shpid gotpid; 478 493 479 494 TRACE((psh, "showjobs(%x) called\n", mode)); … … 607 622 jp = getjob(psh, *psh->argptr, 0); 608 623 for (i = 0 ; i < jp->nprocs ; ) { 609 out1fmt(psh, "% ld", (long)jp->ps[i].pid);624 out1fmt(psh, "%" SHPID_PRI, jp->ps[i].pid); 610 625 out1c(psh, ++i < jp->nprocs ? ' ' : '\n'); 611 626 } … … 613 628 } 614 629 615 int 630 shpid 616 631 getjobpgrp(shinstance *psh, const char *name) 617 632 { … … 785 800 786 801 #ifndef KASH_USE_FORKSHELL2 787 int 802 shpid 788 803 forkshell(shinstance *psh, struct job *jp, union node *n, int mode) 789 804 { … … 798 813 return -1; /* won't get here */ 799 814 case 0: 800 forkchild(psh, jp , n, mode);815 forkchild(psh, jp == NULL || jp->nprocs == 0 ? -1 : jp->ps[0].pid, n, mode); 801 816 return 0; 802 817 default: … … 805 820 } 806 821 #else /* KASH_USE_FORKSHELL2 */ 807 int forkshell2(struct shinstance *psh, struct job *jp, union node *n, int mode, 822 shpid 823 forkshell2(shinstance *psh, struct job *jp, union node *n, int mode, 808 824 int (*child)(struct shinstance *, void *, union node *), 809 825 union node *nchild, void *argp, size_t arglen, 810 826 void (*setupchild)(struct shinstance *, struct shinstance *, void *)) 811 827 { 812 pid_t pid; 813 814 TRACE((psh, "forkshell2(%%%d, %p, %d, %p, %p, %p, %d) called\n", jp - psh->jobtab, n, mode, child, nchild, argp, (int)arglen)); 828 shpid pid; 829 830 # ifdef SH_FORKED_MODE 831 /* 832 * fork variant. 833 */ 815 834 pid = sh_fork(psh); 816 835 if (pid == 0) 817 836 { 818 837 /* child */ 819 forkchild(psh, jp , n, mode);820 sh_ exit(psh, child(psh, nchild, argp));838 forkchild(psh, jp == NULL || jp->nprocs == 0 ? -1 : jp->ps[0].pid, n, mode); 839 sh__exit(psh, child(psh, nchild, argp)); 821 840 return 0; 822 841 } … … 831 850 error(psh, "Cannot fork"); 832 851 return -1; /* won't get here */ 833 } 834 #endif 835 836 #ifdef KASH_USE_FORKSHELL2 837 static 838 #endif 839 int 840 forkparent(shinstance *psh, struct job *jp, union node *n, int mode, pid_t pid) 841 { 842 int pgrp; 852 853 # else 854 /* 855 * Clone the shell and start a thread to service the subshell. 856 */ 857 struct shinstance *pshchild; 858 859 TRACE((psh, "forkshell2(%%%d, %p, %d, %p, %p, %p, %d) called\n", 860 jp - psh->jobtab, n, mode, child, nchild, argp, (int)arglen)); 861 862 pshchild = sh_create_child_shell(psh); 863 if (pshchild) { 864 /* pack arguments */ 865 struct forkshell2args *args = (struct forkshell2args *)sh_calloc(pshchild, sizeof(*args) + arglen, 1); 866 args->psh = pshchild; 867 args->argp = memcpy(args + 1, argp, arglen); 868 args->child = child; 869 args->mode = mode; 870 args->pgrp = jp == NULL || jp->nprocs == 0 ? -1 : jp->ps[0].pid; 871 setstackmark(pshchild, &args->smark); 872 args->n = copyparsetree(pshchild, n); 873 if (setupchild) 874 setupchild(pshchild, psh, args->argp); 875 876 /* start the thread */ 877 pid = sh_thread_start(psh, pshchild, forkshell2_thread, args); 878 if (pid >= 0) 879 return forkparent(psh, jp, n, mode, pid); 880 error(psh, "sh_start_child_thread failed (%d)!", (int)pid); 881 } 882 else 883 error(psh, "sh_create_child_shell failed!"); 884 return -1; 885 # endif 886 } 887 #endif 888 889 static shpid 890 forkparent(shinstance *psh, struct job *jp, union node *n, int mode, shpid pid) 891 { 892 shpid pgrp; 843 893 844 894 if (psh->rootshell && mode != FORK_NOJOB && mflag(psh)) { … … 860 910 commandtext(psh, ps, n); 861 911 } 862 TRACE((psh, "In parent shell: child = % d\n", pid));912 TRACE((psh, "In parent shell: child = %" SHPID_PRI "\n", pid)); 863 913 return pid; 864 914 } 865 915 866 #ifdef KASH_USE_FORKSHELL2 867 static 868 #endif 869 void 870 forkchild(shinstance *psh, struct job *jp, union node *n, int mode) 916 static void 917 forkchild(shinstance *psh, shpid pgrp, union node *n, int mode) 871 918 { 872 919 int wasroot; 873 int pgrp;874 920 const char *devnull = _PATH_DEVNULL; 875 921 const char *nullerr = "Can't open %s"; 876 922 877 923 wasroot = psh->rootshell; 878 TRACE((psh, "Child shell % d\n", sh_getpid(psh)));924 TRACE((psh, "Child shell %" SHPID_PRI "\n", sh_getpid(psh))); 879 925 psh->rootshell = 0; 880 926 … … 884 930 psh->jobctl = 0; /* do job control only in root shell */ 885 931 if (wasroot && mode != FORK_NOJOB && mflag(psh)) { 886 if ( jp == NULL || jp->nprocs == 0)932 if (pgrp == -1) 887 933 pgrp = sh_getpid(psh); 888 else889 pgrp = jp->ps[0].pid;890 934 /* This can fail because we are doing it in the parent also. 891 935 And we must ignore SIGTTOU at this point or we'll be stopped! */ … … 898 942 setsignal(psh, SIGTSTP); 899 943 setsignal(psh, SIGTTOU); 900 } else if (mode == FORK_BG) { 944 } else 945 #endif 946 if (mode == FORK_BG) { 901 947 ignoresig(psh, SIGINT); 902 948 ignoresig(psh, SIGQUIT); 903 if ((jp == NULL || jp->nprocs == 0) && 904 ! fd0_redirected_p(psh)) { 949 if (pgrp == -1 && ! fd0_redirected_p(psh)) { 905 950 shfile_close(&psh->fdtab, 0); 906 951 if (shfile_open(&psh->fdtab, devnull, O_RDONLY, 0) != 0) … … 908 953 } 909 954 } 910 #else911 if (mode == FORK_BG) {912 ignoresig(psh, SIGINT);913 ignoresig(psh, SIGQUIT);914 if ((jp == NULL || jp->nprocs == 0) &&915 ! fd0_redirected_p(psh)) {916 shfile_close(&psh->fdtab, 0);917 if (shfile_open(&psh->fdtab, devnull, O_RDONLY, 0) != 0)918 error(psh, nullerr, devnull);919 }920 }921 #endif922 955 if (wasroot && iflag(psh)) { 923 956 setsignal(psh, SIGINT); … … 928 961 psh->jobs_invalid = 1; 929 962 } 963 964 #if defined(KASH_USE_FORKSHELL2) && !defined(SH_FORKED_MODE) 965 /** thread procedure */ 966 static int forkshell2_thread(shinstance *psh, void *argp) 967 { 968 struct forkshell2args * volatile volargs = (struct forkshell2args *)argp; 969 struct jmploc jmp; 970 TRACE2((psh, "forkshell2_thread:\n")); 971 972 if (setjmp(jmp.loc) == 0) { 973 struct forkshell2args * const args = volargs; 974 975 forkchild(psh, args->pgrp, args->n, args->mode); 976 977 psh->handler = &jmp; 978 return args->child(psh, args->n, args->argp); 979 } 980 981 /* 982 * (We longjmp'ed here.) 983 * 984 * This is copied from main() and simplified: 985 */ 986 for (;;) { 987 psh = volargs->psh; /* longjmp paranoia */ 988 989 if (psh->exception != EXSHELLPROC) { 990 if (psh->exception == EXEXEC) 991 psh->exitstatus = psh->exerrno; 992 else if (psh->exception == EXERROR) 993 psh->exitstatus = 2; 994 TRACE2((psh, "forkshell2_thread: exception=%d -> exitshell2(,%d)\n", psh->exception, psh->exitstatus)); 995 return exitshell2(psh, psh->exitstatus); 996 } 997 998 /* EXSHELLPROC - tryexec gets us here and it wants to run a program 999 hoping (?) it's a shell script. We must reset the shell state and 1000 turn ourselves into a root shell before doing so. */ 1001 TRACE2((psh, "forkshell2_thread: exception=EXSHELLPROC\n")); 1002 psh->rootpid = /*getpid()*/ psh->pid; 1003 psh->rootshell = 1; 1004 psh->minusc = NULL; 1005 1006 reset(psh); 1007 popstackmark(psh, &volargs->smark); 1008 1009 FORCEINTON; /* enable interrupts */ 1010 1011 /* state3: */ 1012 if (sflag(psh) == 0) { 1013 # ifdef SIGTSTP 1014 static int sigs[] = { SIGINT, SIGQUIT, SIGHUP, SIGPIPE, SIGTSTP }; 1015 # else 1016 static int sigs[] = { SIGINT, SIGQUIT, SIGHUP, SIGPIPE }; 1017 # endif 1018 unsigned i; 1019 for (i = 0; i < K_ELEMENTS(sigs); i++) 1020 setsignal(psh, sigs[i]); 1021 } 1022 1023 if (setjmp(jmp.loc) == 0) { 1024 psh->handler = &jmp; 1025 cmdloop(psh, 1); 1026 TRACE2((psh, "forkshell2_thread: cmdloop returned -> exitshell2(,%d)\n", psh->exitstatus)); 1027 return exitshell2(psh, psh->exitstatus); 1028 } 1029 } 1030 } 1031 #endif 1032 930 1033 931 1034 /* … … 952 1055 { 953 1056 #if JOBS 954 intmypgrp = sh_getpgrp(psh);1057 shpid mypgrp = sh_getpgrp(psh); 955 1058 #endif 956 1059 int status; … … 1009 1112 */ 1010 1113 1011 STATIC int1114 STATIC shpid 1012 1115 dowait(shinstance *psh, int block, struct job *job) 1013 1116 { 1014 intpid;1117 shpid pid; 1015 1118 int status; 1016 1119 struct procstat *sp; … … 1023 1126 do { 1024 1127 pid = waitproc(psh, block, job, &status); 1025 TRACE((psh, "wait returns pid % d, status %d\n", pid, status));1128 TRACE((psh, "wait returns pid %" SHPID_PRI ", status %d\n", pid, status)); 1026 1129 } while (pid == -1 && errno == EINTR && psh->gotsig[SIGINT - 1] == 0); 1027 1130 if (pid <= 0) … … 1037 1140 continue; 1038 1141 if (sp->pid == pid) { 1039 TRACE((psh, "Job %d: changing status of proc %d from 0x%x to 0x%x\n", jp - psh->jobtab + 1, pid, sp->status, status)); 1142 TRACE((psh, "Job %d: changing status of proc %" SHPID_PRI " from 0x%x to 0x%x\n", 1143 jp - psh->jobtab + 1, pid, sp->status, status)); 1040 1144 sp->status = status; 1041 1145 thisjob = jp; … … 1086 1190 * rather than blocking. 1087 1191 */ 1088 STATIC int1192 STATIC shpid 1089 1193 waitproc(shinstance *psh, int block, struct job *jp, int *status) 1090 1194 { -
trunk/src/kash/jobs.h
r3437 r3438 42 42 #define FORK_NOJOB 2 43 43 44 #define FORK_JUST_IO 4 /* forking I/O subprocess/thread (here doc). */ 45 44 46 /* mode flags for showjob(s) */ 45 47 #define SHOW_PGID 0x01 /* only show pgid - for jobs -p */ … … 61 63 62 64 struct procstat { 63 pid_tpid; /* process id */65 shpid pid; /* process id */ 64 66 int status; /* last process status from wait() */ 65 67 char cmd[MAXCMDTEXT];/* text of command being run */ … … 70 72 struct procstat *ps; /* status or processes when more than one */ 71 73 int nprocs; /* number of processes */ 72 pid_t pgrp; /* process group of this job*/74 shpid pgrp; /* process group of this job */ /**< @todo is job:pgrp used anywhere? */ 73 75 char state; 74 76 #define JOBRUNNING 0 /* at least one proc running */ … … 96 98 struct job *makejob(struct shinstance *, union node *, int); 97 99 #ifdef KASH_USE_FORKSHELL2 98 intforkshell2(struct shinstance *, struct job *, union node *, int,99 100 101 100 shpid forkshell2(struct shinstance *, struct job *, union node *, int, 101 int (*child)(struct shinstance *, void *, union node *), 102 union node *, void *, size_t, 103 void (*setupchild)(struct shinstance *, struct shinstance *, void *)); 102 104 #else 103 int forkshell(struct shinstance *, struct job *, union node *, int); 104 void forkchild(struct shinstance *, struct job *, union node *, int); 105 int forkparent(struct shinstance *, struct job *, union node *, int, pid_t); 105 shpid forkshell(struct shinstance *, struct job *, union node *, int); 106 106 #endif 107 107 int waitforjob(struct shinstance *, struct job *); 108 108 int stoppedjobs(struct shinstance *); 109 109 void commandtext(struct shinstance *, struct procstat *, union node *); 110 intgetjobpgrp(struct shinstance *, const char *);110 shpid getjobpgrp(struct shinstance *, const char *); 111 111 112 112 #if ! JOBS -
trunk/src/kash/main.c
r3435 r3438 45 45 #endif 46 46 47 #include <assert.h> 47 48 #include <errno.h> 48 49 #include <stdio.h> … … 101 102 102 103 int 103 #if K_OS == K_OS_WINDOWS 104 #if K_OS == K_OS_WINDOWS && defined(SH_FORKED_MODE) 104 105 real_main(int argc, char **argv, char **envp) 105 106 #else … … 130 131 * Create the root shell instance. 131 132 */ 132 psh = sh_create_root_shell( NULL, argc,argv, envp);133 psh = sh_create_root_shell(argv, envp); 133 134 if (!psh) 134 135 return 2; 135 136 shthread_set_shell(psh); 136 shell_main(psh, argc, psh-> argptr);137 shell_main(psh, argc, psh->orgargv); 137 138 /* Not reached. */ 138 139 return 89; … … 406 407 407 408 if (argc >= 2) { /* That's what SVR2 does */ 409 char * const savedcommandname = psh->commandname; 410 int const savedcommandnamemalloc = psh->commandnamemalloc; 408 411 char *fullname; 409 412 struct stackmark smark; … … 413 416 setinputfile(psh, fullname, 1); 414 417 psh->commandname = fullname; 418 psh->commandnamemalloc = 0; 415 419 cmdloop(psh, 0); 416 420 popfile(psh); 421 psh->commandname = savedcommandname; 422 psh->commandnamemalloc = savedcommandnamemalloc; 417 423 popstackmark(psh, &smark); 418 424 } -
trunk/src/kash/options.c
r2652 r3438 41 41 #endif 42 42 43 #include <assert.h> 43 44 #include <stdlib.h> 44 45 … … 77 78 STATIC int getopts(shinstance *, char *, char *, char **, char ***, char **); 78 79 80 #ifndef SH_FORKED_MODE 81 void 82 subshellinitoptions(shinstance *psh, shinstance *inherit) 83 { 84 unsigned i; 85 int left; 86 const char *arg; 87 memcpy(&psh->optlist[0], &inherit->optlist[0], sizeof(psh->optlist)); 88 89 /** @todo opimize: skip this when executing builtins. */ 90 /* Whether the subshell uses argptr/shellparam/arg0 or replaces them depends 91 on whether the shell will execute a builtin command or not. 92 93 orgargv is already set by the shinstance.c core code, scan the original 94 again and update arg0, shellparm, argptr and optptr. */ 95 96 /* arg0 is either something from orgargv, or in the EXSHELLPROC case a 97 separate allocation that we need to dupe here. The (new) arg0malloc 98 flag indicates which. */ 99 i = 0; 100 psh->arg0malloc = inherit->arg0malloc; 101 if (inherit->arg0malloc) { 102 psh->arg0 = savestr(psh, inherit->arg0); 103 } else { 104 while ((arg = inherit->orgargv[i]) != NULL) { 105 if (inherit->arg0 == arg) { 106 psh->arg0 = psh->orgargv[i]; 107 break; 108 } 109 i++; 110 } 111 assert(psh->arg0 != NULL); 112 } 113 114 /* eval.h's commandname is same as arg0 when set unless we're doing a dot-include. */ 115 if (inherit->commandname) { 116 if (inherit->commandname == inherit->arg0) { 117 psh->commandname = psh->arg0; 118 } else { 119 psh->commandname = savestr(psh, inherit->commandname); 120 psh->commandnamemalloc = 1; 121 } 122 } 123 124 /* shellparam is either pointing right after arg0 in orgargv, though it may 125 also be a separately allocated thing (see setparam), or pointing to the 126 arguments of a shell function we're executing (see eval.c). All in all, 127 it's simpler if we just copy the whole darn thing, ASSUMING no 128 modifications will be made that are needed to be visible elsewhere. 129 */ 130 psh->shellparam.malloc = 1; 131 psh->shellparam.reset = inherit->shellparam.reset; 132 psh->shellparam.nparam = left = inherit->shellparam.nparam; 133 assert(left >= 0); 134 psh->shellparam.p = (char **)ckmalloc(psh, left + 1); 135 psh->shellparam.p[left] = NULL; 136 while (left-- > 0) { 137 arg = inherit->shellparam.p[left]; 138 psh->shellparam.p[left] = savestr(psh, arg); 139 } 140 141 /* The shellparam.optnext member is either NULL or points to a 'p' entry. */ 142 if (inherit->shellparam.optnext) { 143 size_t idx = (size_t)(inherit->shellparam.optnext - inherit->shellparam.p); 144 assert(idx <= inherit->shellparam.nparam); 145 if (idx <= inherit->shellparam.nparam) 146 psh->shellparam.optnext = &psh->shellparam.p[idx]; 147 } 148 149 /* The shellparam.optptr member is either NULL or points within argument 150 prior to shellparam.optnext. We can leave it as NULL if at the EOS. */ 151 if (inherit->shellparam.optptr && *inherit->shellparam.optptr != '\0') { 152 intptr_t idx; 153 if (!inherit->shellparam.optnext || inherit->shellparam.optnext == inherit->shellparam.p) 154 idx = (intptr_t)(inherit->shellparam.nparam - 1); 155 else { 156 idx = (intptr_t)(inherit->shellparam.optnext - inherit->shellparam.p - 1); 157 if (idx > inherit->shellparam.nparam) 158 idx = inherit->shellparam.nparam - 1; 159 } 160 while (idx >= 0) { 161 size_t arglen, off; 162 arg = inherit->shellparam.p[idx]; 163 arglen = strlen(arg); 164 off = (size_t)(inherit->shellparam.optptr - arg); 165 if (off < arglen) { 166 psh->shellparam.optptr = psh->shellparam.p[idx] + off; 167 break; 168 } 169 off--; 170 } 171 assert(psh->shellparam.optptr != NULL); 172 } 173 174 /* minusc: only used in main.c, so not applicable to subshells. */ 175 /* optionarg: only used by callers of nextopt, so not relevant when forking subhells. */ 176 } 177 #endif /* SH_FORKED_MODE */ 178 79 179 80 180 /* … … 105 205 debug(psh) = 1; 106 206 #endif 207 psh->commandnamemalloc = 0; 208 psh->arg0malloc = 0; 107 209 psh->arg0 = argv[0]; 108 210 if (sflag(psh) == 0 && psh->minusc == NULL) { -
trunk/src/kash/options.h
r2679 r3438 130 130 /*extern char *optptr;*/ /* used by nextopt */ 131 131 132 #ifndef SH_FORKED_MODE 133 void subshellinitoptions(struct shinstance *, struct shinstance *); 134 #endif 132 135 void procargs(struct shinstance *, int, char **); 133 136 void optschanged(struct shinstance *); -
trunk/src/kash/output.c
r2290 r3438 356 356 f++; 357 357 } 358 #ifdef _MSC_VER /* for SHPID_PRI / KI64_PRI */ 359 else if (*f == 'I' && f[1] == '6' && f[2] == '4') { 360 isquad++; 361 f += 3; 362 } 363 #endif 358 364 digit = digit_upper; 359 365 switch (*f) { -
trunk/src/kash/parser.c
r3437 r3438 617 617 618 618 void fixredir(shinstance *psh, union node *n, const char *text, int err) 619 619 { 620 620 TRACE((psh, "Fix redir %s %d\n", text, err)); 621 621 if (!err) -
trunk/src/kash/redir.c
r3437 r3438 288 288 args.pip[1] = pip[1]; 289 289 args.len = len; 290 forkshell2(psh, (struct job *)NULL, (union node *)NULL, FORK_NOJOB, 290 forkshell2(psh, (struct job *)NULL, (union node *)NULL, 291 FORK_NOJOB | FORK_JUST_IO, 291 292 openhere_child, redir, &args, sizeof(args), NULL); 292 293 } -
trunk/src/kash/shell.h
r3062 r3438 94 94 #include "shtypes.h" 95 95 96 #ifndef SH_FORKED_MODE 97 # ifndef KASH_USE_FORKSHELL2 98 # define KASH_USE_FORKSHELL2 99 # endif 96 100 #endif 101 102 #endif -
trunk/src/kash/shfile.c
r3240 r3438 637 637 #ifdef SHFILE_IN_USE 638 638 /* Get CWD with unix slashes. */ 639 char buf[SHFILE_MAX_PATH]; 640 if (getcwd(buf, sizeof(buf))) 641 { 642 shfile_fix_slashes(buf); 643 644 pfdtab->cwd = sh_strdup(NULL, buf); 645 if (!inherit) 639 if (!inherit) 640 { 641 char buf[SHFILE_MAX_PATH]; 642 if (getcwd(buf, sizeof(buf))) 643 { 644 shfile_fix_slashes(buf); 645 pfdtab->cwd = sh_strdup(NULL, buf); 646 } 647 if (pfdtab->cwd) 646 648 { 647 649 # if K_OS == K_OS_WINDOWS … … 817 819 } 818 820 else 821 rc = -1; 822 } 823 else 824 { 825 /* 826 * Inherit from parent shell's file table. 827 */ 828 shfile const *src; 829 shfile *dst; 830 shmtxtmp tmp; 831 unsigned fdcount; 832 unsigned fd; 833 834 shmtx_enter(&inherit->mtx, &tmp); 835 836 /* allocate table and cwd: */ 837 fdcount = inherit->size; 838 pfdtab->tab = dst = (shfile *)(fdcount ? sh_calloc(NULL, sizeof(pfdtab->tab[0]), fdcount) : NULL); 839 pfdtab->cwd = sh_strdup(NULL, inherit->cwd); 840 if ( pfdtab->cwd 841 && (pfdtab->tab || fdcount == 0)) 819 842 { 820 /** @todo */ 821 errno = ENOSYS; 843 /* duplicate table entries: */ 844 for (fd = 0, src = inherit->tab; fd < fdcount; fd++, src++, dst++) 845 if (src->fd == -1) 846 dst->native = dst->fd = -1; 847 else 848 { 849 # ifdef SH_FORKED_MODE 850 KBOOL const cox = !!(src->shflags & SHFILE_FLAGS_CLOSE_ON_EXEC); 851 # else 852 KBOOL const cox = !!(src->shflags & SHFILE_FLAGS_CLOSE_ON_EXEC); /// @todo K_TRUE 853 # endif 854 *dst = *src; 855 # if K_OS == K_OS_WINDOWS 856 if (DuplicateHandle(GetCurrentProcess(), 857 (HANDLE)src->native, 858 GetCurrentProcess(), 859 (HANDLE *)&dst->native, 860 0, 861 cox ? FALSE : TRUE /* bInheritHandle */, 862 DUPLICATE_SAME_ACCESS)) 863 TRACE2((NULL, "shfile_init: %d (%#x, %#x) %p (was %p)\n", 864 dst->fd, dst->oflags, dst->shflags, dst->native, src->native)); 865 else 866 { 867 dst->native = (intptr_t)INVALID_HANDLE_VALUE; 868 rc = shfile_dos2errno(GetLastError()); 869 TRACE2((NULL, "shfile_init: %d (%#x, %#x) %p - failed %d / %u!\n", 870 dst->fd, dst->oflags, dst->shflags, src->native, rc, GetLastError())); 871 break; 872 } 873 874 # elif K_OS == K_OS_LINUX /* 2.6.27 / glibc 2.9 */ || K_OS == K_OS_FREEBSD /* 10.0 */ || K_OS == K_OS_NETBSD /* 6.0 */ 875 dst->native = dup3(src->native, -1, cox ? O_CLOEXEC : 0); 876 # else 877 if (cox) 878 { 879 # ifndef SH_FORKED_MODE 880 shmtxtmp tmp2; 881 shmtx_enter(&global_exec_something, &tmp) 882 # endif 883 dst->native = dup2(src->native, -1); 884 if (dst->native >= 0) 885 rc = fcntl(dst->native, F_SETFD, FD_CLOEXEC); 886 # ifndef SH_FORKED_MODE 887 shmtx_leave(&global_exec_something, &tmp) 888 # endif 889 if (rc != 0) 890 break; 891 } 892 else 893 dst->native = dup2(src->native, -1); 894 if (dst->native < 0) 895 { 896 rc = -1; 897 break; 898 } 899 # endif 900 } 901 } 902 else 822 903 rc = -1; 823 } 824 } 825 else 826 rc = -1; 904 pfdtab->size = fd; 905 shmtx_leave(&inherit->mtx, &tmp); 906 } /* inherit != NULL */ 827 907 #endif 828 908 } … … 833 913 834 914 /** 835 * Changes the inheritability of a file descript ro, taking console handles into915 * Changes the inheritability of a file descriptor, taking console handles into 836 916 * account. 837 917 * -
trunk/src/kash/shfork-win.c
r2416 r3438 246 246 if (ResumeThread(ProcInfo.hThread) != (DWORD)-1) 247 247 { 248 rc = sh_add_child(psh, ProcInfo.dwProcessId, ProcInfo.hProcess );248 rc = sh_add_child(psh, ProcInfo.dwProcessId, ProcInfo.hProcess, K_TRUE); 249 249 if (!rc) 250 250 rc = (int)ProcInfo.dwProcessId; -
trunk/src/kash/shheap.c
r2416 r3438 35 35 #include "shinstance.h" 36 36 37 #if K_OS == K_OS_WINDOWS 37 #if K_OS == K_OS_WINDOWS && defined(SH_FORKED_MODE) 38 38 # define SHHEAP_IN_USE 39 39 #endif -
trunk/src/kash/shinstance.c
r3437 r3438 40 40 #include "shinstance.h" 41 41 42 #include "alias.h" 43 #include "memalloc.h" 44 #include "shell.h" 45 #include "trap.h" 46 42 47 #if K_OS == K_OS_WINDOWS 43 48 # include <Windows.h> 49 # ifdef SH_FORKED_MODE 44 50 extern pid_t shfork_do(shinstance *psh); /* shforkA-win.asm */ 51 # endif 45 52 #endif 46 53 … … 174 181 static void sh_destroy(shinstance *psh) 175 182 { 183 /** @todo finish this... */ 176 184 memset(psh, 0, sizeof(*psh)); 177 185 sh_free(NULL, psh); … … 221 229 222 230 /** 223 * Creates a root shell instance. 224 * 225 * @param inherit The shell to inherit from. If NULL inherit from environment and such. 226 * @param argc The argument count. 231 * Creates a shell instance, caller must link it. 232 * 233 * @param inherit The shell to inherit from, or NULL if root. 227 234 * @param argv The argument vector. 228 235 * @param envp The environment vector. 236 * @param parentfdtab File table to inherit from, NULL if root. 229 237 * 230 238 * @returns pointer to root shell on success, NULL on failure. 231 239 */ 232 s hinstance *sh_create_root_shell(shinstance *inherit, int argc, char **argv, char **envp)240 static shinstance *sh_create_shell_common(char **argv, char **envp, shfdtab *parentfdtab) 233 241 { 234 242 shinstance *psh; 235 int i;236 243 237 244 /* … … 241 248 if (psh) 242 249 { 243 /* Init it enough for sh_destroy() to not get upset */244 250 /* Init it enough for sh_destroy() to not get upset: */ 251 /* ... */ 245 252 246 253 /* Call the basic initializers. */ 247 254 if ( !sh_clone_string_vector(psh, &psh->shenviron, envp) 248 && !sh_clone_string_vector(psh, &psh->argptr, argv) 249 && !shfile_init(&psh->fdtab, inherit ? &inherit->fdtab : NULL)) 250 { 251 /* the special stuff. */ 252 #ifdef _MSC_VER 253 psh->pid = _getpid(); 255 && !sh_clone_string_vector(psh, &psh->orgargv, argv) 256 && !shfile_init(&psh->fdtab, parentfdtab)) 257 { 258 unsigned i; 259 260 /* 261 * The special stuff. 262 */ 263 #ifdef _MSC_VER 264 psh->pgid = psh->pid = _getpid(); 254 265 #else 255 266 psh->pid = getpid(); 256 #endif 267 psh->pgid = getpgid(); 268 #endif 269 257 270 /*sh_sigemptyset(&psh->sigrestartset);*/ 258 for (i = 0; i < NSIG; i++)271 for (i = 0; i < K_ELEMENTS(psh->sigactions); i++) 259 272 psh->sigactions[i].sh_handler = SH_SIG_UNK; 260 if (inherit)261 psh->sigmask = psh->sigmask;262 else263 {264 273 #if defined(_MSC_VER) 265 sh_sigemptyset(&psh->sigmask); 266 #else 267 sigprocmask(SIG_SETMASK, NULL, &psh->sigmask); 268 #endif 269 } 274 sh_sigemptyset(&psh->sigmask); 275 #else 276 sigprocmask(SIG_SETMASK, NULL, &psh->sigmask); 277 #endif 278 279 /* 280 * State initialization. 281 */ 282 /* cd.c */ 283 psh->getpwd_first = 1; 284 285 /* exec */ 286 psh->builtinloc = -1; 270 287 271 288 /* memalloc.c */ … … 303 320 /* show.c */ 304 321 psh->tracefd = -1; 305 306 /* link it. */307 sh_int_link(psh);308 322 return psh; 309 323 } … … 313 327 return NULL; 314 328 } 329 330 /** 331 * Creates the root shell instance. 332 * 333 * @param argv The argument vector. 334 * @param envp The environment vector. 335 * 336 * @returns pointer to root shell on success, NULL on failure. 337 */ 338 shinstance *sh_create_root_shell(char **argv, char **envp) 339 { 340 shinstance *psh = sh_create_shell_common(argv, envp, NULL /*parentfdtab*/); 341 if (psh) 342 { 343 sh_int_link(psh); 344 return psh; 345 } 346 return NULL; 347 } 348 349 #ifndef SH_FORKED_MODE 350 351 /** 352 * Does the inherting from the parent shell instance. 353 */ 354 static void sh_inherit_from_parent(shinstance *psh, shinstance *inherit) 355 { 356 /* 357 * Do the rest of the inheriting. 358 */ 359 psh->parent = inherit; 360 psh->pgid = inherit->pgid; 361 362 psh->sigmask = psh->sigmask; 363 /** @todo sigactions? */ 364 /// @todo suppressint? 365 366 /* alises: */ 367 subshellinitalias(psh, inherit); 368 369 /* cd.c */ 370 psh->getpwd_first = inherit->getpwd_first; 371 if (inherit->curdir) 372 psh->curdir = savestr(psh, inherit->curdir); 373 if (inherit->prevdir) 374 psh->prevdir = savestr(psh, inherit->prevdir); 375 376 /* eval.h */ 377 /* psh->commandname - see subshellinitoptions */ 378 psh->exitstatus = inherit->exitstatus; /// @todo ?? 379 psh->back_exitstatus = inherit->back_exitstatus; /// @todo ?? 380 psh->funcnest = inherit->funcnest; 381 psh->evalskip = inherit->evalskip; /// @todo ?? 382 psh->skipcount = inherit->skipcount; /// @todo ?? 383 384 /* exec.c */ 385 subshellinitexec(psh, inherit); 386 387 /* input.h/input.c - only for the parser and anyway forkchild calls closescript(). */ 388 389 /* jobs.h - should backgndpid be -1 in subshells? */ 390 391 /* jobs.c - */ 392 psh->jobctl = inherit->jobctl; /// @todo ?? 393 psh->initialpgrp = inherit->initialpgrp; 394 psh->ttyfd = inherit->ttyfd; 395 /** @todo copy jobtab so the 'jobs' command can be run in a subshell. 396 * Better, make it follow the parent chain and skip the copying. Will 397 * require some kind of job locking. */ 398 399 /* mail.c - nothing (for now at least) */ 400 401 /* main.h */ 402 psh->rootpid = inherit->rootpid; 403 psh->psh_rootshell = inherit->psh_rootshell; 404 405 /* memalloc.h / memalloc.c - nothing. */ 406 407 /* myhistedit.h */ /** @todo copy history? Do we need to care? */ 408 409 /* output.h */ /** @todo not sure this is possible/relevant for subshells */ 410 psh->output.fd = inherit->output.fd; 411 psh->errout.fd = inherit->errout.fd; 412 if (inherit->out1 == &inherit->memout) 413 psh->out1 = &psh->memout; 414 if (inherit->out2 == &inherit->memout) 415 psh->out2 = &psh->memout; 416 417 /* options.h */ 418 subshellinitoptions(psh, inherit); 419 420 /* parse.h/parse.c */ 421 psh->whichprompt = inherit->whichprompt; 422 /* tokpushback, doprompt and needprompt shouldn't really matter, parsecmd resets thems. */ 423 /* The rest are internal to the parser, as I see them, and can be ignored. */ 424 425 /* redir.c - we shouldn't sub-shell with redirlist as non-NULL, I think. */ 426 assert(inherit->redirlist == NULL); 427 assert(inherit->fd0_redirected == 0); /* (follows from redirlist == NULL) */ 428 429 /* show.c */ 430 psh->tracefd = inherit->tracefd; 431 432 /* trap.h / trap.c */ /** @todo we don't carry pendingsigs to the subshell, right? */ 433 subshellinittrap(psh, inherit); 434 435 /* var.h */ 436 subshellinitvar(psh, inherit); 437 } 438 439 /** 440 * Creates a child shell instance. 441 * 442 * @param inherit The shell to inherit from. 443 * 444 * @returns pointer to root shell on success, NULL on failure. 445 */ 446 shinstance *sh_create_child_shell(shinstance *inherit) 447 { 448 shinstance *psh = sh_create_shell_common(inherit->orgargv, inherit->shenviron, &inherit->fdtab); 449 if (psh) 450 { 451 /* Fake a pid for the child: */ 452 static unsigned volatile s_cShells = 0; 453 int const iSubShell = ++s_cShells; 454 psh->pid = SHPID_MAKE(SHPID_GET_PID(inherit->pid), iSubShell); 455 456 sh_inherit_from_parent(psh, inherit); 457 458 /* link it */ 459 sh_int_link(psh); 460 return psh; 461 } 462 return NULL; 463 } 464 465 #endif /* !SH_FORKED_MODE */ 315 466 316 467 /** getenv() */ … … 777 928 } 778 929 779 int sh_kill(shinstance *psh, pid_tpid, int signo)930 int sh_kill(shinstance *psh, shpid pid, int signo) 780 931 { 781 932 shinstance *pshDst; … … 793 944 if (pshDst->pid == pid) 794 945 { 795 TRACE2((psh, "sh_kill(% d, %d): pshDst=%p\n", pid, signo, pshDst));946 TRACE2((psh, "sh_kill(%" SHPID_PRI ", %d): pshDst=%p\n", pid, signo, pshDst)); 796 947 sh_sig_do_signal(psh, pshDst, signo, 1 /* locked */); 797 948 … … 807 958 * Some other process, call kill where possible 808 959 */ 809 #if defined(SH_FORKED_MODE) 810 # ifdef _MSC_VER 960 #ifdef _MSC_VER 811 961 errno = ENOSYS; 812 962 rc = -1; 813 # else963 #elif defined(SH_FORKED_MODE) 814 964 /* fprintf(stderr, "kill(%d, %d)\n", pid, signo);*/ 815 965 rc = kill(pid, signo); 816 # endif 817 818 #else 966 #else 967 # error "PORT ME?" 819 968 #endif 820 969 … … 823 972 } 824 973 825 int sh_killpg(shinstance *psh, pid_t pgid, int signo) 826 { 974 int sh_killpg(shinstance *psh, shpid pgid, int signo) 975 { 976 shinstance *pshDst; 977 shmtxtmp tmp; 827 978 int rc; 828 979 829 #if defined(SH_FORKED_MODE) 830 # ifdef _MSC_VER 980 /* 981 * Self or any of the subshells? 982 */ 983 shmtx_enter(&g_sh_mtx, &tmp); 984 985 pshDst = g_sh_tail; 986 while (pshDst != NULL) 987 { 988 if (pshDst->pgid == pgid) 989 { 990 TRACE2((psh, "sh_killpg(%" SHPID_PRI ", %d): pshDst=%p\n", pgid, signo, pshDst)); 991 sh_sig_do_signal(psh, pshDst, signo, 1 /* locked */); 992 993 shmtx_leave(&g_sh_mtx, &tmp); 994 return 0; 995 } 996 pshDst = pshDst->prev; 997 } 998 999 shmtx_leave(&g_sh_mtx, &tmp); 1000 1001 #ifdef _MSC_VER 831 1002 errno = ENOSYS; 832 1003 rc = -1; 833 # else1004 #elif defined(SH_FORKED_MODE) 834 1005 //fprintf(stderr, "killpg(%d, %d)\n", pgid, signo); 835 1006 rc = killpg(pgid, signo); 836 # endif 837 838 #else 839 #endif 840 841 TRACE2((psh, "sh_killpg(%d, %d) -> %d [%d]\n", pgid, signo, rc, errno)); 1007 #else 1008 # error "PORTME?" 1009 #endif 1010 1011 TRACE2((psh, "sh_killpg(%" SHPID_PRI ", %d) -> %d [%d]\n", pgid, signo, rc, errno)); 842 1012 (void)psh; 843 1013 return rc; … … 846 1016 clock_t sh_times(shinstance *psh, shtms *tmsp) 847 1017 { 848 #if defined(SH_FORKED_MODE) 849 (void)psh; 850 # ifdef _MSC_VER 1018 #ifdef _MSC_VER 851 1019 errno = ENOSYS; 852 1020 return (clock_t)-1; 853 # else 1021 #elif defined(SH_FORKED_MODE) 1022 (void)psh; 854 1023 return times(tmsp); 855 # endif 856 857 #else 1024 #else 1025 # error "PORTME" 858 1026 #endif 859 1027 } … … 873 1041 * @returns 0 on success, on failure -1 and errno set to ENOMEM. 874 1042 * 875 * @param psh The shell instance. 876 * @param pid The child pid. 877 * @param hChild Windows child handle. 1043 * @param psh The shell instance. 1044 * @param pid The child pid. 1045 * @param hChild Windows child handle. 1046 * @param fProcess Set if process, clear if thread. 878 1047 */ 879 int sh_add_child(shinstance *psh, pid_t pid, void *hChild)1048 int sh_add_child(shinstance *psh, shpid pid, void *hChild, KBOOL fProcess) 880 1049 { 881 1050 /* get a free table entry. */ … … 898 1067 psh->children[i].hChild = hChild; 899 1068 #endif 900 (void)hChild; 1069 #ifndef SH_FORKED_MODE 1070 psh->children[i].fProcess = fProcess; 1071 #endif 1072 (void)hChild; (void)fProcess; 901 1073 return 0; 902 1074 } 1075 1076 #ifdef SH_FORKED_MODE 903 1077 904 1078 pid_t sh_fork(shinstance *psh) … … 938 1112 } 939 1113 1114 #else /* !SH_FORKED_MODE */ 1115 1116 # ifdef _MSC_VER 1117 /** Thread wrapper procedure. */ 1118 static unsigned __stdcall sh_thread_wrapper(void *user) 1119 { 1120 shinstance *psh = (shinstance *)user; 1121 int iExit; 1122 1123 /* Update the TID and PID (racing sh_thread_start) */ 1124 DWORD tid = GetCurrentThreadId(); 1125 shpid pid = GetCurrentProcessId(); 1126 1127 pid = SHPID_MAKE(pid, tid); 1128 psh->pid = pid; 1129 psh->tid = tid; 1130 1131 /* Set the TLS entry before we try TRACE or TRACE2. */ 1132 shthread_set_shell(psh); 1133 1134 TRACE2((psh, "sh_thread_wrapper: enter\n")); 1135 iExit = psh->thread(psh, psh->threadarg); 1136 /** @todo do shell cleanup. */ 1137 TRACE2((psh, "sh_thread_wrapper: quits - iExit=%d\n", iExit)); 1138 1139 _endthreadex(iExit); 1140 return iExit; 1141 } 1142 # else 1143 # error "PORTME" 1144 # endif 1145 1146 /** 1147 * Starts a sub-shell thread. 1148 */ 1149 shpid sh_thread_start(shinstance *pshparent, shinstance *pshchild, int (*thread)(shinstance *, void *), void *arg) 1150 { 1151 # ifdef _MSC_VER 1152 unsigned tid = 0; 1153 uintptr_t hThread; 1154 shpid pid; 1155 1156 pshchild->thread = thread; 1157 pshchild->threadarg = arg; 1158 hThread = _beginthreadex(NULL /*security*/, 0 /*stack_size*/, sh_thread_wrapper, pshchild, 0 /*initflags*/, &tid); 1159 if (hThread == -1) 1160 return -errno; 1161 1162 pid = SHPID_MAKE(SHPID_GET_PID(pshparent->pid), tid); 1163 pshchild->pid = pid; 1164 pshchild->tid = tid; 1165 1166 if (sh_add_child(pshparent, pid, (void *)hThread, K_FALSE) != 0) { 1167 return -ENOMEM; 1168 } 1169 return pid; 1170 1171 # else 1172 # error "PORTME" 1173 # endif 1174 } 1175 1176 #endif /* !SH_FORKED_MODE */ 1177 940 1178 /** waitpid() */ 941 pid_t sh_waitpid(shinstance *psh, pid_tpid, int *statusp, int flags)942 { 943 pid_tpidret;1179 shpid sh_waitpid(shinstance *psh, shpid pid, int *statusp, int flags) 1180 { 1181 shpid pidret; 944 1182 #if K_OS == K_OS_WINDOWS //&& defined(SH_FORKED_MODE) 945 1183 DWORD dwRet; … … 1015 1253 { 1016 1254 DWORD dwExitCode = 127; 1255 #ifndef SH_FORKED_MODE 1256 if (psh->children[i].fProcess ? GetExitCodeProcess(hChild, &dwExitCode) : GetExitCodeThread(hChild, &dwExitCode)) 1257 #else 1017 1258 if (GetExitCodeProcess(hChild, &dwExitCode)) 1259 #endif 1018 1260 { 1019 1261 pidret = psh->children[i].pid; … … 1046 1288 #endif 1047 1289 1048 TRACE2((psh, "waitpid(% d, %p, %#x) -> %d[%d] *statusp=%#x (rc=%d)\n", pid, statusp, flags,1290 TRACE2((psh, "waitpid(%" SHPID_PRI ", %p, %#x) -> %" SHPID_PRI " [%d] *statusp=%#x (rc=%d)\n", pid, statusp, flags, 1049 1291 pidret, errno, *statusp, WEXITSTATUS(*statusp))); 1050 1292 (void)psh; … … 1282 1524 uid_t sh_getuid(shinstance *psh) 1283 1525 { 1284 #if defined(SH_FORKED_MODE) 1285 # ifdef _MSC_VER 1526 #ifdef _MSC_VER 1286 1527 uid_t uid = 0; 1287 # 1528 #else 1288 1529 uid_t uid = getuid(); 1289 # endif1290 1291 #else1292 1530 #endif 1293 1531 … … 1299 1537 uid_t sh_geteuid(shinstance *psh) 1300 1538 { 1301 #if defined(SH_FORKED_MODE) 1302 # ifdef _MSC_VER 1539 #ifdef _MSC_VER 1303 1540 uid_t euid = 0; 1304 # 1541 #else 1305 1542 uid_t euid = geteuid(); 1306 # endif1307 1308 #else1309 1543 #endif 1310 1544 … … 1316 1550 gid_t sh_getgid(shinstance *psh) 1317 1551 { 1318 #if defined(SH_FORKED_MODE) 1319 # ifdef _MSC_VER 1552 #ifdef _MSC_VER 1320 1553 gid_t gid = 0; 1321 # 1554 #else 1322 1555 gid_t gid = getgid(); 1323 # endif1324 1325 #else1326 1556 #endif 1327 1557 … … 1333 1563 gid_t sh_getegid(shinstance *psh) 1334 1564 { 1335 #if defined(SH_FORKED_MODE) 1336 # ifdef _MSC_VER 1565 #ifdef _MSC_VER 1337 1566 gid_t egid = 0; 1338 # 1567 #else 1339 1568 gid_t egid = getegid(); 1340 # endif1341 1342 #else1343 1569 #endif 1344 1570 … … 1348 1574 } 1349 1575 1350 pid_t sh_getpid(shinstance *psh) 1351 { 1352 pid_t pid; 1353 1354 #if defined(SH_FORKED_MODE) 1355 # ifdef _MSC_VER 1356 pid = _getpid(); 1357 # else 1358 pid = getpid(); 1359 # endif 1360 #else 1361 #endif 1362 1576 shpid sh_getpid(shinstance *psh) 1577 { 1578 return psh->pid; 1579 } 1580 1581 shpid sh_getpgrp(shinstance *psh) 1582 { 1583 shpid pgid = psh->pgid; 1584 #ifndef _MSC_VER 1585 assert(pgid == getpgrp()); 1586 #endif 1587 1588 TRACE2((psh, "sh_getpgrp() -> %" SHPID_PRI " [%d]\n", pgid, errno)); 1589 return pgid; 1590 } 1591 1592 /** 1593 * @param pid Should always be zero, i.e. referring to the current shell 1594 * process. 1595 */ 1596 shpid sh_getpgid(shinstance *psh, shpid pid) 1597 { 1598 shpid pgid; 1599 if (pid == 0 || psh->pid == pid) 1600 { 1601 shpid pgid = psh->pgid; 1602 #ifndef _MSC_VER 1603 assert(pgid == getpgrp()); 1604 #endif 1605 } 1606 else 1607 { 1608 assert(0); 1609 errno = ESRCH; 1610 pgid = -1; 1611 } 1612 1613 TRACE2((psh, "sh_getpgid(%" SHPID_PRI ") -> %" SHPID_PRI " [%d]\n", pid, pgid, errno)); 1614 return pgid; 1615 } 1616 1617 /** 1618 * 1619 * @param pid The pid to modify. This is always 0, except when forkparent 1620 * calls to group a newly created child. Though, we might 1621 * almost safely ignore it in that case as the child will also 1622 * perform the operation. 1623 * @param pgid The process group to assign @a pid to. 1624 */ 1625 int sh_setpgid(shinstance *psh, shpid pid, shpid pgid) 1626 { 1627 #if defined(SH_FORKED_MODE) && !defined(_MSC_VER) 1628 int rc = setpgid(pid, pgid); 1629 TRACE2((psh, "sh_setpgid(%" SHPID_PRI ", %" SHPID_PRI ") -> %d [%d]\n", pid, pgid, rc, errno)); 1363 1630 (void)psh; 1364 return pid; 1365 } 1366 1367 pid_t sh_getpgrp(shinstance *psh) 1368 { 1369 #if defined(SH_FORKED_MODE) 1370 # ifdef _MSC_VER 1371 pid_t pgrp = _getpid(); 1372 # else 1373 pid_t pgrp = getpgrp(); 1374 # endif 1375 1376 #else 1377 #endif 1378 1379 TRACE2((psh, "sh_getpgrp() -> %d [%d]\n", pgrp, errno)); 1631 #else 1632 int rc = 0; 1633 if (pid == 0 || psh->pid == pid) 1634 { 1635 TRACE2((psh, "sh_setpgid(self,): %" SHPID_PRI " -> %" SHPID_PRI "\n", psh->pgid, pgid)); 1636 psh->pgid = pgid; 1637 } 1638 else 1639 { 1640 /** @todo fixme */ 1641 rc = -1; 1642 errno = ENOSYS; 1643 } 1644 #endif 1645 return rc; 1646 } 1647 1648 shpid sh_tcgetpgrp(shinstance *psh, int fd) 1649 { 1650 shpid pgrp; 1651 1652 #ifdef _MSC_VER 1653 pgrp = -1; 1654 errno = ENOSYS; 1655 #elif defined(SH_FORKED_MODE) 1656 pgrp = tcgetpgrp(fd); 1657 #else 1658 # error "PORT ME" 1659 #endif 1660 1661 TRACE2((psh, "sh_tcgetpgrp(%d) -> %" SHPID_PRI " [%d]\n", fd, pgrp, errno)); 1380 1662 (void)psh; 1381 1663 return pgrp; 1382 1664 } 1383 1665 1384 pid_t sh_getpgid(shinstance *psh, pid_t pid) 1385 { 1386 #if defined(SH_FORKED_MODE) 1387 # ifdef _MSC_VER 1388 pid_t pgid = pid; 1389 # else 1390 pid_t pgid = getpgid(pid); 1391 # endif 1392 1393 #else 1394 #endif 1395 1396 TRACE2((psh, "sh_getpgid(%d) -> %d [%d]\n", pid, pgid, errno)); 1666 int sh_tcsetpgrp(shinstance *psh, int fd, shpid pgrp) 1667 { 1668 int rc; 1669 TRACE2((psh, "sh_tcsetpgrp(%d, %" SHPID_PRI ")\n", fd, pgrp)); 1670 1671 #ifdef _MSC_VER 1672 rc = -1; 1673 errno = ENOSYS; 1674 #elif defined(SH_FORKED_MODE) 1675 rc = tcsetpgrp(fd, pgrp); 1676 #else 1677 # error "PORT ME" 1678 #endif 1679 1680 TRACE2((psh, "sh_tcsetpgrp(%d, %" SHPID_PRI ") -> %d [%d]\n", fd, pgrp, rc, errno)); 1397 1681 (void)psh; 1398 return pgid; 1399 } 1400 1401 int sh_setpgid(shinstance *psh, pid_t pid, pid_t pgid) 1402 { 1403 #if defined(SH_FORKED_MODE) 1404 # ifdef _MSC_VER 1682 return rc; 1683 } 1684 1685 int sh_getrlimit(shinstance *psh, int resid, shrlimit *limp) 1686 { 1687 #ifdef _MSC_VER 1405 1688 int rc = -1; 1406 1689 errno = ENOSYS; 1407 # else 1408 int rc = setpgid(pid, pgid); 1409 # endif 1410 1411 #else 1412 #endif 1413 1414 TRACE2((psh, "sh_setpgid(%d, %d) -> %d [%d]\n", pid, pgid, rc, errno)); 1415 (void)psh; 1416 return rc; 1417 } 1418 1419 pid_t sh_tcgetpgrp(shinstance *psh, int fd) 1420 { 1421 pid_t pgrp; 1422 1423 #if defined(SH_FORKED_MODE) 1424 # ifdef _MSC_VER 1425 pgrp = -1; 1426 errno = ENOSYS; 1427 # else 1428 pgrp = tcgetpgrp(fd); 1429 # endif 1430 1431 #else 1432 #endif 1433 1434 TRACE2((psh, "sh_tcgetpgrp(%d) -> %d [%d]\n", fd, pgrp, errno)); 1435 (void)psh; 1436 return pgrp; 1437 } 1438 1439 int sh_tcsetpgrp(shinstance *psh, int fd, pid_t pgrp) 1440 { 1441 int rc; 1442 TRACE2((psh, "sh_tcsetpgrp(%d, %d)\n", fd, pgrp)); 1443 1444 #if defined(SH_FORKED_MODE) 1445 # ifdef _MSC_VER 1446 rc = -1; 1447 errno = ENOSYS; 1448 # else 1449 rc = tcsetpgrp(fd, pgrp); 1450 # endif 1451 1452 #else 1453 #endif 1454 1455 TRACE2((psh, "sh_tcsetpgrp(%d, %d) -> %d [%d]\n", fd, pgrp, rc, errno)); 1456 (void)psh; 1457 return rc; 1458 } 1459 1460 int sh_getrlimit(shinstance *psh, int resid, shrlimit *limp) 1461 { 1462 #if defined(SH_FORKED_MODE) 1463 # ifdef _MSC_VER 1464 int rc = -1; 1465 errno = ENOSYS; 1466 # else 1690 #elif defined(SH_FORKED_MODE) 1467 1691 int rc = getrlimit(resid, limp); 1468 # endif 1469 1470 #else 1692 #else 1693 # error "PORT ME" 1471 1694 /* returned the stored limit */ 1472 1695 #endif … … 1480 1703 int sh_setrlimit(shinstance *psh, int resid, const shrlimit *limp) 1481 1704 { 1482 #if defined(SH_FORKED_MODE) 1483 # ifdef _MSC_VER 1705 #ifdef _MSC_VER 1484 1706 int rc = -1; 1485 1707 errno = ENOSYS; 1486 # else1708 #elif defined(SH_FORKED_MODE) 1487 1709 int rc = setrlimit(resid, limp); 1488 # endif 1489 1490 #else 1710 #else 1711 # error "PORT ME" 1491 1712 /* if max(shell) < limp; then setrlimit; fi 1492 1713 if success; then store limit for later retrival and maxing. */ -
trunk/src/kash/shinstance.h
r3435 r3438 65 65 typedef struct shchild 66 66 { 67 pid_tpid; /**< The pid. */67 shpid pid; /**< The pid. */ 68 68 #if K_OS == K_OS_WINDOWS 69 69 void *hChild; /**< The process handle. */ 70 #endif 71 #ifndef SH_FORKED_MODE 72 KBOOL fProcess; /**< Set if process, clear if internal thread. */ 70 73 #endif 71 74 } shchild; … … 140 143 struct shinstance *prev; /**< The previous shell instance. */ 141 144 struct shinstance *parent; /**< The parent shell instance. */ 142 pid_tpid; /**< The (fake) process id of this shell instance. */145 shpid pid; /**< The (fake) process id of this shell instance. */ 143 146 shtid tid; /**< The thread identifier of the thread for this shell. */ 147 shpid pgid; /**< Process group ID. */ 144 148 shfdtab fdtab; /**< The file descriptor table. */ 145 149 shsigaction_t sigactions[NSIG]; /**< The signal actions registered with this shell instance. */ … … 148 152 int num_children; /**< Number of children in the array. */ 149 153 shchild *children; /**< The child array. */ 154 #ifndef SH_FORKED_MODE 155 int (*thread)(struct shinstance *, void *); /**< The thread procedure. */ 156 void *threadarg; /**< The thread argument. */ 157 #endif 150 158 151 159 /* alias.c */ 152 160 #define ATABSIZE 39 153 161 struct alias *atab[ATABSIZE]; 162 unsigned aliases; /**< Number of active aliases. */ 154 163 155 164 /* cd.c */ … … 178 187 int skipcount; /**< number of levels to skip */ 179 188 int loopnest; /**< current loop nesting level */ 189 int commandnamemalloc; /**< Set if commandname is malloc'ed (only subshells). */ 180 190 181 191 /* expand.c */ … … 210 220 211 221 /* jobs.h */ 212 pid_tbackgndpid/* = -1 */; /**< pid of last background process */222 shpid backgndpid/* = -1 */; /**< pid of last background process */ 213 223 int job_warning; /**< user was warned about stopped jobs */ 214 224 … … 217 227 int njobs; /**< size of array */ 218 228 int jobs_invalid; /**< set in child */ 219 intinitialpgrp; /**< pgrp of shell on invocation */229 shpid initialpgrp; /**< pgrp of shell on invocation */ 220 230 int curjob/* = -1*/;/**< current job */ 221 231 int ttyfd/* = -1*/; … … 231 241 232 242 /* main.h */ 233 introotpid; /**< pid of main shell. */243 shpid rootpid; /**< pid of main shell. */ 234 244 int rootshell; /**< true if we aren't a child of the main shell. */ 235 245 struct shinstance *psh_rootshell; /**< The root shell pointer. (!rootshell) */ … … 272 282 char *optionarg; /**< set by nextopt */ 273 283 char *optptr; /**< used by nextopt */ 284 char **orgargv; /**< The original argument vector (for cleanup). */ 285 int arg0malloc; /**< Indicates whether arg0 was allocated or is part of orgargv. */ 274 286 275 287 /* parse.h */ … … 346 358 347 359 348 extern shinstance *sh_create_root_shell(shinstance *, int, char **, char **); 360 extern shinstance *sh_create_root_shell(char **, char **); 361 extern shinstance *sh_create_child_shell(shinstance *); 349 362 350 363 /* environment & pwd.h */ … … 395 408 SH_NORETURN_1 void sh_abort(shinstance *) SH_NORETURN_2; 396 409 void sh_raise_sigint(shinstance *); 397 int sh_kill(shinstance *, pid_t, int);398 int sh_killpg(shinstance *, pid_t, int);410 int sh_kill(shinstance *, shpid, int); 411 int sh_killpg(shinstance *, shpid, int); 399 412 400 413 /* times */ … … 416 429 417 430 /* wait / process */ 418 int sh_add_child(shinstance *psh, pid_t pid, void *hChild);431 int sh_add_child(shinstance *psh, shpid pid, void *hChild, KBOOL fProcess); 419 432 #ifdef _MSC_VER 420 433 # include <process.h> … … 442 455 # endif 443 456 #endif 444 pid_t sh_fork(shinstance *); 445 pid_t sh_waitpid(shinstance *, pid_t, int *, int); 457 #ifdef SH_FORKED_MODE 458 shpid sh_fork(shinstance *); 459 #else 460 shpid sh_thread_start(shinstance *pshparent, shinstance *pshchild, int (*thread)(shinstance *, void *), void *arg); 461 #endif 462 shpid sh_waitpid(shinstance *, shpid, int *, int); 446 463 SH_NORETURN_1 void sh__exit(shinstance *, int) SH_NORETURN_2; 447 464 int sh_execve(shinstance *, const char *, const char * const*, const char * const *); … … 450 467 gid_t sh_getgid(shinstance *); 451 468 gid_t sh_getegid(shinstance *); 452 pid_tsh_getpid(shinstance *);453 pid_tsh_getpgrp(shinstance *);454 pid_t sh_getpgid(shinstance *, pid_t);455 int sh_setpgid(shinstance *, pid_t, pid_t);469 shpid sh_getpid(shinstance *); 470 shpid sh_getpgrp(shinstance *); 471 shpid sh_getpgid(shinstance *, shpid); 472 int sh_setpgid(shinstance *, shpid, shpid); 456 473 457 474 /* tc* */ 458 pid_tsh_tcgetpgrp(shinstance *, int);459 int sh_tcsetpgrp(shinstance *, int, pid_t);475 shpid sh_tcgetpgrp(shinstance *, int); 476 int sh_tcsetpgrp(shinstance *, int, shpid); 460 477 461 478 /* sys/resource.h */ -
trunk/src/kash/show.c
r2423 r3438 299 299 300 300 if (pos) { 301 301 int s = errno; 302 302 char prefix[40]; 303 303 size_t len; 304 304 305 len = sprintf(prefix, "[%d] ", sh_getpid(psh)); 305 #ifdef SH_FORKED_MODE 306 len = sprintf(prefix, "[%" SHPID_PRI "] ", sh_getpid(psh)); 307 #else 308 shpid pid = sh_getpid(psh); 309 len = sprintf(prefix, "[%d/%d] ", SHPID_GET_PID(pid), SHPID_GET_TID(pid)); 310 #endif 306 311 shfile_write(&psh->fdtab, psh->tracefd, prefix, len); 307 312 shfile_write(&psh->fdtab, psh->tracefd, psh->tracebuf, pos); … … 310 315 psh->tracebuf[0] = '\0'; 311 316 312 317 errno = s; 313 318 } 314 319 } … … 359 364 } else { 360 365 /* it's too big for some reason... */ 361 366 int s = errno; 362 367 trace_flush(psh); 363 368 shfile_write(&psh->fdtab, psh->tracefd, str, len); 364 369 if (!flush_it) 365 370 shfile_write(&psh->fdtab, psh->tracefd, "[too long]\n", sizeof( "[too long]\n") - 1); 366 371 errno = s; 367 372 } 368 373 -
trunk/src/kash/shtypes.h
r2546 r3438 131 131 #endif 132 132 133 /** @name Extra wide pid_t so we can safely add a sub-pid to the top. 134 * @{ */ 135 #ifndef SH_FORKED_MODE 136 typedef KI64 shpid; 137 # define SHPID_MAKE(pid, tid) ((shpid)(KU32)(pid) | (shpid)(KU32)(tid) << 32) 138 # define SHPID_GET_PID(shpid) ((pid_t)(KU32)(shpid)) 139 # define SHPID_GET_TID(shpid) ((pid_t)((shpid) >> 32)) 140 # define SHPID_PRI KI64_PRI 141 #else 142 typedef pid_t shpid; 143 # define SHPID_GET_PID(shpid) (shpid) 144 # define SHPID_PRI KI32_PRI 145 #endif 146 /** @} */ 147 133 148 #endif 134 149 -
trunk/src/kash/trap.c
r3435 r3438 80 80 static int getsigaction(shinstance *, int, shsig_t *); 81 81 82 #ifndef SH_FORKED_MODE 83 void 84 subshellinittrap(shinstance *psh, shinstance *inherit) 85 { 86 /* The forkchild calls clear_traps(), we have to emulate that here. */ 87 unsigned i; 88 memcpy(psh->sigmode, inherit->sigmode, sizeof(psh->sigmode)); 89 for (i = 0; i < K_ELEMENTS(inherit->trap); i++) { 90 const char *src = inherit->trap[i]; 91 if (!src) { 92 } else if (i > 0) { 93 setsignal(psh, i); 94 } 95 } 96 } 97 #endif 98 99 82 100 /* 83 101 * return the signal number described by `p' (as a number or a name) … … 210 228 if (*tp && **tp) { /* trap not NULL or SIG_IGN */ 211 229 INTOFF; 212 213 230 ckfree(psh, *tp); 231 *tp = NULL; 214 232 if (tp != &psh->trap[0]) 215 233 setsignal(psh, (int)(tp - psh->trap)); … … 417 435 */ 418 436 419 SH_NORETURN_1 void 420 exitshell (shinstance *psh, int status)437 int 438 exitshell2(shinstance *psh, int status) 421 439 { 422 440 struct jmploc loc1, loc2; 423 441 char *p; 424 442 425 TRACE((psh, "pid % d, exitshell(%d)\n", sh_getpid(psh), status));443 TRACE((psh, "pid %" SHPID_PRI ", exitshell(%d)\n", sh_getpid(psh), status)); 426 444 if (setjmp(loc1.loc)) { 427 445 goto l1; … … 435 453 evalstring(psh, p, 0); 436 454 } 437 l1: psh->handler = &loc2; /* probably unnecessary */ 455 l1: 456 psh->handler = &loc2; /* probably unnecessary */ 438 457 output_flushall(psh); 439 458 #if JOBS 440 459 setjobctl(psh, 0); 441 460 #endif 442 l2: sh__exit(psh, status); 461 l2: 462 return status; 463 } 464 465 SH_NORETURN_1 void 466 exitshell(shinstance *psh, int status) 467 { 468 sh__exit(psh, exitshell2(psh, status)); 443 469 /* NOTREACHED */ 444 470 } 471 -
trunk/src/kash/trap.h
r3435 r3438 37 37 /*extern int pendingsigs;*/ 38 38 39 #ifndef SH_FORKED_MODE 40 void subshellinittrap(shinstance *, shinstance *); 41 #endif 39 42 int trapcmd(struct shinstance *, int, char **); 40 43 void clear_traps(struct shinstance *); … … 44 47 void dotrap(struct shinstance *); 45 48 void setinteractive(struct shinstance *, int); 49 int exitshell2(struct shinstance *, int); 46 50 SH_NORETURN_1 void exitshell(struct shinstance *, int) SH_NORETURN_2; 51 -
trunk/src/kash/var.c
r2641 r3438 41 41 #endif 42 42 43 #include <assert.h> 43 44 #include <stddef.h> 44 45 #include <stdlib.h> … … 270 271 } 271 272 } 273 274 275 #ifndef SH_FORKED_MODE 276 /* 277 * This routine is called to copy variable state from parent to child shell. 278 */ 279 void 280 subshellinitvar(shinstance *psh, shinstance *inherit) 281 { 282 unsigned i; 283 for (i = 0; i < K_ELEMENTS(inherit->vartab); i++) { 284 struct var const *vsrc = inherit->vartab[i]; 285 if (!vsrc) { 286 } else { 287 struct var **ppdst = &psh->vartab[i]; 288 do 289 { 290 struct var *dst; 291 if (!(vsrc->flags & VSTRFIXED)) { 292 dst = (struct var *)ckmalloc(psh, sizeof(*dst)); 293 } else { 294 /* VSTRFIXED is used when the structure is a fixed allocation in 295 the shinstance structure, so scan those to find which it is: */ 296 size_t left = ((struct var *)&inherit->vartab[0] - &inherit->vatty); 297 struct var const *fixedsrc = &inherit->vatty; 298 dst = &psh->vatty; 299 while (left-- > 0) 300 if (vsrc != fixedsrc) { 301 fixedsrc++; 302 dst++; 303 } else 304 break; 305 assert(left < 256 /*whatever, just no rollover*/); 306 } 307 *dst = *vsrc; 308 309 if (!(vsrc->flags & VTEXTFIXED)) { 310 dst->text = savestr(psh, vsrc->text); 311 dst->flags &= ~VSTACK; 312 } 313 314 *ppdst = dst; 315 ppdst = &dst->next; 316 317 vsrc = vsrc->next; 318 } while (vsrc); 319 *ppdst = NULL; 320 } 321 } 322 323 /** @todo We don't always need to copy local variables. */ 324 if (inherit->localvars) { 325 struct localvar const *vsrc = inherit->localvars; 326 struct localvar **ppdst = &psh->localvars; 327 do 328 { 329 struct localvar *dst = ckmalloc(psh, sizeof(*dst)); 330 331 dst->flags = vsrc->flags & ~VSTACK; 332 if (vsrc->flags & VTEXTFIXED) 333 dst->text = savestr(psh, vsrc->text); 334 else 335 dst->text = vsrc->text; 336 337 dst->vp = find_var(psh, vsrc->vp->text, NULL, NULL); 338 assert(dst->vp); 339 340 *ppdst = dst; 341 ppdst = &dst->next; 342 343 vsrc = vsrc->next; 344 } while (vsrc); 345 } 346 } 347 #endif /* !SH_FORKED_MODE */ 272 348 273 349 /* -
trunk/src/kash/var.h
r2682 r3438 127 127 128 128 void initvar(struct shinstance *); 129 #ifndef SH_FORKED_MODE 130 void subshellinitvar(shinstance *, shinstance *); 131 #endif 129 132 void setvar(struct shinstance *, const char *, const char *, int); 130 133 void setvareq(struct shinstance *, char *, int);
Note:
See TracChangeset
for help on using the changeset viewer.