Changeset 3438 for trunk/src/kash/jobs.c
- Timestamp:
- Sep 9, 2020, 10:01:39 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 {
Note:
See TracChangeset
for help on using the changeset viewer.