diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /gnu/libexec/uucp/libunix/detach.c |
initial import of NetBSD tree
Diffstat (limited to 'gnu/libexec/uucp/libunix/detach.c')
-rw-r--r-- | gnu/libexec/uucp/libunix/detach.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/gnu/libexec/uucp/libunix/detach.c b/gnu/libexec/uucp/libunix/detach.c new file mode 100644 index 00000000000..88becf18702 --- /dev/null +++ b/gnu/libexec/uucp/libunix/detach.c @@ -0,0 +1,181 @@ +/* detach.c + Detach from the controlling terminal. + + Copyright (C) 1992, 1993, 1995 Ian Lance Taylor + + This file is part of the Taylor UUCP package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author of the program may be contacted at ian@airs.com or + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. + */ + +#include "uucp.h" + +#include "uudefs.h" +#include "system.h" +#include "sysdep.h" + +#include <errno.h> + +#if HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif + +#ifdef TIOCNOTTY +#define HAVE_TIOCNOTTY 1 +#else +#define HAVE_TIOCNOTTY 0 +#endif + +#if HAVE_FCNTL_H +#include <fcntl.h> +#else +#if HAVE_SYS_FILE_H +#include <sys/file.h> +#endif +#endif + +#ifndef O_RDONLY +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#endif + +#if HAVE_BROKEN_SETSID +#undef HAVE_SETSID +#define HAVE_SETSID 0 +#endif + +/* Detach from the controlling terminal. This is called by uucico if + it is calling out to another system, so that it can receive SIGHUP + signals from the port it calls out on. It is also called by uucico + just before it starts uuxqt, so that uuxqt is completely + independent of the terminal. */ + +void +usysdep_detach () +{ + pid_t igrp; + + /* Make sure that we can open the log file. We do this now so that, + if we can't, a message will be written to stderr. After we leave + this routine, stderr will be closed. */ + ulog (LOG_NORMAL, (const char *) NULL); + + /* Make sure we are not a process group leader. */ +#if HAVE_BSD_PGRP + igrp = getpgrp (0); +#else + igrp = getpgrp (); +#endif + + if (igrp == getpid ()) + { + boolean fignored; + pid_t ipid; + + /* Ignore SIGHUP, since our process group leader is about to + die. */ + usset_signal (SIGHUP, SIG_IGN, FALSE, &fignored); + + ipid = ixsfork (); + if (ipid < 0) + ulog (LOG_FATAL, "fork: %s", strerror (errno)); + + if (ipid != 0) + _exit (EXIT_SUCCESS); + + /* We'll always wind up as a child of process number 1, right? + Right? We have to wait for our parent to die before + reenabling SIGHUP. */ + while (getppid () != 1) + sleep (1); + + ipid = getpid (); + ulog_id (ipid); + + /* Restore SIGHUP catcher if it wasn't being ignored. */ + if (! fignored) + usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL); + + DEBUG_MESSAGE2 (DEBUG_PORT, + "usysdep_detach: Forked; old PID %ld, new pid %ld", + (long) igrp, (long) ipid); + } + +#if ! HAVE_SETSID && HAVE_TIOCNOTTY + /* Lose the original controlling terminal as well as our process + group. */ + { + int o; + + o = open ((char *) "/dev/tty", O_RDONLY); + if (o >= 0) + { + (void) ioctl (o, TIOCNOTTY, (char *) NULL); + (void) close (o); + } + } +#endif /* ! HAVE_SETSID && HAVE_TIOCNOTTY */ + + /* Close stdin, stdout and stderr and reopen them on /dev/null, to + make sure we have no connection at all to the terminal. */ + (void) close (0); + (void) close (1); + (void) close (2); + if (open ((char *) "/dev/null", O_RDONLY) != 0 + || open ((char *) "/dev/null", O_WRONLY) != 1 + || open ((char *) "/dev/null", O_WRONLY) != 2) + ulog (LOG_FATAL, "open (/dev/null): %s", strerror (errno)); + +#if HAVE_SETSID + + /* Under POSIX the setsid call creates a new session for which we + are the process group leader. It also detaches us from our + controlling terminal. */ + if (setsid () < 0) + ulog (LOG_ERROR, "setsid: %s", strerror (errno)); + +#else /* ! HAVE_SETSID */ + +#if ! HAVE_SETPGRP + #error Cannot detach from controlling terminal +#endif + + /* If we don't have setsid, we must use setpgrp. On an old System V + system setpgrp will make us the leader of a new process group and + detach the controlling terminal. On an old BSD system the call + setpgrp (0, 0) will set our process group to 0 so that we can + acquire a new controlling terminal (TIOCNOTTY may or may not have + already done that anyhow). */ +#if HAVE_BSD_PGRP + if (setpgrp (0, 0) < 0) +#else + if (setpgrp () < 0) +#endif + { + /* Some systems seem to give EPERM errors inappropriately. */ + if (errno != EPERM) + ulog (LOG_ERROR, "setpgrp: %s", strerror (errno)); + } + +#endif /* ! HAVE_SETSID */ + + /* At this point we have completely detached from our controlling + terminal. The next terminal device we open will probably become + our controlling terminal. */ +} |