diff options
author | conklin <conklin@FreeBSD.org> | 1993-08-05 18:28:27 +0000 |
---|---|---|
committer | conklin <conklin@FreeBSD.org> | 1993-08-05 18:28:27 +0000 |
commit | 9445dd12015987ffafa05df26c1bcd0f39c1dd70 (patch) | |
tree | 64cb2831b24d3f5002a9a9ec1426e82c6d6bb5d4 /gnu/libexec/uucp/libunix/detach.c | |
parent | f0d11b6bf5fa75bb5f59b57795dcd450a1bf433b (diff) | |
download | FreeBSD-src-9445dd12015987ffafa05df26c1bcd0f39c1dd70.zip FreeBSD-src-9445dd12015987ffafa05df26c1bcd0f39c1dd70.tar.gz |
Taylor UUCP 1.04
Diffstat (limited to 'gnu/libexec/uucp/libunix/detach.c')
-rw-r--r-- | gnu/libexec/uucp/libunix/detach.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/gnu/libexec/uucp/libunix/detach.c b/gnu/libexec/uucp/libunix/detach.c new file mode 100644 index 0000000..41e1969 --- /dev/null +++ b/gnu/libexec/uucp/libunix/detach.c @@ -0,0 +1,186 @@ +/* detach.c + Detach from the controlling terminal. + + Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + The author of the program may be contacted at ian@airs.com or + c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + */ + +#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 + +/* 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 () +{ +#if ! HAVE_BSD_PGRP || ! HAVE_TIOCNOTTY + + pid_t igrp; + + /* First make sure we are not a process group leader. If we have + TIOCNOTTY, this doesn't matter, since TIOCNOTTY sets our process + group to 0 anyhow. */ + +#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); + + ulog_id (getpid ()); + + /* Restore SIGHUP catcher if it wasn't being ignored. */ + if (! fignored) + usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL); + } + +#endif /* ! HAVE_BSD_PGRP || ! HAVE_TIOCNOTTY */ + +#if HAVE_TIOCNOTTY + /* Lose the original controlling terminal. If standard input has + been reopened to /dev/null, this will do no harm. If another + port has been opened to become the controlling terminal, it + should have been detached when it was closed. */ + (void) ioctl (0, TIOCNOTTY, (char *) NULL); +#endif + + /* 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_BSD_PGRP + + /* Make sure our process group ID is set to 0. On BSD TIOCNOTTY + should already have set it 0, so this will do no harm. On System + V we presumably did not execute the TIOCNOTTY call, but the + System V setpgrp will detach the controlling terminal anyhow. + This lets us use the same code on both BSD and System V, provided + it compiles correctly, which life easier for the configure + script. We don't output an error if we got EPERM because some + BSD variants don't permit this usage of setpgrp (which means they + don't provide any way to pick up a new controlling terminal). */ + + if (setpgrp (0, 0) < 0) + { + if (errno != EPERM) + ulog (LOG_ERROR, "setpgrp: %s", strerror (errno)); + } + +#else /* ! HAVE_BSD_PGRP */ + +#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. I'm using the BSD setpgrp call first + because they should be equivalent for my purposes, but it turns + out that on Ultrix 4.0 setsid prevents us from ever acquiring + another controlling terminal (it does not change our process + group, and Ultrix 4.0 prevents us from setting our process group + to 0). */ + (void) setsid (); + +#else /* ! HAVE_SETSID */ + +#if HAVE_SETPGRP + + /* Now we assume we have the System V setpgrp, which takes no + arguments, and we couldn't compile the HAVE_BSD_PGRP code above + because there was a prototype somewhere in scope. On System V + setpgrp makes us the leader of a new process group and also + detaches the controlling terminal. */ + + if (setpgrp () < 0) + ulog (LOG_ERROR, "setpgrp: %s", strerror (errno)); + +#else /* ! HAVE_SETPGRP */ + + #error Must detach from controlling terminal + +#endif /* HAVE_SETPGRP */ +#endif /* ! HAVE_SETSID */ +#endif /* ! HAVE_BSD_PGRP */ + + /* At this point we have completely detached from our controlling + terminal. The next terminal device we open will probably become + our controlling terminal. */ +} |