]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/libexec/uucp/libunix/detach.c
This commit was generated by cvs2svn to compensate for changes in r52746,
[FreeBSD/FreeBSD.git] / gnu / libexec / uucp / libunix / detach.c
1 /* detach.c
2    Detach from the controlling terminal.
3
4    Copyright (C) 1992, 1993, 1995 Ian Lance Taylor
5
6    This file is part of the Taylor UUCP package.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
22    The author of the program may be contacted at ian@airs.com or
23    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
24    */
25
26 #include "uucp.h"
27
28 #include "uudefs.h"
29 #include "system.h"
30 #include "sysdep.h"
31
32 #include <errno.h>
33
34 #if HAVE_SYS_IOCTL_H
35 #include <sys/ioctl.h>
36 #endif
37
38 #ifdef TIOCNOTTY
39 #define HAVE_TIOCNOTTY 1
40 #else
41 #define HAVE_TIOCNOTTY 0 
42 #endif
43
44 #if HAVE_FCNTL_H
45 #include <fcntl.h>
46 #else
47 #if HAVE_SYS_FILE_H
48 #include <sys/file.h>
49 #endif
50 #endif
51
52 #ifndef O_RDONLY
53 #define O_RDONLY 0
54 #define O_WRONLY 1
55 #define O_RDWR 2
56 #endif
57
58 #if HAVE_BROKEN_SETSID
59 #undef HAVE_SETSID
60 #define HAVE_SETSID 0
61 #endif
62 \f
63 /* Detach from the controlling terminal.  This is called by uucico if
64    it is calling out to another system, so that it can receive SIGHUP
65    signals from the port it calls out on.  It is also called by uucico
66    just before it starts uuxqt, so that uuxqt is completely
67    independent of the terminal.  */
68
69 void
70 usysdep_detach ()
71 {
72   pid_t igrp;
73
74   /* Make sure that we can open the log file.  We do this now so that,
75      if we can't, a message will be written to stderr.  After we leave
76      this routine, stderr will be closed.  */
77   ulog (LOG_NORMAL, (const char *) NULL);
78
79   /* Make sure we are not a process group leader.  */
80 #if HAVE_BSD_PGRP
81   igrp = getpgrp (0);
82 #else
83   igrp = getpgrp ();
84 #endif
85
86   if (igrp == getpid ())
87     {
88       boolean fignored;
89       pid_t ipid;
90
91       /* Ignore SIGHUP, since our process group leader is about to
92          die.  */
93       usset_signal (SIGHUP, SIG_IGN, FALSE, &fignored);
94
95       ipid = ixsfork ();
96       if (ipid < 0)
97         ulog (LOG_FATAL, "fork: %s", strerror (errno));
98
99       if (ipid != 0)
100         _exit (EXIT_SUCCESS);
101
102       /* We'll always wind up as a child of process number 1, right?
103          Right?  We have to wait for our parent to die before
104          reenabling SIGHUP.  */
105       while (getppid () != 1)
106         sleep (1);
107
108       ipid = getpid ();
109       ulog_id (ipid);
110
111       /* Restore SIGHUP catcher if it wasn't being ignored.  */
112       if (! fignored)
113         usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL);
114
115       DEBUG_MESSAGE2 (DEBUG_PORT,
116                       "usysdep_detach: Forked; old PID %ld, new pid %ld",
117                       (long) igrp, (long) ipid);
118     }
119
120 #if ! HAVE_SETSID && HAVE_TIOCNOTTY
121   /* Lose the original controlling terminal as well as our process
122      group.  */
123   {
124     int o;
125
126     o = open ((char *) "/dev/tty", O_RDONLY);
127     if (o >= 0)
128       {
129         (void) ioctl (o, TIOCNOTTY, (char *) NULL);
130         (void) close (o);
131       }
132   }
133 #endif /* ! HAVE_SETSID && HAVE_TIOCNOTTY */
134
135   /* Close stdin, stdout and stderr and reopen them on /dev/null, to
136      make sure we have no connection at all to the terminal.  */
137   (void) close (0);
138   (void) close (1);
139   (void) close (2);
140   if (open ((char *) "/dev/null", O_RDONLY) != 0
141       || open ((char *) "/dev/null", O_WRONLY) != 1
142       || open ((char *) "/dev/null", O_WRONLY) != 2)
143     ulog (LOG_FATAL, "open (/dev/null): %s", strerror (errno));
144
145 #if HAVE_SETSID
146
147   /* Under POSIX the setsid call creates a new session for which we
148      are the process group leader.  It also detaches us from our
149      controlling terminal.  */
150   if (setsid () < 0)
151     ulog (LOG_ERROR, "setsid: %s", strerror (errno));
152
153 #else /* ! HAVE_SETSID */
154
155 #if ! HAVE_SETPGRP
156  #error Cannot detach from controlling terminal
157 #endif
158
159   /* If we don't have setsid, we must use setpgrp.  On an old System V
160      system setpgrp will make us the leader of a new process group and
161      detach the controlling terminal.  On an old BSD system the call
162      setpgrp (0, 0) will set our process group to 0 so that we can
163      acquire a new controlling terminal (TIOCNOTTY may or may not have
164      already done that anyhow).  */
165 #if HAVE_BSD_PGRP
166   if (setpgrp (0, 0) < 0)
167 #else
168   if (setpgrp () < 0)
169 #endif
170     {
171       /* Some systems seem to give EPERM errors inappropriately.  */
172       if (errno != EPERM)
173         ulog (LOG_ERROR, "setpgrp: %s", strerror (errno));
174     }
175
176 #endif /* ! HAVE_SETSID */
177
178   /* At this point we have completely detached from our controlling
179      terminal.  The next terminal device we open will probably become
180      our controlling terminal.  */
181 }