Lines Matching +full:- +full:j
3 /*-
10 * is granted to deal in this work without restriction, including un-
31 /* cross fingers and hope kill is killpg-endowed */
32 #define mksh_killpg(p,s) kill(-(p), (s))
61 char command[256 - (ALLOC_OVERHEAD +
65 /* Notify/print flag - j_print() argument */
67 #define JP_MEDIUM 2 /* print [job-num] -/+ command */
68 #define JP_LONG 3 /* print [job-num] -/+ pid command */
81 #define JF_SAVEDTTY 0x020 /* j->ttystat is valid */
87 #define JF_SAVEDTTYPGRP 0x800 /* j->saved_ttypgrp is valid */
121 #define JL_INVALID 2 /* non-pid, non-% job id */
149 static pid_t restore_ttypgrp = -1;
183 /* Make sure SIGCHLD isn't ignored - can do odd things under SYSV */ in j_init()
204 for (i = NELEM(tt_sigs); --i >= 0; ) { in j_init()
226 switch (p->state) { in proc_errorlevel()
228 return ((WEXITSTATUS(p->status)) & 255); in proc_errorlevel()
230 return (ksh_sigmask(WTERMSIG(p->status))); in proc_errorlevel()
289 Job *j; in j_exit() local
292 for (j = job_list; j != NULL; j = j->next) { in j_exit()
293 if (j->ppid == procpid && in j_exit()
294 (j->state == PSTOPPED || in j_exit()
295 (j->state == PRUNNING && in j_exit()
296 ((j->flags & JF_FG) || in j_exit()
299 if (j->pgrp == 0) in j_exit()
300 kill_job(j, SIGHUP); in j_exit()
302 mksh_killpg(j->pgrp, SIGHUP); in j_exit()
304 if (j->state == PSTOPPED) { in j_exit()
305 if (j->pgrp == 0) in j_exit()
306 kill_job(j, SIGCONT); in j_exit()
308 mksh_killpg(j->pgrp, SIGCONT); in j_exit()
375 for (i = NELEM(tt_sigs); --i >= 0; )
402 for (i = NELEM(tt_sigs); --i >= 0; )
406 for (i = NELEM(tt_sigs); --i >= 0; ) {
429 if (nice(ness) == -1 && (eno = errno) != 0)
452 Job *j; local
473 p->next = NULL;
474 p->state = PRUNNING;
475 p->status = 0;
476 p->pid = 0;
482 internal_errorf("exchild: XPIPEI and no last_job - pid %d",
484 j = last_job;
486 last_proc->next = p;
489 /* fills in j->job */
490 j = new_job();
495 j->flags = (flags & XXCOM) ? JF_XXCOM :
497 timerclear(&j->usrtime);
498 timerclear(&j->systime);
499 j->state = PRUNNING;
500 j->pgrp = 0;
501 j->ppid = procpid;
502 j->age = ++njobs;
503 j->proc_list = p;
504 j->coproc_id = 0;
505 last_job = j;
507 put_job(j, PJ_PAST_STOPPED);
510 vistree(p->command, sizeof(p->command), t);
525 kill_job(j, SIGKILL);
526 remove_job(j, "fork failed");
530 errorf("can't fork - try again");
532 p->pid = cldpid ? cldpid : (procpid = getpid());
539 if (j->pgrp == 0) {
541 j->pgrp = p->pid;
549 setpgid(p->pid, j->pgrp);
551 tcsetpgrp(tty_fd, j->pgrp);
573 for (forksleep = NELEM(tt_sigs); --forksleep >= 0; )
598 remove_job(j, "child");
613 if (t->type == TPIPE)
627 j_startjob(j);
629 j->coproc_id = coproc.id;
630 /* n jobs using co-process output */
632 /* j using co-process input */
633 coproc.job = (void *)j;
636 j_set_async(j);
638 shf_fprintf(shl_out, "[%d]", j->job);
639 for (p = j->proc_list; p; p = p->next)
641 (int)p->pid);
646 rv = j_waitj(j, jwflags, "jw:last proc");
666 /* no need to report error - waitlast() will do it */
669 last_job->flags |= JF_WAITING;
682 Job *j; local
689 j = last_job;
690 if (!j || !(j->flags & JF_STARTED)) {
691 if (!j)
698 /* not so arbitrary, non-zero value */
702 rv = j_waitj(j, JW_NONE, "waitlast");
716 Job *j; local
727 * wait for an unspecified job - always returns 0, so
730 for (j = job_list; j; j = j->next)
731 /* AT&T ksh will wait for stopped jobs - we don't */
732 if (j->ppid == procpid && j->state == PRUNNING)
734 if (!j) {
738 return (-1);
740 } else if ((j = j_lookup(cp, &ecode))) {
743 if (j->ppid != procpid) {
747 return (-1);
755 return (-1);
758 /* AT&T ksh will wait for stopped jobs - we don't */
759 rv = j_waitj(j, flags, "jw:waitfor");
767 *sigp = ksh_sigmask(-rv);
772 /* kill (built-in) a job */
776 Job *j; local
784 if ((j = j_lookup(cp, &ecode)) == NULL) {
792 if (j->pgrp == 0) {
794 if (kill_job(j, sig) < 0) {
800 if (j->state == PSTOPPED && (sig == SIGTERM || sig == SIGHUP))
801 mksh_killpg(j->pgrp, SIGCONT);
803 if (mksh_killpg(j->pgrp, sig) < 0) {
817 /* fg and bg built-ins: called only if Flag(FMONITOR) set */
821 Job *j; local
829 if ((j = j_lookup(cp, &ecode)) == NULL) {
835 if (j->pgrp == 0) {
837 bi_errorf("job not job-controlled");
842 shprintf("[%d] ", j->job);
845 for (p = j->proc_list; p != NULL; p = p->next) {
846 if (p->state == PSTOPPED) {
847 p->state = PRUNNING;
848 p->status = 0;
851 shf_puts(p->command, shl_stdout);
852 if (p->next)
858 j->state = PRUNNING;
860 put_job(j, PJ_PAST_STOPPED);
862 j_set_async(j);
865 if (j->state == PRUNNING) {
866 if (ttypgrp_ok && (j->flags & JF_SAVEDTTY))
867 mksh_tcset(tty_fd, &j->ttystat);
870 tcsetpgrp(tty_fd, (j->flags & JF_SAVEDTTYPGRP) ?
871 j->saved_ttypgrp : j->pgrp) < 0) {
873 if (j->flags & JF_SAVEDTTY)
878 (long)((j->flags & JF_SAVEDTTYPGRP) ?
879 j->saved_ttypgrp : j->pgrp),
884 j->flags |= JF_FG;
885 j->flags &= ~JF_KNOWN;
886 if (j == async_job)
890 if (j->state == PRUNNING && mksh_killpg(j->pgrp, SIGCONT) < 0) {
894 j->flags &= ~JF_FG;
895 if (ttypgrp_ok && (j->flags & JF_SAVEDTTY))
909 j->flags &= ~(JF_SAVEDTTY | JF_SAVEDTTYPGRP);
911 rv = j_waitj(j, JW_NONE, "jw:resume");
922 Job *j; local
925 for (j = job_list; j != NULL; j = j->next) {
927 if (j->ppid == procpid && j->state == PSTOPPED)
931 j->ppid == procpid && j->state == PRUNNING)
946 /* list jobs for jobs built-in */
952 Job *j, *tmp; local
968 if ((j = j_lookup(cp, &ecode)) == NULL) {
976 j = job_list;
978 for (; j; j = j->next) {
979 if ((!(j->flags & JF_ZOMBIE) || zflag) &&
980 (!nflag || (j->flags & JF_CHANGED))) {
981 j_print(j, how, shl_stdout);
982 if (j->state == PEXITED || j->state == PSIGNALLED)
983 j->flags |= JF_REMOVE;
988 /* Remove jobs after printing so there won't be multiple + or - jobs */
989 for (j = job_list; j; j = tmp) {
990 tmp = j->next;
991 if (j->flags & JF_REMOVE)
992 remove_job(j, Tjobs);
1000 /* list jobs for top-level notification */
1004 Job *j, *tmp; local
1010 for (j = job_list; j; j = j->next) {
1012 if (Flag(FMONITOR) && (j->flags & JF_CHANGED))
1013 j_print(j, JP_MEDIUM, shl_out);
1017 * multiple +/- jobs.
1019 if (j->state == PEXITED || j->state == PSIGNALLED)
1020 j->flags |= JF_REMOVE;
1022 for (j = job_list; j; j = tmp) {
1023 tmp = j->next;
1024 if (j->flags & JF_REMOVE) {
1025 if (j == async_job || (j->flags & JF_KNOWN)) {
1026 j->flags = (j->flags & ~JF_REMOVE) | JF_ZOMBIE;
1027 j->job = -1;
1030 remove_job(j, "notify");
1050 async_job->flags |= JF_KNOWN;
1060 * Make j the last async process
1065 j_set_async(Job *j) argument
1069 if (async_job && (async_job->flags & (JF_KNOWN|JF_ZOMBIE)) == JF_ZOMBIE)
1071 if (!(j->flags & JF_STARTED)) {
1075 async_job = j;
1076 async_pid = j->last_proc->pid;
1079 for (jl = job_list; jl; jl = jl->next)
1080 if (jl != async_job && (jl->flags & JF_ZOMBIE) &&
1081 (!oldest || jl->age < oldest->age))
1085 if (!(async_job->flags & JF_ZOMBIE) || nzombie != 1) {
1097 * Start a job: set STARTED, check for held signals and set j->last_proc
1102 j_startjob(Job *j) argument
1106 j->flags |= JF_STARTED;
1107 for (p = j->proc_list; p->next; p = p->next)
1109 j->last_proc = p;
1126 j_waitj(Job *j, argument
1138 * No auto-notify on the job we are waiting on.
1140 j->flags |= JF_WAITING;
1142 j->flags |= JF_W_ASYNCNOTIFY;
1149 while (j->state == PRUNNING ||
1150 ((flags & JW_STOPPEDWAIT) && j->state == PSTOPPED)) {
1164 int oldf = j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY);
1165 j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
1168 j->flags |= oldf;
1171 j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
1172 return (-rv);
1175 j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
1177 if (j->flags & JF_FG) {
1178 j->flags &= ~JF_FG;
1180 if (Flag(FMONITOR) && ttypgrp_ok && j->pgrp) {
1192 if (j->state == PSTOPPED &&
1193 (j->saved_ttypgrp = tcgetpgrp(tty_fd)) >= 0)
1194 j->flags |= JF_SAVEDTTYPGRP;
1199 if (j->state == PSTOPPED) {
1200 j->flags |= JF_SAVEDTTY;
1201 mksh_tcget(tty_fd, &j->ttystat);
1215 if (j->state == PEXITED && j->status == 0 &&
1216 (j->flags & JF_USETTYMODE)) {
1220 /*-
1232 if (j->state == PSTOPPED)
1233 j->flags &= ~JF_USETTYMODE;
1243 if (Flag(FMONITOR) && j->state == PSIGNALLED &&
1244 WIFSIGNALED(j->last_proc->status)) {
1247 if ((termsig = WTERMSIG(j->last_proc->status)) > 0 &&
1255 j_usrtime = j->usrtime;
1256 j_systime = j->systime;
1257 rv = j->status;
1259 if (!(p = j->proc_list)) {
1267 vp->flag = DEFINED | ISSET | INTEGER | RDONLY | ARRAY | INT_U;
1274 /* strlen(vp_pipest->name) == 10 */
1276 vp_pipest->areap);
1278 memcpy(vq->name, vp_pipest->name, 11);
1279 vp->u.array = vq;
1282 vp->areap = vp_pipest->areap;
1283 vp->ua.index = ++num;
1284 vp->flag = DEFINED | ISSET | INTEGER | RDONLY |
1287 vp->val.i = proc_errorlevel(p);
1288 if (Flag(FPIPEFAIL) && vp->val.i)
1289 rv = vp->val.i;
1290 p = p->next;
1298 } while ((p = p->next));
1303 && (!Flag(FMONITOR) || j->state != PSTOPPED)
1306 j_print(j, JP_SHORT, shl_out);
1309 if (j->state != PSTOPPED
1314 remove_job(j, where);
1329 Job *j; local
1348 for (j = job_list; j; j = j->next)
1349 if (j->ppid == procpid && !(j->flags & JF_STARTED)) {
1358 pid = waitpid(-1, &status, WNOHANG);
1361 pid = waitpid(-1, &status, (WNOHANG |
1373 * or interrupted (-1)
1381 for (j = job_list; j != NULL; j = j->next)
1382 for (p = j->proc_list; p != NULL; p = p->next)
1383 if (p->pid == pid)
1386 if (j == NULL) {
1395 timeradd(&j->usrtime, &ru1.ru_utime, &j->usrtime);
1396 timersub(&j->usrtime, &ru0.ru_utime, &j->usrtime);
1397 timeradd(&j->systime, &ru1.ru_stime, &j->systime);
1398 timersub(&j->systime, &ru0.ru_stime, &j->systime);
1400 p->status = status;
1403 p->state = PSTOPPED;
1407 p->state = j->state = PRUNNING;
1408 /* skip check_job(), no-op in this case */
1414 p->state = PSIGNALLED;
1416 p->state = PEXITED;
1419 check_job(j);
1435 * Called only when a process in j has exited/stopped (ie, called only
1443 check_job(Job *j) argument
1448 /* XXX debugging (nasty - interrupt routine using shl_out) */
1449 if (!(j->flags & JF_STARTED)) {
1451 (unsigned int)j->flags);
1456 for (p=j->proc_list; p != NULL; p = p->next) {
1457 if (p->state == PRUNNING)
1460 if (p->state > jstate)
1461 jstate = p->state;
1463 j->state = jstate;
1464 j->status = proc_errorlevel(j->last_proc);
1467 * Note when co-process dies: can't be done in j_wait() nor
1468 * remove_job() since neither may be called for non-interactive
1471 if (j->state == PEXITED || j->state == PSIGNALLED) {
1473 * No need to keep co-process input any more
1476 if (coproc.job == j) {
1487 if (j->coproc_id && j->coproc_id == coproc.id &&
1488 --coproc.njobs == 0)
1492 j->flags |= JF_CHANGED;
1494 if (Flag(FMONITOR) && !(j->flags & JF_XXCOM)) {
1497 * the user (don't want finished jobs effecting %+ or %-)
1499 if (j->state == PSTOPPED)
1500 put_job(j, PJ_ON_FRONT);
1502 (j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY)) != JF_WAITING) {
1508 for (ep = e; ep; ep = ep->oenv)
1509 if (ep->savefd && ep->savefd[2])
1510 fd = ep->savefd[2];
1518 j_print(j, JP_MEDIUM, shl_j);
1520 if (!(j->flags & JF_WAITING) && j->state != PSTOPPED)
1521 remove_job(j, "notify");
1529 !(j->flags & (JF_WAITING|JF_FG)) &&
1530 j->state != PSTOPPED) {
1531 if (j == async_job || (j->flags & JF_KNOWN)) {
1532 j->flags |= JF_ZOMBIE;
1533 j->job = -1;
1536 remove_job(j, "checkjob");
1546 j_print(Job *j, int how, struct shf *shf) argument
1565 shf_fprintf(shf, Tf_dN, (int)(j->pgrp ? j->pgrp :
1566 (j->last_proc ? j->last_proc->pid : 0)));
1569 j->flags &= ~JF_CHANGED;
1570 filler = j->job > 10 ? "\n " : "\n ";
1571 if (j == job_list)
1573 else if (j == job_list->next)
1574 jobchar = '-';
1576 for (p = j->proc_list; p != NULL;) {
1580 switch (p->state) {
1585 int stopsig = WSTOPSIG(p->status);
1592 int exitstatus = (WEXITSTATUS(p->status)) & 255;
1604 int termsig = WTERMSIG(p->status);
1606 if (WCOREDUMP(p->status))
1630 if (p == j->proc_list)
1631 shf_fprintf(shf, "[%d] %c ", j->job, jobchar);
1637 shf_fprintf(shf, "%5d ", (int)p->pid);
1652 shf_fprintf(shf, "%-20s %s%s%s", buf, p->command,
1653 p->next ? "|" : null,
1660 state = p->state;
1661 status = p->status;
1662 p = p->next;
1663 while (p && p->state == state && p->status == status) {
1665 shf_fprintf(shf, "%s%5d %-20s %s%s", filler,
1666 (int)p->pid, T1space, p->command,
1667 p->next ? "|" : null);
1669 shf_fprintf(shf, Tf__ss, p->command,
1670 p->next ? "|" : null);
1671 p = p->next;
1686 Job *j, *last_match; local
1692 /* Look for last_proc->pid (what $! returns) first... */
1693 for (j = job_list; j != NULL; j = j->next)
1694 if (j->last_proc && j->last_proc->pid == job)
1695 return (j);
1697 * ...then look for process group (this is non-POSIX,
1700 for (j = job_list; j != NULL; j = j->next)
1701 if (j->pgrp && j->pgrp == job)
1702 return (j);
1712 case '\0': /* non-standard */
1719 case '-':
1720 if (job_list != NULL && job_list->next)
1721 return (job_list->next);
1728 for (j = job_list; j != NULL; j = j->next)
1729 if (j->job == job)
1730 return (j);
1736 for (j = job_list; j != NULL; j = j->next)
1737 for (p = j->proc_list; p != NULL; p = p->next)
1738 if (strstr(p->command, cp+1) != NULL) {
1744 last_match = j;
1754 for (j = job_list; j != NULL; j = j->next)
1755 if (strncmp(cp, j->proc_list->command, len) == 0) {
1761 last_match = j;
1785 Job *newj, *j; local
1789 free_jobs = free_jobs->next;
1797 cp = alloc(sizeof(Job) - sizeof(ALLOC_ITEM), APERM);
1799 newj = (void *)(cp - sizeof(ALLOC_ITEM));
1806 j = job_list;
1807 while (j && j->job != i)
1808 j = j->next;
1809 } while (j);
1810 newj->job = i;
1827 free_procs = free_procs->next;
1841 remove_job(Job *j, const char *where) argument
1848 while (curr && curr != j) {
1849 prev = &curr->next;
1852 if (curr != j) {
1856 *prev = curr->next;
1859 for (p = j->proc_list; p != NULL; ) {
1861 p = p->next;
1862 tmp->next = free_procs;
1866 if ((j->flags & JF_ZOMBIE) && j->ppid == procpid)
1867 --nzombie;
1868 j->next = free_jobs;
1869 free_jobs = j;
1871 if (j == last_job)
1873 if (j == async_job)
1878 * put j in a particular location (taking it out job_list if it is there
1884 put_job(Job *j, int where) argument
1891 while (curr && curr != j) {
1892 prev = &curr->next;
1895 if (curr == j)
1896 *prev = curr->next;
1900 j->next = job_list;
1901 job_list = j;
1907 for (; curr && curr->state == PSTOPPED; prev = &curr->next,
1910 j->next = curr;
1911 *prev = j;
1922 kill_job(Job *j, int sig) argument
1927 for (p = j->proc_list; p != NULL; p = p->next)
1928 if (p->pid != 0)
1929 if (kill(p->pid, sig) < 0)
1930 rval = -1;
1958 "can't set close-on-exec flag", cstrerror(errno));