1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <nl_types.h>
35 #include <locale.h>
36 #include <signal.h>
37 #include <string.h>
38 #include <limits.h>
39 #include <errno.h>
40 #include <unistd.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <libproc.h>
44 #include <dirent.h>
45 #include <ctype.h>
46 #include <sys/time.h>
47
48 #define NOHUP_PERM (S_IRUSR | S_IWUSR)
49
50 #define NOHUP_NOEXEC 126
51 #define NOHUP_ERROR 127
52
53 #ifdef XPG4
54 #define OPTSTR ""
55 #else
56 #define OPTSTR "pFag"
57
58 static int pnohup(int, char **);
59
60 static struct ps_prochandle *g_proc;
61 static int g_wrfd;
62 static int g_rdfd;
63
64 static int g_dirty;
65 static volatile int g_interrupt = 0;
66 #endif
67
68 static int opt_p = 0;
69 static int opt_g = 0;
70 static int opt_a = 0;
71 static int opt_F = 0;
72
73 static char *pname;
74
75 static char nout[PATH_MAX] = "nohup.out";
76
77 static int
open_file(void)78 open_file(void)
79 {
80 char *home;
81 int fd;
82 int flags = O_CREAT | O_WRONLY | O_APPEND;
83
84 if ((fd = open(nout, flags, NOHUP_PERM)) < 0) {
85 if ((home = getenv("HOME")) == NULL)
86 return (-1);
87
88 if ((snprintf(nout, sizeof (nout),
89 "%s/nohup.out", home) >= sizeof (nout)) ||
90 (fd = open(nout, flags, NOHUP_PERM)) < 0) {
91 return (-1);
92 }
93
94 }
95
96 (void) fprintf(stderr, gettext("Sending output to %s\n"), nout);
97
98 return (fd);
99 }
100
101 int
main(int argc,char ** argv)102 main(int argc, char **argv)
103 {
104 int fd = -1;
105 int opt;
106 int err;
107
108 if ((pname = strrchr(argv[0], '/')) == NULL)
109 pname = argv[0];
110 else
111 argv[0] = ++pname; /* for getopt */
112
113 (void) setlocale(LC_ALL, "");
114
115 #ifndef TEXT_DOMAIN
116 #define TEXT_DOMAIN "SYS_TEST"
117 #endif
118
119 (void) textdomain(TEXT_DOMAIN);
120
121 while ((opt = getopt(argc, argv, OPTSTR)) != EOF) {
122 switch (opt) {
123 case 'p':
124 opt_p = 1;
125 break;
126 case 'F':
127 opt_F = 1;
128 break;
129 case 'a':
130 opt_a = 1;
131 break;
132 case 'g':
133 opt_g = 1;
134 break;
135 default:
136 goto usage;
137 }
138 }
139
140 argc -= optind;
141 argv += optind;
142
143 if (argc == 0)
144 goto usage; /* need at least one argument */
145
146 #ifndef XPG4
147 if (opt_p && opt_g)
148 goto usage;
149
150 if (opt_p || opt_g)
151 return (pnohup(argc, argv));
152
153 if (opt_a || opt_F)
154 goto usage; /* only valid with -p or -g */
155 #endif
156
157 argv[argc] = NULL;
158
159 (void) signal(SIGHUP, SIG_IGN); /* POSIX.2 only SIGHUP */
160 #ifndef XPG4
161 (void) signal(SIGQUIT, SIG_IGN); /* Solaris compatibility */
162 #endif
163
164 if (isatty(STDOUT_FILENO)) {
165 if ((fd = open_file()) < 0)
166 goto err;
167
168 (void) dup2(fd, STDOUT_FILENO);
169 }
170
171 if (isatty(STDERR_FILENO)) {
172 if (fd < 0 && (fd = open_file()) < 0)
173 goto err;
174
175 (void) dup2(fd, STDERR_FILENO);
176 }
177
178 if (fd >= 0)
179 (void) close(fd);
180
181 (void) execvp(argv[0], argv);
182 err = errno;
183
184 (void) freopen("/dev/tty", "w", stderr);
185 (void) fprintf(stderr, gettext("nohup: %s: %s\n"), argv[0],
186 strerror(err));
187
188 return (err == ENOENT ? NOHUP_ERROR : NOHUP_NOEXEC);
189
190 err:
191 (void) fprintf(stderr, gettext("nohup: cannot open/create "
192 "nohup.out: %s\n"), strerror(errno));
193 return (NOHUP_ERROR);
194
195 usage:
196 #ifdef XPG4
197 (void) fprintf(stderr,
198 gettext("usage: nohup command [argument ...]\n"));
199 #else
200 (void) fprintf(stderr, gettext("usage:\n"
201 "\tnohup command [argument ...]\n"
202 "\tnohup -p [-Fa] pid [pid ...]\n"
203 "\tnohup -g [-Fa] pgid [pgid ...]\n"));
204 #endif
205 return (NOHUP_ERROR);
206 }
207
208 #ifndef XPG4
209
210 /*
211 * File descriptor iteration interface.
212 */
213 typedef int proc_fd_iter_f(void *, int);
214
215 static int
Pfd_iter(struct ps_prochandle * P,proc_fd_iter_f * cb,void * data)216 Pfd_iter(struct ps_prochandle *P, proc_fd_iter_f *cb, void *data)
217 {
218 char file[64];
219 dirent_t *dentp;
220 DIR *dirp;
221 int ret = 0;
222
223 if (Pstate(P) == PS_DEAD)
224 return (-1);
225
226 (void) sprintf(file, "/proc/%d/fd", (int)Pstatus(P)->pr_pid);
227 if ((dirp = opendir(file)) == NULL)
228 return (-1);
229
230 while ((dentp = readdir(dirp)) != NULL) {
231 if (dentp->d_name[0] == '.')
232 continue;
233
234 if ((ret = cb(data, atoi(dentp->d_name))) != 0)
235 break;
236 }
237
238 (void) closedir(dirp);
239
240 return (ret);
241 }
242
243 /*ARGSUSED*/
244 static int
fd_cb(void * data,int fd)245 fd_cb(void *data, int fd)
246 {
247 struct stat64 sbuf;
248 int flags;
249 int *fdp;
250 int oflags;
251 char *file;
252 int tmpfd;
253
254 /*
255 * See if this fd refers to the controlling tty.
256 */
257 if (pr_fstat64(g_proc, fd, &sbuf) == -1 ||
258 sbuf.st_rdev != Ppsinfo(g_proc)->pr_ttydev)
259 return (0);
260
261 /*
262 * tty's opened for input are usually O_RDWR so that the program
263 * can change terminal settings. We assume that if there's a
264 * controlling tty in the STDIN_FILENO file descriptor that is
265 * effectively used only for input. If standard in gets dup'ed to
266 * other file descriptors, then we're out of luck unless the
267 * program is nice enough to fcntl it to be O_RDONLY. We close the
268 * file descriptor before we call open to handle the case that
269 * there are no available file descriptors left in the victim. If
270 * our call to pr_open fails, we try to reopen the controlling tty.
271 */
272 flags = pr_fcntl(g_proc, fd, F_GETFL, NULL);
273 if ((flags & O_ACCMODE) == O_RDONLY || fd == STDIN_FILENO) {
274 fdp = &g_rdfd;
275 oflags = O_RDONLY;
276 file = "/dev/null";
277 } else {
278 fdp = &g_wrfd;
279 oflags = O_RDWR | O_APPEND;
280 file = &nout[0];
281 }
282
283 if (*fdp < 0) {
284 (void) pr_close(g_proc, fd);
285
286 tmpfd = pr_open(g_proc, file, oflags, 0);
287
288 if (tmpfd < 0) {
289 (void) fprintf(stderr,
290 gettext("nohup: process %d cannot open %s: %s\n"),
291 Pstatus(g_proc)->pr_pid, file, strerror(errno));
292
293 goto err;
294 }
295
296 if (tmpfd != fd) {
297 (void) pr_fcntl(g_proc, tmpfd, F_DUP2FD,
298 (void *)(uintptr_t)fd);
299 (void) pr_close(g_proc, tmpfd);
300 }
301
302 *fdp = fd;
303 } else {
304 (void) pr_fcntl(g_proc, *fdp, F_DUP2FD, (void *)(uintptr_t)fd);
305 }
306
307 return (0);
308
309 err:
310 /*
311 * The victim couldn't open nohup.out so we'll have it try to reopen
312 * its terminal. If this fails, we are left with little recourse.
313 */
314 tmpfd = pr_open(g_proc, "/dev/tty", O_RDWR, 0);
315
316 if (tmpfd != fd && tmpfd >= 0) {
317 (void) pr_fcntl(g_proc, tmpfd, F_DUP2FD, (void *)(uintptr_t)fd);
318 (void) pr_close(g_proc, tmpfd);
319 }
320
321 return (1);
322 }
323
324 static int
lwp_restartable(short syscall)325 lwp_restartable(short syscall)
326 {
327 switch (syscall) {
328 case SYS_read:
329 case SYS_readv:
330 case SYS_pread:
331 case SYS_pread64:
332 case SYS_write:
333 case SYS_writev:
334 case SYS_pwrite:
335 case SYS_pwrite64:
336 case SYS_ioctl:
337 case SYS_fcntl:
338 case SYS_getmsg:
339 case SYS_getpmsg:
340 case SYS_putmsg:
341 case SYS_putpmsg:
342 case SYS_recv:
343 case SYS_recvmsg:
344 case SYS_recvfrom:
345 case SYS_send:
346 case SYS_sendmsg:
347 case SYS_sendto:
348 return (1);
349 }
350
351 return (0);
352 }
353
354 /*ARGSUSED*/
355 static int
lwp_abort(void * data,const lwpstatus_t * lsp)356 lwp_abort(void *data, const lwpstatus_t *lsp)
357 {
358 struct ps_lwphandle *L;
359 int err;
360
361 /*
362 * Continue if this lwp isn't asleep in a restartable syscall.
363 */
364 if (!(lsp->pr_flags & PR_ASLEEP) || !lwp_restartable(lsp->pr_syscall))
365 return (0);
366
367 L = Lgrab(g_proc, lsp->pr_lwpid, &err);
368 (void) Lsetrun(L, 0, PRSABORT);
369 Lfree(L);
370
371 /*
372 * Indicate that we have aborted a syscall.
373 */
374 g_dirty = 1;
375
376 return (0);
377 }
378
379 /*ARGSUSED*/
380 static int
lwp_restart(void * data,const lwpstatus_t * lsp)381 lwp_restart(void *data, const lwpstatus_t *lsp)
382 {
383 struct ps_lwphandle *L;
384 int err;
385
386 /*
387 * If any lwp is still sleeping in a restartable syscall, it means
388 * the lwp is wedged and we've screwed up.
389 */
390 if (lsp->pr_flags & PR_ASLEEP) {
391 if (!lwp_restartable(lsp->pr_syscall))
392 return (0);
393 (void) fprintf(stderr, gettext("nohup: LWP %d failed "
394 "to abort syscall (%d) in process %d\n"),
395 lsp->pr_lwpid, lsp->pr_syscall, Pstatus(g_proc)->pr_pid);
396 return (1);
397 }
398
399 if (lsp->pr_why == PR_SYSEXIT && lsp->pr_errno == EINTR) {
400 L = Lgrab(g_proc, lsp->pr_lwpid, &err);
401 (void) Lputareg(L, R_R0, ERESTART);
402 Lsync(L);
403 Lfree(L);
404 }
405
406 return (0);
407 }
408
409 static int
do_pnohup(struct ps_prochandle * P)410 do_pnohup(struct ps_prochandle *P)
411 {
412 int sig = 0;
413 struct sigaction sa;
414 const pstatus_t *psp;
415
416 psp = Pstatus(P);
417
418 /*
419 * Make sure there's a pending procfs stop directive.
420 */
421 (void) Pdstop(P);
422
423 if (Pcreate_agent(P) != 0) {
424 (void) fprintf(stderr, gettext("nohup: cannot control "
425 "process %d\n"), psp->pr_pid);
426 goto err_no_agent;
427 }
428
429 /*
430 * Set the disposition of SIGHUP and SIGQUIT to SIG_IGN. If either
431 * signal is handled by the victim, only adjust the disposition if
432 * the -a flag is set.
433 */
434 if (!opt_a && pr_sigaction(P, SIGHUP, NULL, &sa) != 0) {
435 (void) fprintf(stderr, gettext("nohup: cannot read "
436 "disposition of SIGHUP for %d\n"), psp->pr_pid);
437 goto no_sigs;
438 }
439
440 if (!opt_a && sa.sa_handler != SIG_DFL && sa.sa_handler != SIG_IGN) {
441 (void) fprintf(stderr, gettext("nohup: SIGHUP already handled "
442 "by %d; use -a to force process to ignore\n"), psp->pr_pid);
443 goto no_sigs;
444 }
445
446 if (!opt_a && pr_sigaction(P, SIGQUIT, NULL, &sa) != 0) {
447 (void) fprintf(stderr, gettext("nohup: cannot read "
448 "disposition of SIGQUIT for %d\n"), psp->pr_pid);
449 goto no_sigs;
450 }
451
452 if (!opt_a && sa.sa_handler != SIG_DFL && sa.sa_handler != SIG_IGN) {
453 (void) fprintf(stderr, gettext("nohup: SIGQUIT already handled "
454 "by %d; use -a to force process to ignore\n"), psp->pr_pid);
455 goto no_sigs;
456 }
457
458 sa.sa_handler = SIG_IGN;
459
460 if (pr_sigaction(P, SIGHUP, &sa, NULL) != 0) {
461 (void) fprintf(stderr, gettext("nohup: cannot set "
462 "disposition of SIGHUP for %d\n"), psp->pr_pid);
463 goto no_sigs;
464 }
465
466 if (pr_sigaction(P, SIGQUIT, &sa, NULL) != 0) {
467 (void) fprintf(stderr, gettext("nohup: cannot set "
468 "disposition of SIGQUIT for %d\n"), psp->pr_pid);
469 goto no_sigs;
470 }
471
472 no_sigs:
473 Pdestroy_agent(P);
474
475 /*
476 * We need to close and reassign some file descriptors, but we
477 * need to be careful about how we do it. If we send in the agent
478 * to close some fd and there's an lwp asleep in the kernel due to
479 * a syscall using that fd, then we have a problem. The normal
480 * sequence of events is the close syscall wakes up any threads
481 * that have the fd in question active (see kthread.t_activefd)
482 * and then waits for those threads to wake up and release the
483 * file descriptors (they then continue to user-land to return
484 * EBADF from the syscall). However, recall that if the agent lwp
485 * is present in a process, no other lwps can run, so if the agent
486 * lwp itself is making the call to close(2) (or something else
487 * like dup2 that involves a call to closeandsetf()) then we're in
488 * pretty bad shape. The solution is to abort and restart any lwp
489 * asleep in a syscall on the off chance that it may be using one
490 * of the file descriptors that we want to manipulate.
491 */
492
493 /*
494 * We may need to chase some lwps out of the kernel briefly, so we
495 * send SIGCONT to the process if it was previously stopped due to
496 * a job control signal, and save the current signal to repost it
497 * when we detatch from the victim. A process that is stopped due
498 * to job control will start running as soon as we send SIGCONT
499 * since there is no procfs stop command pending; we use Pdstop to
500 * post a procfs stop request (above).
501 */
502 if ((psp->pr_lwp.pr_flags & PR_STOPPED) &&
503 psp->pr_lwp.pr_why == PR_JOBCONTROL) {
504 sig = psp->pr_lwp.pr_what;
505 (void) kill(psp->pr_pid, SIGCONT);
506 (void) Pwait(P, 0);
507 }
508
509 (void) Psysexit(P, 0, 1);
510
511 /*
512 * Abort each syscall; set g_dirty if any lwp was asleep.
513 */
514 g_dirty = 0;
515 g_proc = P;
516 (void) Plwp_iter(P, lwp_abort, NULL);
517
518 if (g_dirty) {
519 /*
520 * Block until each lwp that was asleep in a syscall has
521 * wandered back up to user-land.
522 */
523 (void) Pwait(P, 0);
524
525 /*
526 * Make sure that each lwp has successfully aborted its
527 * syscall and that the syscall gets restarted when we
528 * detach later.
529 */
530 if (Plwp_iter(P, lwp_restart, NULL) != 0)
531 goto err_no_agent;
532 }
533
534 (void) Psysexit(P, 0, 0);
535
536 if (Pcreate_agent(P) != 0) {
537 (void) fprintf(stderr, gettext("nohup: cannot control "
538 "process %d\n"), psp->pr_pid);
539 goto err_no_agent;
540 }
541
542 /*
543 * See if the victim has access to the nohup.out file we created.
544 * If the user does something that would invalidate the result
545 * of this call from here until the call to pr_open, the process
546 * may be left in an inconsistent state -- we assume that the user
547 * is not intentionally trying to shoot himself in the foot.
548 */
549 if (pr_access(P, nout, R_OK | W_OK) != 0) {
550 (void) fprintf(stderr, gettext("nohup: process %d can not "
551 "access %s: %s\n"), psp->pr_pid, nout, strerror(errno));
552 goto err_agent;
553 }
554
555 /*
556 * Redirect output to the controlling tty to nohup.out and tty
557 * input to read from /dev/null.
558 */
559
560 g_wrfd = -1;
561 g_rdfd = -1;
562
563 (void) Pfd_iter(P, fd_cb, NULL);
564
565 Pdestroy_agent(P);
566 if (sig != 0)
567 (void) kill(psp->pr_pid, sig);
568
569 return (0);
570
571 err_agent:
572 Pdestroy_agent(P);
573 err_no_agent:
574 if (sig != 0)
575 (void) kill(psp->pr_pid, sig);
576 return (-1);
577 }
578
579 /*ARGSUSED*/
580 static void
intr(int sig)581 intr(int sig)
582 {
583 g_interrupt = 1;
584 }
585
586 static int
pnohup(int argc,char ** argv)587 pnohup(int argc, char **argv)
588 {
589 struct ps_prochandle *P;
590 int i, j;
591 int flag = 0;
592 int gcode;
593 int nh_fd = -1;
594 char *fname;
595 char *home;
596 int nerrs = 0;
597
598 /*
599 * Catch signals from the terminal.
600 */
601 if (sigset(SIGHUP, SIG_IGN) == SIG_DFL)
602 (void) sigset(SIGHUP, intr);
603 if (sigset(SIGINT, SIG_IGN) == SIG_DFL)
604 (void) sigset(SIGINT, intr);
605 if (sigset(SIGQUIT, SIG_IGN) == SIG_DFL)
606 (void) sigset(SIGQUIT, intr);
607 (void) sigset(SIGPIPE, intr);
608 (void) sigset(SIGTERM, intr);
609
610 if (opt_F)
611 flag |= PGRAB_FORCE;
612
613 /*
614 * Set nout to be the full path name of nohup.out and fname to be
615 * the simplified path name:
616 * nout = /cwd/nohup.out fname = nohup.out
617 * nout = $HOME/nohup.out fname = $HOME/nohup.out
618 */
619 if (getcwd(nout, sizeof (nout) - strlen("/nohup.out") - 1) != NULL) {
620 fname = &nout[strlen(nout)];
621 (void) strcpy(fname, "/nohup.out");
622 fname++;
623
624 nh_fd = open(nout, O_WRONLY | O_CREAT, NOHUP_PERM);
625 }
626
627 if (nh_fd == -1 && (home = getenv("HOME")) != NULL) {
628 if (snprintf(nout, sizeof (nout),
629 "%s/nohup.out", home) < sizeof (nout)) {
630 nh_fd = open(nout, O_WRONLY | O_CREAT, NOHUP_PERM);
631 fname = &nout[0];
632 }
633 }
634
635 if (nh_fd == -1) {
636 (void) fprintf(stderr, gettext("nohup: cannot open/create "
637 "nohup.out: %s\n"), strerror(errno));
638
639 return (NOHUP_ERROR);
640 }
641
642 if (opt_g) {
643 pid_t *pgids;
644 int npgids;
645 int success;
646
647 /*
648 * Make nohup its own process group leader so that we
649 * don't accidently send SIGSTOP to this process.
650 */
651 (void) setpgid(0, 0);
652
653 /*
654 * If a list of process group ids is specified, we want to
655 * first SIGSTOP the whole process group so that we can be
656 * sure not to miss any processes that belong to the group
657 * (it's harder to hit a moving target). We then iterate
658 * over all the processes on the system looking for
659 * members of the given process group to apply the
660 * do_pnohup function to. If the process was stopped due
661 * to our SIGSTOP, we send the process SIGCONT; if the
662 * process was already stopped, we leave it alone.
663 */
664 pgids = calloc(argc, sizeof (pid_t));
665 pgids[0] = getpid();
666 npgids = 1;
667
668 for (i = 0; i < argc; i++) {
669 dirent_t *dent;
670 DIR *dirp;
671 psinfo_t psinfo;
672 const pstatus_t *psp;
673 pid_t pgid;
674 char *end;
675 hrtime_t kill_time, stop_time;
676
677 if (isdigit(*argv[i])) {
678 pgid = strtol(argv[i], &end, 10);
679
680 /*
681 * kill(2) with pid = 0 or -1 has a special
682 * meaning, so don't let pgid be 0 or 1.
683 */
684 if (*end == '\0' && pgid > 1)
685 goto pgid_ok;
686 }
687
688 (void) fprintf(stderr, gettext("nohup: "
689 "bad process group %s\n"), argv[i]);
690 nerrs++;
691 continue;
692
693 pgid_ok:
694 /*
695 * We don't want to nohup a process group twice.
696 */
697 for (j = 0; j < npgids; j++) {
698 if (pgids[j] == pgid)
699 break;
700 }
701
702 if (j != npgids)
703 continue;
704
705 pgids[npgids++] = pgid;
706
707 /*
708 * Have the kernel stop all members of the process
709 * group; record the time we stopped the process
710 * group so that we can tell if a member stopped
711 * because of this call to kill(2) or if it was
712 * already stopped when we got here. If the user
713 * job control stops the victim between the call
714 * to gethrtime(2) and kill(2), we may send
715 * SIGCONT when we really shouldn't -- we assume
716 * that the user is not trying to shoot himself in
717 * the foot.
718 */
719 kill_time = gethrtime();
720 if (kill(-pgid, SIGSTOP) == -1) {
721 (void) fprintf(stderr, gettext("nohup: cannot "
722 "stop process group %d: %s\n"), pgid,
723 errno != ESRCH ? strerror(errno) :
724 gettext("No such process group"));
725
726 nerrs++;
727 continue;
728 }
729
730 dirp = opendir("/proc");
731 success = 0;
732 while ((dent = readdir(dirp)) != NULL && !g_interrupt) {
733 if (dent->d_name[0] == '.')
734 continue;
735
736 if (proc_arg_psinfo(dent->d_name,
737 PR_ARG_PIDS, &psinfo, &gcode) == -1)
738 continue;
739
740 if (psinfo.pr_pgid != pgid)
741 continue;
742
743 /*
744 * Ignore zombies.
745 */
746 if (psinfo.pr_nlwp == 0)
747 continue;
748
749 if ((P = proc_arg_grab(dent->d_name,
750 PR_ARG_PIDS, flag, &gcode)) == NULL) {
751 (void) fprintf(stderr, gettext("nohup: "
752 "cannot examine %s: %s\n"),
753 dent->d_name, Pgrab_error(gcode));
754
755 (void) kill(psinfo.pr_pid, SIGCONT);
756 continue;
757 }
758
759 /*
760 * This implicitly restarts any process that
761 * was stopped via job control any time after
762 * the call to kill(2). This is the desired
763 * behavior since nohup is busy trying to
764 * disassociate a process from its controlling
765 * terminal.
766 */
767 psp = Pstatus(P);
768 if (psp->pr_lwp.pr_why == PR_JOBCONTROL) {
769 stop_time =
770 psp->pr_lwp.pr_tstamp.tv_sec;
771 stop_time *= (hrtime_t)NANOSEC;
772 stop_time +=
773 psp->pr_lwp.pr_tstamp.tv_nsec;
774 } else {
775 stop_time = 0;
776 }
777
778 if (do_pnohup(P) == 0)
779 success = 1;
780
781 /*
782 * If the process was stopped because of
783 * our call to kill(2) (i.e. if it stopped
784 * some time after kill_time) then restart
785 * the process.
786 */
787 if (kill_time <= stop_time)
788 (void) kill(psinfo.pr_pid, SIGCONT);
789
790 Prelease(P, 0);
791 }
792
793 /*
794 * If we didn't successfully nohup any member of the
795 * process group.
796 */
797 if (!success)
798 nerrs++;
799
800 (void) closedir(dirp);
801 }
802 } else {
803 for (i = 0; i < argc && !g_interrupt; i++) {
804 if ((P = proc_arg_grab(argv[i], PR_ARG_PIDS, flag,
805 &gcode)) == NULL) {
806 (void) fprintf(stderr,
807 gettext("nohup: cannot examine %s: %s\n"),
808 argv[i], Pgrab_error(gcode));
809
810 nerrs++;
811 continue;
812 }
813
814 if (do_pnohup(P) != 0)
815 nerrs++;
816
817 Prelease(P, 0);
818 }
819 }
820
821 (void) close(nh_fd);
822
823 if (argc == nerrs)
824 return (NOHUP_ERROR);
825
826 (void) fprintf(stderr, gettext("Sending output to %s\n"), fname);
827
828 return (0);
829 }
830
831 #endif /* !XPG4 */
832