/* change a Flag(*) value; takes care of special actions */ void change_flag(enum sh_flag f, int what, /* flag to change */ int newval) /* what is changing the flag (command line vs set) */ { int oldval; oldval = Flag(f); Flag(f) = newval; #ifdef JOBS if (f == FMONITOR) { if (what != OF_CMDLINE && newval != oldval) j_change(); } else #endif /* JOBS */ #ifdef EDIT if (0 # ifdef VI || f == FVI # endif /* VI */ # ifdef EMACS || f == FEMACS || f == FGMACS # endif /* EMACS */ ) { if (newval) { # ifdef VI Flag(FVI) = 0; # endif /* VI */ # ifdef EMACS Flag(FEMACS) = Flag(FGMACS) = 0; # endif /* EMACS */ Flag(f) = newval; } } else #endif /* EDIT */ /* Turning off -p? */ if (f == FPRIVILEGED && oldval && !newval) { gid_t gid = getgid(); setresgid(gid, gid, gid); setgroups(1, &gid); setresuid(ksheuid, ksheuid, ksheuid); } else if (f == FPOSIX && newval) { #ifdef BRACE_EXPAND Flag(FBRACEEXPAND) = 0 #endif /* BRACE_EXPAND */ ; } /* Changing interactive flag? */ if (f == FTALKING) { if ((what == OF_CMDLINE || what == OF_SET) && procpid == kshpid) Flag(FTALKING_I) = newval; } }
/* job cleanup before shell exit */ void j_exit(void) { /* kill stopped, and possibly running, jobs */ Job *j; int killed = 0; for (j = job_list; j != (Job *) 0; j = j->next) { if (j->ppid == procpid && (j->state == PSTOPPED || (j->state == PRUNNING && ((j->flags & JF_FG) || (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid))))) { killed = 1; if (j->pgrp == 0) kill_job(j, SIGHUP); else killpg(j->pgrp, SIGHUP); #ifdef JOBS if (j->state == PSTOPPED) { if (j->pgrp == 0) kill_job(j, SIGCONT); else killpg(j->pgrp, SIGCONT); } #endif /* JOBS */ } } if (killed) sleep(1); j_notify(); #ifdef JOBS if (kshpid == procpid && restore_ttypgrp >= 0) { /* Need to restore the tty pgrp to what it was when the * shell started up, so that the process that started us * will be able to access the tty when we are done. * Also need to restore our process group in case we are * about to do an exec so that both our parent and the * process we are to become will be able to access the tty. */ tcsetpgrp(tty_fd, restore_ttypgrp); setpgid(0, restore_ttypgrp); } if (Flag(FMONITOR)) { Flag(FMONITOR) = 0; j_change(); } #endif /* JOBS */ }
/* change a Flag(*) value; takes care of special actions */ void change_flag(enum sh_flag f, int what, unsigned int newval) { unsigned char oldval; oldval = Flag(f); Flag(f) = newval ? 1 : 0; /* needed for tristates */ #ifndef MKSH_UNEMPLOYED if (f == FMONITOR) { if (what != OF_CMDLINE && newval != oldval) j_change(); } else #endif if (( #if !MKSH_S_NOVI f == FVI || #endif f == FEMACS || f == FGMACS) && newval) { #if !MKSH_S_NOVI Flag(FVI) = #endif Flag(FEMACS) = Flag(FGMACS) = 0; Flag(f) = (unsigned char)newval; } else if (f == FPRIVILEGED && oldval && !newval) { /* Turning off -p? */ #if HAVE_SETRESUGID gid_t kshegid = getgid(); setresgid(kshegid, kshegid, kshegid); #if HAVE_SETGROUPS setgroups(1, &kshegid); #endif setresuid(ksheuid, ksheuid, ksheuid); #else seteuid(ksheuid = kshuid = getuid()); setuid(ksheuid); setegid(kshegid = kshgid = getgid()); setgid(kshegid); #endif } else if ((f == FPOSIX || f == FSH) && newval) { Flag(FPOSIX) = Flag(FSH) = Flag(FBRACEEXPAND) = 0; Flag(f) = (unsigned char)newval; } /* Changing interactive flag? */ if (f == FTALKING) { if ((what == OF_CMDLINE || what == OF_SET) && procpid == kshpid) Flag(FTALKING_I) = (unsigned char)newval; } }
/* initialize job control */ void j_init(int mflagset) { if(!child_max) child_max = sysconf(_SC_CHILD_MAX); sigemptyset(&sm_default); sigprocmask(SIG_SETMASK, &sm_default, (sigset_t *) 0); sigemptyset(&sm_sigchld); sigaddset(&sm_sigchld, SIGCHLD); setsig(&sigtraps[SIGCHLD], j_sigchld, SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP); #ifdef JOBS if (!mflagset && Flag(FTALKING)) Flag(FMONITOR) = 1; /* shl_j is used to do asynchronous notification (used in * an interrupt handler, so need a distinct shf) */ shl_j = shf_fdopen(2, SHF_WR, (struct shf *) 0); if (Flag(FMONITOR) || Flag(FTALKING)) { int i; /* the TF_SHELL_USES test is a kludge that lets us know if * if the signals have been changed by the shell. */ for (i = NELEM(tt_sigs); --i >= 0; ) { sigtraps[tt_sigs[i]].flags |= TF_SHELL_USES; /* j_change() sets this to SS_RESTORE_DFL if FMONITOR */ setsig(&sigtraps[tt_sigs[i]], SIG_IGN, SS_RESTORE_IGN|SS_FORCE); } } /* j_change() calls tty_init() */ if (Flag(FMONITOR)) j_change(); else #endif /* JOBS */ if (Flag(FTALKING)) tty_init(true); }
/* change a Flag(*) value; takes care of special actions */ void change_flag(enum sh_flag f, int what, bool newset) { unsigned char oldval; unsigned char newval = (newset ? 1 : 0); if (f == FXTRACE) { change_xtrace(newval, true); return; } oldval = Flag(f); Flag(f) = newval = (newset ? 1 : 0); #ifndef MKSH_UNEMPLOYED if (f == FMONITOR) { if (what != OF_CMDLINE && newval != oldval) j_change(); } else #endif #ifndef MKSH_NO_CMDLINE_EDITING if (( #if !MKSH_S_NOVI f == FVI || #endif f == FEMACS || f == FGMACS) && newval) { #if !MKSH_S_NOVI Flag(FVI) = #endif Flag(FEMACS) = Flag(FGMACS) = 0; Flag(f) = newval; } else #endif if (f == FPRIVILEGED && oldval && !newval) { /* Turning off -p? */ /*XXX this can probably be optimised */ kshegid = kshgid = getgid(); ksheuid = kshuid = getuid(); #if HAVE_SETRESUGID DO_SETUID(setresgid, (kshegid, kshegid, kshegid)); #if HAVE_SETGROUPS /* setgroups doesn't EAGAIN on Linux */ setgroups(1, &kshegid); #endif DO_SETUID(setresuid, (ksheuid, ksheuid, ksheuid)); #else /* !HAVE_SETRESUGID */ /* setgid, setegid, seteuid don't EAGAIN on Linux */ setgid(kshegid); #ifndef MKSH__NO_SETEUGID setegid(kshegid); #endif DO_SETUID(setuid, (ksheuid)); #ifndef MKSH__NO_SETEUGID seteuid(ksheuid); #endif #endif /* !HAVE_SETRESUGID */ } else if ((f == FPOSIX || f == FSH) && newval) { /* Turning on -o posix or -o sh? */ Flag(FBRACEEXPAND) = 0; } else if (f == FTALKING) { /* Changing interactive flag? */ if ((what == OF_CMDLINE || what == OF_SET) && procpid == kshpid) Flag(FTALKING_I) = newval; } }