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