1 /* $OpenBSD: proc.c,v 1.33 2019/06/28 13:34:58 deraadt Exp $ */ 2 /* $NetBSD: proc.c,v 1.9 1995/04/29 23:21:33 mycroft Exp $ */ 3 4 /*- 5 * Copyright (c) 1980, 1991, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/types.h> 34 #include <sys/wait.h> 35 #include <errno.h> 36 #include <unistd.h> 37 #include <limits.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <stdarg.h> 41 42 #include "csh.h" 43 #include "dir.h" 44 #include "proc.h" 45 #include "extern.h" 46 47 #define BIGINDEX 9 /* largest desirable job index */ 48 49 static struct rusage zru; 50 51 static void pflushall(void); 52 static void pflush(struct process *); 53 static void pclrcurr(struct process *); 54 static void padd(struct command *); 55 static int pprint(struct process *, int); 56 static void ptprint(struct process *); 57 static void pads(Char *); 58 static void pkill(Char **v, int); 59 static struct process 60 *pgetcurr(struct process *); 61 static void okpcntl(void); 62 63 /* 64 * pchild - called at interrupt level by the SIGCHLD signal 65 * indicating that at least one child has terminated or stopped 66 * thus at least one wait system call will definitely return a 67 * childs status. Top level routines (like pwait) must be sure 68 * to mask interrupts when playing with the proclist data structures! 69 */ 70 /* ARGUSED */ 71 void 72 pchild(int notused) 73 { 74 struct process *pp; 75 struct process *fp; 76 int pid; 77 extern int insource; 78 int save_errno = errno; 79 int w; 80 int jobflags; 81 struct rusage ru; 82 83 loop: 84 errno = 0; /* reset, just in case */ 85 pid = wait3(&w, 86 (setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG), &ru); 87 88 if (pid <= 0) { 89 if (errno == EINTR) { 90 errno = 0; 91 goto loop; 92 } 93 pnoprocesses = pid == -1; 94 errno = save_errno; 95 return; 96 } 97 for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) 98 if (pid == pp->p_pid) 99 goto found; 100 goto loop; 101 found: 102 if (pid == atoi(short2str(value(STRchild)))) 103 unsetv(STRchild); 104 pp->p_flags &= ~(PRUNNING | PSTOPPED | PREPORTED); 105 if (WIFSTOPPED(w)) { 106 pp->p_flags |= PSTOPPED; 107 pp->p_reason = WSTOPSIG(w); 108 } 109 else { 110 if (pp->p_flags & (PTIME | PPTIME) || adrof(STRtime)) 111 (void) clock_gettime(CLOCK_MONOTONIC, &pp->p_etime); 112 113 pp->p_rusage = ru; 114 if (WIFSIGNALED(w)) { 115 if (WTERMSIG(w) == SIGINT) 116 pp->p_flags |= PINTERRUPTED; 117 else 118 pp->p_flags |= PSIGNALED; 119 if (WCOREDUMP(w)) 120 pp->p_flags |= PDUMPED; 121 pp->p_reason = WTERMSIG(w); 122 } 123 else { 124 pp->p_reason = WEXITSTATUS(w); 125 if (pp->p_reason != 0) 126 pp->p_flags |= PAEXITED; 127 else 128 pp->p_flags |= PNEXITED; 129 } 130 } 131 jobflags = 0; 132 fp = pp; 133 do { 134 if ((fp->p_flags & (PPTIME | PRUNNING | PSTOPPED)) == 0 && 135 !child && adrof(STRtime) && 136 fp->p_rusage.ru_utime.tv_sec + fp->p_rusage.ru_stime.tv_sec 137 >= atoi(short2str(value(STRtime)))) 138 fp->p_flags |= PTIME; 139 jobflags |= fp->p_flags; 140 } while ((fp = fp->p_friends) != pp); 141 pp->p_flags &= ~PFOREGND; 142 if (pp == pp->p_friends && (pp->p_flags & PPTIME)) { 143 pp->p_flags &= ~PPTIME; 144 pp->p_flags |= PTIME; 145 } 146 if ((jobflags & (PRUNNING | PREPORTED)) == 0) { 147 fp = pp; 148 do { 149 if (fp->p_flags & PSTOPPED) 150 fp->p_flags |= PREPORTED; 151 } while ((fp = fp->p_friends) != pp); 152 while (fp->p_pid != fp->p_jobid) 153 fp = fp->p_friends; 154 if (jobflags & PSTOPPED) { 155 if (pcurrent && pcurrent != fp) 156 pprevious = pcurrent; 157 pcurrent = fp; 158 } 159 else 160 pclrcurr(fp); 161 if (jobflags & PFOREGND) { 162 if (jobflags & (PSIGNALED | PSTOPPED | PPTIME) || 163 !eq(dcwd->di_name, fp->p_cwd->di_name)) { 164 ; /* print in pjwait */ 165 } 166 /* PWP: print a newline after ^C */ 167 else if (jobflags & PINTERRUPTED) { 168 (void) vis_fputc('\r' | QUOTE, cshout); 169 (void) fputc('\n', cshout); 170 } 171 } 172 else { 173 if (jobflags & PNOTIFY || adrof(STRnotify)) { 174 (void) vis_fputc('\r' | QUOTE, cshout); 175 (void) fputc('\n', cshout); 176 (void) pprint(pp, NUMBER | NAME | REASON); 177 if ((jobflags & PSTOPPED) == 0) 178 pflush(pp); 179 } 180 else { 181 fp->p_flags |= PNEEDNOTE; 182 neednote++; 183 } 184 } 185 } 186 goto loop; 187 } 188 189 void 190 pnote(void) 191 { 192 struct process *pp; 193 int flags; 194 sigset_t sigset, osigset; 195 196 neednote = 0; 197 sigemptyset(&sigset); 198 sigaddset(&sigset, SIGCHLD); 199 for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) { 200 if (pp->p_flags & PNEEDNOTE) { 201 sigprocmask(SIG_BLOCK, &sigset, &osigset); 202 pp->p_flags &= ~PNEEDNOTE; 203 flags = pprint(pp, NUMBER | NAME | REASON); 204 if ((flags & (PRUNNING | PSTOPPED)) == 0) 205 pflush(pp); 206 sigprocmask(SIG_SETMASK, &osigset, NULL); 207 } 208 } 209 } 210 211 /* 212 * pwait - wait for current job to terminate, maintaining integrity 213 * of current and previous job indicators. 214 */ 215 void 216 pwait(void) 217 { 218 struct process *fp, *pp; 219 sigset_t sigset, osigset; 220 221 /* 222 * Here's where dead procs get flushed. 223 */ 224 sigemptyset(&sigset); 225 sigaddset(&sigset, SIGCHLD); 226 sigprocmask(SIG_BLOCK, &sigset, &osigset); 227 for (pp = (fp = &proclist)->p_next; pp != NULL; pp = (fp = pp)->p_next) 228 if (pp->p_pid == 0) { 229 fp->p_next = pp->p_next; 230 free(pp->p_command); 231 if (pp->p_cwd && --pp->p_cwd->di_count == 0) 232 if (pp->p_cwd->di_next == 0) 233 dfree(pp->p_cwd); 234 free(pp); 235 pp = fp; 236 } 237 sigprocmask(SIG_SETMASK, &osigset, NULL); 238 pjwait(pcurrjob); 239 } 240 241 242 /* 243 * pjwait - wait for a job to finish or become stopped 244 * It is assumed to be in the foreground state (PFOREGND) 245 */ 246 void 247 pjwait(struct process *pp) 248 { 249 struct process *fp; 250 int jobflags, reason; 251 sigset_t sigset, osigset; 252 253 while (pp->p_pid != pp->p_jobid) 254 pp = pp->p_friends; 255 fp = pp; 256 257 do { 258 if ((fp->p_flags & (PFOREGND | PRUNNING)) == PRUNNING) 259 (void) fprintf(csherr, "BUG: waiting for background job!\n"); 260 } while ((fp = fp->p_friends) != pp); 261 /* 262 * Now keep pausing as long as we are not interrupted (SIGINT), and the 263 * target process, or any of its friends, are running 264 */ 265 fp = pp; 266 sigemptyset(&sigset); 267 sigaddset(&sigset, SIGCHLD); 268 sigprocmask(SIG_BLOCK, &sigset, &osigset); 269 for (;;) { 270 sigemptyset(&sigset); 271 sigaddset(&sigset, SIGCHLD); 272 sigprocmask(SIG_BLOCK, &sigset, NULL); 273 jobflags = 0; 274 do 275 jobflags |= fp->p_flags; 276 while ((fp = (fp->p_friends)) != pp); 277 if ((jobflags & PRUNNING) == 0) 278 break; 279 sigset = osigset; 280 sigdelset(&sigset, SIGCHLD); 281 sigsuspend(&sigset); 282 } 283 sigprocmask(SIG_SETMASK, &osigset, NULL); 284 if (tpgrp > 0) /* get tty back */ 285 (void) tcsetpgrp(FSHTTY, tpgrp); 286 if ((jobflags & (PSIGNALED | PSTOPPED | PTIME)) || 287 !eq(dcwd->di_name, fp->p_cwd->di_name)) { 288 if (jobflags & PSTOPPED) { 289 (void) fputc('\n', cshout); 290 if (adrof(STRlistjobs)) { 291 Char *jobcommand[3]; 292 293 jobcommand[0] = STRjobs; 294 if (eq(value(STRlistjobs), STRlong)) 295 jobcommand[1] = STRml; 296 else 297 jobcommand[1] = NULL; 298 jobcommand[2] = NULL; 299 300 dojobs(jobcommand, NULL); 301 (void) pprint(pp, SHELLDIR); 302 } 303 else 304 (void) pprint(pp, AREASON | SHELLDIR); 305 } 306 else 307 (void) pprint(pp, AREASON | SHELLDIR); 308 } 309 if ((jobflags & (PINTERRUPTED | PSTOPPED)) && setintr && 310 (!gointr || !eq(gointr, STRminus))) { 311 if ((jobflags & PSTOPPED) == 0) 312 pflush(pp); 313 pintr1(0); 314 /* NOTREACHED */ 315 } 316 reason = 0; 317 fp = pp; 318 do { 319 if (fp->p_reason) 320 reason = fp->p_flags & (PSIGNALED | PINTERRUPTED) ? 321 fp->p_reason | META : fp->p_reason; 322 } while ((fp = fp->p_friends) != pp); 323 if ((reason != 0) && (adrof(STRprintexitvalue))) { 324 (void) fprintf(cshout, "Exit %d\n", reason); 325 } 326 set(STRstatus, putn(reason)); 327 if (reason && exiterr) 328 exitstat(); 329 pflush(pp); 330 } 331 332 /* 333 * dowait - wait for all processes to finish 334 */ 335 void 336 /*ARGSUSED*/ 337 dowait(Char **v, struct command *t) 338 { 339 struct process *pp; 340 sigset_t sigset, osigset; 341 342 pjobs++; 343 sigemptyset(&sigset); 344 sigaddset(&sigset, SIGCHLD); 345 sigprocmask(SIG_BLOCK, &sigset, &osigset); 346 loop: 347 for (pp = proclist.p_next; pp; pp = pp->p_next) 348 if (pp->p_pid && /* pp->p_pid == pp->p_jobid && */ 349 pp->p_flags & PRUNNING) { 350 sigemptyset(&sigset); 351 sigsuspend(&sigset); 352 goto loop; 353 } 354 sigprocmask(SIG_SETMASK, &osigset, NULL); 355 pjobs = 0; 356 } 357 358 /* 359 * pflushall - flush all jobs from list (e.g. at fork()) 360 */ 361 static void 362 pflushall(void) 363 { 364 struct process *pp; 365 366 for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) 367 if (pp->p_pid) 368 pflush(pp); 369 } 370 371 /* 372 * pflush - flag all process structures in the same job as the 373 * the argument process for deletion. The actual free of the 374 * space is not done here since pflush is called at interrupt level. 375 */ 376 static void 377 pflush(struct process *pp) 378 { 379 struct process *np; 380 int idx; 381 382 if (pp->p_pid == 0) { 383 (void) fprintf(csherr, "BUG: process flushed twice"); 384 return; 385 } 386 while (pp->p_pid != pp->p_jobid) 387 pp = pp->p_friends; 388 pclrcurr(pp); 389 if (pp == pcurrjob) 390 pcurrjob = 0; 391 idx = pp->p_index; 392 np = pp; 393 do { 394 np->p_index = np->p_pid = 0; 395 np->p_flags &= ~PNEEDNOTE; 396 } while ((np = np->p_friends) != pp); 397 if (idx == pmaxindex) { 398 for (np = proclist.p_next, idx = 0; np; np = np->p_next) 399 if (np->p_index > idx) 400 idx = np->p_index; 401 pmaxindex = idx; 402 } 403 } 404 405 /* 406 * pclrcurr - make sure the given job is not the current or previous job; 407 * pp MUST be the job leader 408 */ 409 static void 410 pclrcurr(struct process *pp) 411 { 412 413 if (pp == pcurrent) 414 if (pprevious != NULL) { 415 pcurrent = pprevious; 416 pprevious = pgetcurr(pp); 417 } 418 else { 419 pcurrent = pgetcurr(pp); 420 pprevious = pgetcurr(pp); 421 } 422 else if (pp == pprevious) 423 pprevious = pgetcurr(pp); 424 } 425 426 /* +4 here is 1 for '\0', 1 ea for << >& >> */ 427 static Char command[PMAXLEN + 4]; 428 static int cmdlen; 429 static Char *cmdp; 430 431 /* 432 * palloc - allocate a process structure and fill it up. 433 * an important assumption is made that the process is running. 434 */ 435 void 436 palloc(int pid, struct command *t) 437 { 438 struct process *pp; 439 int i; 440 441 pp = xcalloc(1, (size_t) sizeof(struct process)); 442 pp->p_pid = pid; 443 pp->p_flags = t->t_dflg & F_AMPERSAND ? PRUNNING : PRUNNING | PFOREGND; 444 if (t->t_dflg & F_TIME) 445 pp->p_flags |= PPTIME; 446 cmdp = command; 447 cmdlen = 0; 448 padd(t); 449 *cmdp++ = 0; 450 if (t->t_dflg & F_PIPEOUT) { 451 pp->p_flags |= PPOU; 452 if (t->t_dflg & F_STDERR) 453 pp->p_flags |= PERR; 454 } 455 pp->p_command = Strsave(command); 456 if (pcurrjob) { 457 struct process *fp; 458 459 /* careful here with interrupt level */ 460 pp->p_cwd = 0; 461 pp->p_index = pcurrjob->p_index; 462 pp->p_friends = pcurrjob; 463 pp->p_jobid = pcurrjob->p_pid; 464 for (fp = pcurrjob; fp->p_friends != pcurrjob; fp = fp->p_friends) 465 continue; 466 fp->p_friends = pp; 467 } 468 else { 469 pcurrjob = pp; 470 pp->p_jobid = pid; 471 pp->p_friends = pp; 472 pp->p_cwd = dcwd; 473 dcwd->di_count++; 474 if (pmaxindex < BIGINDEX) 475 pp->p_index = ++pmaxindex; 476 else { 477 struct process *np; 478 479 for (i = 1;; i++) { 480 for (np = proclist.p_next; np; np = np->p_next) 481 if (np->p_index == i) 482 goto tryagain; 483 pp->p_index = i; 484 if (i > pmaxindex) 485 pmaxindex = i; 486 break; 487 tryagain:; 488 } 489 } 490 if (pcurrent == NULL) 491 pcurrent = pp; 492 else if (pprevious == NULL) 493 pprevious = pp; 494 } 495 pp->p_next = proclist.p_next; 496 proclist.p_next = pp; 497 (void) clock_gettime(CLOCK_MONOTONIC, &pp->p_btime); 498 } 499 500 static void 501 padd(struct command *t) 502 { 503 Char **argp; 504 505 if (t == 0) 506 return; 507 switch (t->t_dtyp) { 508 509 case NODE_PAREN: 510 pads(STRLparensp); 511 padd(t->t_dspr); 512 pads(STRspRparen); 513 break; 514 515 case NODE_COMMAND: 516 for (argp = t->t_dcom; *argp; argp++) { 517 pads(*argp); 518 if (argp[1]) 519 pads(STRspace); 520 } 521 break; 522 523 case NODE_OR: 524 case NODE_AND: 525 case NODE_PIPE: 526 case NODE_LIST: 527 padd(t->t_dcar); 528 switch (t->t_dtyp) { 529 case NODE_OR: 530 pads(STRspor2sp); 531 break; 532 case NODE_AND: 533 pads(STRspand2sp); 534 break; 535 case NODE_PIPE: 536 pads(STRsporsp); 537 break; 538 case NODE_LIST: 539 pads(STRsemisp); 540 break; 541 } 542 padd(t->t_dcdr); 543 return; 544 } 545 if ((t->t_dflg & F_PIPEIN) == 0 && t->t_dlef) { 546 pads((t->t_dflg & F_READ) ? STRspLarrow2sp : STRspLarrowsp); 547 pads(t->t_dlef); 548 } 549 if ((t->t_dflg & F_PIPEOUT) == 0 && t->t_drit) { 550 pads((t->t_dflg & F_APPEND) ? STRspRarrow2 : STRspRarrow); 551 if (t->t_dflg & F_STDERR) 552 pads(STRand); 553 pads(STRspace); 554 pads(t->t_drit); 555 } 556 } 557 558 static void 559 pads(Char *cp) 560 { 561 int i; 562 563 /* 564 * Avoid the Quoted Space alias hack! Reported by: 565 * sam@john-bigboote.ICS.UCI.EDU (Sam Horrocks) 566 */ 567 if (cp[0] == STRQNULL[0]) 568 cp++; 569 570 i = Strlen(cp); 571 572 if (cmdlen >= PMAXLEN) 573 return; 574 if (cmdlen + i >= PMAXLEN) { 575 (void) Strlcpy(cmdp, STRsp3dots, PMAXLEN - cmdlen); 576 cmdlen = PMAXLEN; 577 cmdp += 4; 578 return; 579 } 580 (void) Strlcpy(cmdp, cp, PMAXLEN - cmdlen); 581 cmdp += i; 582 cmdlen += i; 583 } 584 585 /* 586 * psavejob - temporarily save the current job on a one level stack 587 * so another job can be created. Used for { } in exp6 588 * and `` in globbing. 589 */ 590 void 591 psavejob(void) 592 { 593 594 pholdjob = pcurrjob; 595 pcurrjob = NULL; 596 } 597 598 /* 599 * prestjob - opposite of psavejob. This may be missed if we are interrupted 600 * somewhere, but pendjob cleans up anyway. 601 */ 602 void 603 prestjob(void) 604 { 605 606 pcurrjob = pholdjob; 607 pholdjob = NULL; 608 } 609 610 /* 611 * pendjob - indicate that a job (set of commands) has been completed 612 * or is about to begin. 613 */ 614 void 615 pendjob(void) 616 { 617 struct process *pp, *tp; 618 619 if (pcurrjob && (pcurrjob->p_flags & (PFOREGND | PSTOPPED)) == 0) { 620 pp = pcurrjob; 621 while (pp->p_pid != pp->p_jobid) 622 pp = pp->p_friends; 623 (void) fprintf(cshout, "[%d]", pp->p_index); 624 tp = pp; 625 do { 626 (void) fprintf(cshout, " %d", pp->p_pid); 627 pp = pp->p_friends; 628 } while (pp != tp); 629 (void) fputc('\n', cshout); 630 } 631 pholdjob = pcurrjob = 0; 632 } 633 634 /* 635 * pprint - print a job 636 */ 637 static int 638 pprint(struct process *pp, bool flag) 639 { 640 int status, reason; 641 struct process *tp; 642 int jobflags, pstatus; 643 bool hadnl = 1; /* did we just have a newline */ 644 645 (void) fpurge(cshout); 646 647 while (pp->p_pid != pp->p_jobid) 648 pp = pp->p_friends; 649 if (pp == pp->p_friends && (pp->p_flags & PPTIME)) { 650 pp->p_flags &= ~PPTIME; 651 pp->p_flags |= PTIME; 652 } 653 tp = pp; 654 status = reason = -1; 655 jobflags = 0; 656 do { 657 jobflags |= pp->p_flags; 658 pstatus = pp->p_flags & PALLSTATES; 659 if (tp != pp && !hadnl && !(flag & FANCY) && 660 ((pstatus == status && pp->p_reason == reason) || 661 !(flag & REASON))) { 662 (void) fputc(' ', cshout); 663 hadnl = 0; 664 } 665 else { 666 if (tp != pp && !hadnl) { 667 (void) fputc('\n', cshout); 668 hadnl = 1; 669 } 670 if (flag & NUMBER) { 671 if (pp == tp) 672 (void) fprintf(cshout, "[%d]%s %c ", pp->p_index, 673 pp->p_index < 10 ? " " : "", 674 pp == pcurrent ? '+' : 675 (pp == pprevious ? '-' : ' ')); 676 else 677 (void) fprintf(cshout, " "); 678 hadnl = 0; 679 } 680 if (flag & FANCY) { 681 (void) fprintf(cshout, "%5d ", pp->p_pid); 682 hadnl = 0; 683 } 684 if (flag & (REASON | AREASON)) { 685 int width = 0; 686 if (flag & NAME) 687 width = -23; 688 if (pstatus == status) 689 if (pp->p_reason == reason) { 690 (void) fprintf(cshout, "%*s", width, ""); 691 hadnl = 0; 692 goto prcomd; 693 } 694 else 695 reason = pp->p_reason; 696 else { 697 status = pstatus; 698 reason = pp->p_reason; 699 } 700 switch (status) { 701 702 case PRUNNING: 703 (void) fprintf(cshout, "%*s", width, "Running "); 704 hadnl = 0; 705 break; 706 707 case PINTERRUPTED: 708 case PSTOPPED: 709 case PSIGNALED: 710 /* 711 * tell what happened to the background job 712 * From: Michael Schroeder 713 * <mlschroe@immd4.informatik.uni-erlangen.de> 714 */ 715 if ((flag & REASON) 716 || ((flag & AREASON) 717 && reason != SIGINT 718 && (reason != SIGPIPE 719 || (pp->p_flags & PPOU) == 0))) { 720 (void) fprintf(cshout, "%*s", width, 721 sys_siglist[(unsigned char) 722 pp->p_reason]); 723 hadnl = 0; 724 } 725 break; 726 727 case PNEXITED: 728 case PAEXITED: 729 if (flag & REASON) { 730 if (pp->p_reason) 731 (void) fprintf(cshout, "Exit %-18d", pp->p_reason); 732 else 733 (void) fprintf(cshout, "%*s", width, "Done"); 734 hadnl = 0; 735 } 736 break; 737 738 default: 739 (void) fprintf(csherr, "BUG: status=%-9o", status); 740 } 741 } 742 } 743 prcomd: 744 if (flag & NAME) { 745 (void) fprintf(cshout, "%s", vis_str(pp->p_command)); 746 if (pp->p_flags & PPOU) 747 (void) fprintf(cshout, " |"); 748 if (pp->p_flags & PERR) 749 (void) fputc('&', cshout); 750 hadnl = 0; 751 } 752 if (flag & (REASON | AREASON) && pp->p_flags & PDUMPED) { 753 (void) fprintf(cshout, " (core dumped)"); 754 hadnl = 0; 755 } 756 if (tp == pp->p_friends) { 757 if (flag & AMPERSAND) { 758 (void) fprintf(cshout, " &"); 759 hadnl = 0; 760 } 761 if (flag & JOBDIR && 762 !eq(tp->p_cwd->di_name, dcwd->di_name)) { 763 (void) fprintf(cshout, " (wd: "); 764 dtildepr(value(STRhome), tp->p_cwd->di_name); 765 (void) fputc(')', cshout); 766 hadnl = 0; 767 } 768 } 769 if (pp->p_flags & PPTIME && !(status & (PSTOPPED | PRUNNING))) { 770 if (!hadnl) 771 (void) fprintf(cshout, "\n\t"); 772 prusage(&zru, &pp->p_rusage, &pp->p_etime, 773 &pp->p_btime); 774 hadnl = 1; 775 } 776 if (tp == pp->p_friends) { 777 if (!hadnl) { 778 (void) fputc('\n', cshout); 779 hadnl = 1; 780 } 781 if (flag & SHELLDIR && !eq(tp->p_cwd->di_name, dcwd->di_name)) { 782 (void) fprintf(cshout, "(wd now: "); 783 dtildepr(value(STRhome), dcwd->di_name); 784 (void) fprintf(cshout, ")\n"); 785 hadnl = 1; 786 } 787 } 788 } while ((pp = pp->p_friends) != tp); 789 if (jobflags & PTIME && (jobflags & (PSTOPPED | PRUNNING)) == 0) { 790 if (jobflags & NUMBER) 791 (void) fprintf(cshout, " "); 792 ptprint(tp); 793 hadnl = 1; 794 } 795 (void) fflush(cshout); 796 return (jobflags); 797 } 798 799 static void 800 ptprint(struct process *tp) 801 { 802 struct timespec tetime, diff; 803 static struct timespec ztime; 804 struct rusage ru; 805 static struct rusage zru; 806 struct process *pp = tp; 807 808 ru = zru; 809 tetime = ztime; 810 do { 811 ruadd(&ru, &pp->p_rusage); 812 timespecsub(&pp->p_etime, &pp->p_btime, &diff); 813 if (timespeccmp(&diff, &tetime, >)) 814 tetime = diff; 815 } while ((pp = pp->p_friends) != tp); 816 prusage(&zru, &ru, &tetime, &ztime); 817 } 818 819 /* 820 * dojobs - print all jobs 821 */ 822 void 823 /*ARGSUSED*/ 824 dojobs(Char **v, struct command *t) 825 { 826 struct process *pp; 827 int flag = NUMBER | NAME | REASON; 828 int i; 829 830 if (chkstop) 831 chkstop = 2; 832 if (*++v) { 833 if (v[1] || !eq(*v, STRml)) 834 stderror(ERR_JOBS); 835 flag |= FANCY | JOBDIR; 836 } 837 for (i = 1; i <= pmaxindex; i++) 838 for (pp = proclist.p_next; pp; pp = pp->p_next) 839 if (pp->p_index == i && pp->p_pid == pp->p_jobid) { 840 pp->p_flags &= ~PNEEDNOTE; 841 if (!(pprint(pp, flag) & (PRUNNING | PSTOPPED))) 842 pflush(pp); 843 break; 844 } 845 } 846 847 /* 848 * dofg - builtin - put the job into the foreground 849 */ 850 void 851 /*ARGSUSED*/ 852 dofg(Char **v, struct command *t) 853 { 854 struct process *pp; 855 856 okpcntl(); 857 ++v; 858 do { 859 pp = pfind(*v); 860 pstart(pp, 1); 861 pjwait(pp); 862 } while (*v && *++v); 863 } 864 865 /* 866 * %... - builtin - put the job into the foreground 867 */ 868 void 869 /*ARGSUSED*/ 870 dofg1(Char **v, struct command *t) 871 { 872 struct process *pp; 873 874 okpcntl(); 875 pp = pfind(v[0]); 876 pstart(pp, 1); 877 pjwait(pp); 878 } 879 880 /* 881 * dobg - builtin - put the job into the background 882 */ 883 void 884 /*ARGSUSED*/ 885 dobg(Char **v, struct command *t) 886 { 887 struct process *pp; 888 889 okpcntl(); 890 ++v; 891 do { 892 pp = pfind(*v); 893 pstart(pp, 0); 894 } while (*v && *++v); 895 } 896 897 /* 898 * %... & - builtin - put the job into the background 899 */ 900 void 901 /*ARGSUSED*/ 902 dobg1(Char **v, struct command *t) 903 { 904 struct process *pp; 905 906 pp = pfind(v[0]); 907 pstart(pp, 0); 908 } 909 910 /* 911 * dostop - builtin - stop the job 912 */ 913 void 914 /*ARGSUSED*/ 915 dostop(Char **v, struct command *t) 916 { 917 pkill(++v, SIGSTOP); 918 } 919 920 /* 921 * dokill - builtin - superset of kill (1) 922 */ 923 void 924 /*ARGSUSED*/ 925 dokill(Char **v, struct command *t) 926 { 927 int signum = SIGTERM; 928 const char *errstr; 929 char *name; 930 931 v++; 932 if (v[0] && v[0][0] == '-') { 933 if (v[0][1] == 'l') { 934 if (v[1]) { 935 if (!Isdigit(v[1][0])) 936 stderror(ERR_NAME | ERR_BADSIG); 937 938 signum = strtonum(short2str(v[1]), 0, NSIG-1, &errstr); 939 if (errstr) 940 stderror(ERR_NAME | ERR_BADSIG); 941 else if (signum == 0) 942 (void) fputc('0', cshout); /* 0's symbolic name is '0' */ 943 else 944 (void) fprintf(cshout, "%s ", sys_signame[signum]); 945 } else { 946 for (signum = 1; signum < NSIG; signum++) { 947 (void) fprintf(cshout, "%s ", sys_signame[signum]); 948 if (signum == NSIG / 2) 949 (void) fputc('\n', cshout); 950 } 951 } 952 (void) fputc('\n', cshout); 953 return; 954 } 955 if (Isdigit(v[0][1])) { 956 signum = strtonum(short2str(v[0] + 1), 0, NSIG-1, &errstr); 957 if (errstr) 958 stderror(ERR_NAME | ERR_BADSIG); 959 } 960 else { 961 if (v[0][1] == 's' && (Isspace(v[0][2]) || v[0][2] == '\0')) { 962 v++; 963 name = short2str(&v[0][0]); 964 } else { 965 name = short2str(&v[0][1]); 966 } 967 968 if (v[0] == NULL || v[1] == NULL) { 969 stderror(ERR_NAME | ERR_TOOFEW); 970 return; 971 } 972 973 for (signum = 1; signum < NSIG; signum++) 974 if (!strcasecmp(sys_signame[signum], name) || 975 (strlen(name) > 3 && !strncasecmp("SIG", name, 3) && 976 !strcasecmp(sys_signame[signum], name + 3))) 977 break; 978 979 if (signum == NSIG) { 980 if (name[0] == '0') 981 signum = 0; 982 else { 983 setname(vis_str(&v[0][0])); 984 stderror(ERR_NAME | ERR_UNKSIG); 985 } 986 } 987 } 988 v++; 989 } 990 pkill(v, signum); 991 } 992 993 static void 994 pkill(Char **v, int signum) 995 { 996 struct process *pp, *np; 997 int jobflags = 0; 998 int pid, err1 = 0; 999 sigset_t sigset; 1000 Char *cp; 1001 1002 sigemptyset(&sigset); 1003 sigaddset(&sigset, SIGCHLD); 1004 if (setintr) 1005 sigaddset(&sigset, SIGINT); 1006 sigprocmask(SIG_BLOCK, &sigset, NULL); 1007 gflag = 0, tglob(v); 1008 if (gflag) { 1009 v = globall(v); 1010 if (v == 0) 1011 stderror(ERR_NAME | ERR_NOMATCH); 1012 } 1013 else { 1014 v = gargv = saveblk(v); 1015 trim(v); 1016 } 1017 1018 while (v && (cp = *v)) { 1019 if (*cp == '%') { 1020 np = pp = pfind(cp); 1021 do 1022 jobflags |= np->p_flags; 1023 while ((np = np->p_friends) != pp); 1024 switch (signum) { 1025 1026 case SIGSTOP: 1027 case SIGTSTP: 1028 case SIGTTIN: 1029 case SIGTTOU: 1030 if ((jobflags & PRUNNING) == 0) { 1031 (void) fprintf(csherr, "%s: Already suspended\n", 1032 vis_str(cp)); 1033 err1++; 1034 goto cont; 1035 } 1036 break; 1037 /* 1038 * suspend a process, kill -CONT %, then type jobs; the shell 1039 * says it is suspended, but it is running; thanks jaap.. 1040 */ 1041 case SIGCONT: 1042 pstart(pp, 0); 1043 goto cont; 1044 } 1045 if (kill(-pp->p_jobid, signum) == -1) { 1046 (void) fprintf(csherr, "%s: %s\n", vis_str(cp), 1047 strerror(errno)); 1048 err1++; 1049 } 1050 if (signum == SIGTERM || signum == SIGHUP) 1051 (void) kill(-pp->p_jobid, SIGCONT); 1052 } 1053 else if (!(Isdigit(*cp) || *cp == '-')) 1054 stderror(ERR_NAME | ERR_JOBARGS); 1055 else { 1056 char *ep; 1057 char *pidnam = short2str(cp); 1058 1059 pid = strtol(pidnam, &ep, 10); 1060 if (!*pidnam || *ep) { 1061 (void) fprintf(csherr, "%s: illegal process id\n", pidnam); 1062 err1++; 1063 goto cont; 1064 } 1065 if (kill((pid_t) pid, signum) == -1) { 1066 (void) fprintf(csherr, "%d: %s\n", pid, strerror(errno)); 1067 err1++; 1068 goto cont; 1069 } 1070 if (signum == SIGTERM || signum == SIGHUP) 1071 (void) kill((pid_t) pid, SIGCONT); 1072 } 1073 cont: 1074 v++; 1075 } 1076 blkfree(gargv); 1077 gargv = NULL; 1078 sigprocmask(SIG_UNBLOCK, &sigset, NULL); 1079 if (err1) 1080 stderror(ERR_SILENT); 1081 } 1082 1083 /* 1084 * pstart - start the job in foreground/background 1085 */ 1086 void 1087 pstart(struct process *pp, int foregnd) 1088 { 1089 struct process *np; 1090 sigset_t sigset, osigset; 1091 long jobflags = 0; 1092 1093 sigemptyset(&sigset); 1094 sigaddset(&sigset, SIGCHLD); 1095 sigprocmask(SIG_BLOCK, &sigset, &osigset); 1096 np = pp; 1097 do { 1098 jobflags |= np->p_flags; 1099 if (np->p_flags & (PRUNNING | PSTOPPED)) { 1100 np->p_flags |= PRUNNING; 1101 np->p_flags &= ~PSTOPPED; 1102 if (foregnd) 1103 np->p_flags |= PFOREGND; 1104 else 1105 np->p_flags &= ~PFOREGND; 1106 } 1107 } while ((np = np->p_friends) != pp); 1108 if (!foregnd) 1109 pclrcurr(pp); 1110 (void) pprint(pp, foregnd ? NAME | JOBDIR : NUMBER | NAME | AMPERSAND); 1111 if (foregnd) 1112 (void) tcsetpgrp(FSHTTY, pp->p_jobid); 1113 if (jobflags & PSTOPPED) 1114 (void) kill(-pp->p_jobid, SIGCONT); 1115 sigprocmask(SIG_SETMASK, &osigset, NULL); 1116 } 1117 1118 void 1119 panystop(bool neednl) 1120 { 1121 struct process *pp; 1122 1123 chkstop = 2; 1124 for (pp = proclist.p_next; pp; pp = pp->p_next) 1125 if (pp->p_flags & PSTOPPED) 1126 stderror(ERR_STOPPED, neednl ? "\n" : ""); 1127 } 1128 1129 struct process * 1130 pfind(Char *cp) 1131 { 1132 struct process *pp, *np; 1133 1134 if (cp == 0 || cp[1] == 0 || eq(cp, STRcent2) || eq(cp, STRcentplus)) { 1135 if (pcurrent == NULL) 1136 stderror(ERR_NAME | ERR_JOBCUR); 1137 return (pcurrent); 1138 } 1139 if (eq(cp, STRcentminus) || eq(cp, STRcenthash)) { 1140 if (pprevious == NULL) 1141 stderror(ERR_NAME | ERR_JOBPREV); 1142 return (pprevious); 1143 } 1144 if (Isdigit(cp[1])) { 1145 const char *errstr; 1146 int idx = strtonum(short2str(cp + 1), 1, INT_MAX, &errstr); 1147 1148 if (errstr) { 1149 stderror(ERR_NAME | ERR_NOSUCHJOB); 1150 return (0); 1151 } 1152 for (pp = proclist.p_next; pp; pp = pp->p_next) 1153 if (pp->p_index == idx && pp->p_pid == pp->p_jobid) 1154 return (pp); 1155 stderror(ERR_NAME | ERR_NOSUCHJOB); 1156 return (0); 1157 } 1158 np = NULL; 1159 for (pp = proclist.p_next; pp; pp = pp->p_next) 1160 if (pp->p_pid == pp->p_jobid) { 1161 if (cp[1] == '?') { 1162 Char *dp; 1163 1164 for (dp = pp->p_command; *dp; dp++) { 1165 if (*dp != cp[2]) 1166 continue; 1167 if (prefix(cp + 2, dp)) 1168 goto match; 1169 } 1170 } 1171 else if (prefix(cp + 1, pp->p_command)) { 1172 match: 1173 if (np) 1174 stderror(ERR_NAME | ERR_AMBIG); 1175 np = pp; 1176 } 1177 } 1178 if (np) 1179 return (np); 1180 stderror(ERR_NAME | (cp[1] == '?' ? ERR_JOBPAT : ERR_NOSUCHJOB)); 1181 /* NOTREACHED */ 1182 return (0); 1183 } 1184 1185 1186 /* 1187 * pgetcurr - find most recent job that is not pp, preferably stopped 1188 */ 1189 static struct process * 1190 pgetcurr(struct process *pp) 1191 { 1192 struct process *np; 1193 struct process *xp = NULL; 1194 1195 for (np = proclist.p_next; np; np = np->p_next) 1196 if (np != pcurrent && np != pp && np->p_pid && 1197 np->p_pid == np->p_jobid) { 1198 if (np->p_flags & PSTOPPED) 1199 return (np); 1200 if (xp == NULL) 1201 xp = np; 1202 } 1203 return (xp); 1204 } 1205 1206 /* 1207 * donotify - flag the job so as to report termination asynchronously 1208 */ 1209 void 1210 /*ARGSUSED*/ 1211 donotify(Char **v, struct command *t) 1212 { 1213 struct process *pp; 1214 1215 pp = pfind(*++v); 1216 pp->p_flags |= PNOTIFY; 1217 } 1218 1219 /* 1220 * Do the fork and whatever should be done in the child side that 1221 * should not be done if we are not forking at all (like for simple builtin's) 1222 * Also do everything that needs any signals fiddled with in the parent side 1223 * 1224 * Wanttty tells whether process and/or tty pgrps are to be manipulated: 1225 * -1: leave tty alone; inherit pgrp from parent 1226 * 0: already have tty; manipulate process pgrps only 1227 * 1: want to claim tty; manipulate process and tty pgrps 1228 * It is usually just the value of tpgrp. 1229 */ 1230 1231 int 1232 pfork(struct command *t, int wanttty) 1233 { 1234 int pid; 1235 bool ignint = 0; 1236 int pgrp; 1237 sigset_t sigset, osigset; 1238 1239 /* 1240 * A child will be uninterruptible only under very special conditions. 1241 * Remember that the semantics of '&' is implemented by disconnecting the 1242 * process from the tty so signals do not need to ignored just for '&'. 1243 * Thus signals are set to default action for children unless: we have had 1244 * an "onintr -" (then specifically ignored) we are not playing with 1245 * signals (inherit action) 1246 */ 1247 if (setintr) 1248 ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) 1249 || (gointr && eq(gointr, STRminus)); 1250 /* 1251 * Check for maximum nesting of 16 processes to avoid Forking loops 1252 */ 1253 if (child == 16) 1254 stderror(ERR_NESTING, 16); 1255 /* 1256 * Hold SIGCHLD until we have the process installed in our table. 1257 */ 1258 sigemptyset(&sigset); 1259 sigaddset(&sigset, SIGCHLD); 1260 sigprocmask(SIG_BLOCK, &sigset, &osigset); 1261 while ((pid = fork()) == -1) 1262 if (setintr == 0) 1263 (void) sleep(FORKSLEEP); 1264 else { 1265 sigprocmask(SIG_SETMASK, &osigset, NULL); 1266 stderror(ERR_NOPROC); 1267 } 1268 if (pid == 0) { 1269 settimes(); 1270 pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); 1271 pflushall(); 1272 pcurrjob = NULL; 1273 child++; 1274 if (setintr) { 1275 setintr = 0; /* until I think otherwise */ 1276 /* 1277 * Children just get blown away on SIGINT, SIGQUIT unless "onintr 1278 * -" seen. 1279 */ 1280 (void) signal(SIGINT, ignint ? SIG_IGN : SIG_DFL); 1281 (void) signal(SIGQUIT, ignint ? SIG_IGN : SIG_DFL); 1282 if (wanttty >= 0) { 1283 /* make stoppable */ 1284 (void) signal(SIGTSTP, SIG_DFL); 1285 (void) signal(SIGTTIN, SIG_DFL); 1286 (void) signal(SIGTTOU, SIG_DFL); 1287 } 1288 (void) signal(SIGTERM, parterm); 1289 } 1290 else if (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) { 1291 (void) signal(SIGINT, SIG_IGN); 1292 (void) signal(SIGQUIT, SIG_IGN); 1293 } 1294 pgetty(wanttty, pgrp); 1295 /* 1296 * Nohup and nice apply only to NODE_COMMAND's but it would be nice 1297 * (?!?) if you could say "nohup (foo;bar)" Then the parser would have 1298 * to know about nice/nohup/time 1299 */ 1300 if (t->t_dflg & F_NOHUP) 1301 (void) signal(SIGHUP, SIG_IGN); 1302 if (t->t_dflg & F_NICE) 1303 (void) setpriority(PRIO_PROCESS, 0, t->t_nice); 1304 } 1305 else { 1306 if (wanttty >= 0) 1307 (void) setpgid(pid, pcurrjob ? pcurrjob->p_jobid : pid); 1308 palloc(pid, t); 1309 sigprocmask(SIG_SETMASK, &osigset, NULL); 1310 } 1311 1312 return (pid); 1313 } 1314 1315 static void 1316 okpcntl(void) 1317 { 1318 if (tpgrp == -1) 1319 stderror(ERR_JOBCONTROL); 1320 if (tpgrp == 0) 1321 stderror(ERR_JOBCTRLSUB); 1322 } 1323 1324 /* 1325 * if we don't have vfork(), things can still go in the wrong order 1326 * resulting in the famous 'Stopped (tty output)'. But some systems 1327 * don't permit the setpgid() call, (these are more recent secure 1328 * systems such as ibm's aix). Then we'd rather print an error message 1329 * than hang the shell! 1330 * I am open to suggestions how to fix that. 1331 */ 1332 void 1333 pgetty(int wanttty, int pgrp) 1334 { 1335 sigset_t sigset, osigset; 1336 1337 /* 1338 * christos: I am blocking the tty signals till I've set things 1339 * correctly.... 1340 */ 1341 if (wanttty > 0) { 1342 sigemptyset(&sigset); 1343 sigaddset(&sigset, SIGTSTP); 1344 sigaddset(&sigset, SIGTTIN); 1345 sigaddset(&sigset, SIGTTOU); 1346 sigprocmask(SIG_BLOCK, &sigset, &osigset); 1347 } 1348 /* 1349 * From: Michael Schroeder <mlschroe@immd4.informatik.uni-erlangen.de> 1350 * Don't check for tpgrp >= 0 so even non-interactive shells give 1351 * background jobs process groups Same for the comparison in the other part 1352 * of the #ifdef 1353 */ 1354 if (wanttty >= 0) 1355 if (setpgid(0, pgrp) == -1) { 1356 (void) fprintf(csherr, "csh: setpgid error.\n"); 1357 xexit(0); 1358 } 1359 1360 if (wanttty > 0) { 1361 (void) tcsetpgrp(FSHTTY, pgrp); 1362 sigprocmask(SIG_SETMASK, &osigset, NULL); 1363 } 1364 1365 if (tpgrp > 0) 1366 tpgrp = 0; /* gave tty away */ 1367 } 1368