File: daemon.c

package info (click to toggle)
gopher 2.3-2
  • links: PTS
  • area: non-free
  • in suites: hamm
  • size: 2,364 kB
  • ctags: 2,030
  • sloc: ansic: 22,451; perl: 1,950; sh: 1,510; makefile: 397; asm: 1
file content (313 lines) | stat: -rw-r--r-- 7,413 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
/********************************************************************
 * $Author: lindner $
 * $Revision: 3.25 $
 * $Date: 1996/01/04 18:30:11 $
 * $Source: /home/arcwelder/GopherSrc/CVS/gopher+/gopherd/daemon.c,v $
 * $State: Exp $
 *
 * Paul Lindner, University of Minnesota CIS.
 *
 * Copyright 1991, 1992 by the Regents of the University of Minnesota
 * see the file "Copyright" in the distribution for conditions of use.
 *********************************************************************
 * MODULE: daemon.c
 * Routines to detach from and run as a daemon.
 *********************************************************************
 * Revision History:
 * $Log: daemon.c,v $
 * Revision 3.25  1996/01/04  18:30:11  lindner
 * Fix for Ustat on Linux, autoconf changes
 *
 * Revision 3.24  1995/11/12  03:41:43  lindner
 * Hmmm, fix for sigcld...
 *
 * Revision 3.23  1995/11/06  20:53:08  lindner
 * Waiting fixes
 *
 * Revision 3.22  1995/09/25  05:02:31  lindner
 * Convert to ANSI C
 *
 * Revision 3.21  1995/06/09  04:48:38  lindner
 * none
 *
 * Revision 3.20  1995/04/15  08:08:50  lindner
 * daemon.c
 *
 * Revision 3.19  1995/04/15  07:13:16  lindner
 * Fix for waitpid stuff
 *
 * Revision 3.18  1995/02/13  19:11:01  lindner
 * Fix for AIX
 *
 * Revision 3.17  1995/02/11  06:20:23  lindner
 * Modifications to keep track of our children..
 *
 * Revision 3.16  1994/12/12  17:41:37  lindner
 * Hack around AIX
 *
 * Revision 3.15  1994/10/20  04:21:46  lindner
 * Rollback AUX changes (they didn't work!)
 *
 * Revision 3.14  1994/10/02  02:32:58  lindner
 * Fix for AUX zombie handler..
 *
 * Revision 3.13  1994/08/03  04:22:40  lindner
 * Fix for svr4 irix systems
 *
 * Revision 3.12  1994/03/17  05:53:38  lindner
 * Decouple daemon.c from gopherd.h
 *
 * Revision 3.11  1994/03/17  04:28:44  lindner
 * Fix for vms include files
 *
 * Revision 3.10  1993/10/20  03:32:45  lindner
 * daemon.c
 *
 * Revision 3.9  1993/09/22  04:50:29  lindner
 * Fix for wait() probs on NeXT
 *
 * Revision 3.8  1993/09/22  04:26:22  lindner
 * Fix for sgi daemon code..
 *
 * Revision 3.7  1993/08/16  16:27:35  lindner
 * Fix for the error 'wait error (No children)
 *
 * Revision 3.6  1993/08/03  20:43:22  lindner
 * Fix for core dumps on HPUX 8.0
 *
 * Revision 3.5  1993/07/26  20:28:58  lindner
 * Fixed mode for uopen
 *
 * Revision 3.4  1993/07/23  03:20:02  lindner
 * Zombie killer code...
 *
 * Revision 3.3  1993/07/07  19:38:34  lindner
 * fix for linux and svr4
 *
 * Revision 3.2  1993/03/24  20:18:04  lindner
 * Fixes for SCO3.2
 *
 * Revision 3.1.1.1  1993/02/11  18:02:50  lindner
 * Gopher+1.2beta release
 *
 * Revision 1.1  1992/12/10  23:13:27  lindner
 * gopher 1.1 release
 *
 *
 *********************************************************************/

#ifdef unix
#  include <sys/param.h>
#endif

#include <stdio.h>
#include <errno.h>
extern int errno;
#include <signal.h>

#include "gopherd.h"

#ifndef NOFILE
#  define NOFILE (100)
#endif

/*
 * A BSD style SIGCLD signal handler that can be used by a server
 * that's not interested in its child's exit status, but needs to
 * wait for them, to avoid clogging up the system with zombies.
 *
 * Beware that the calling process may get an interrupted system
 * call when we return, so they had better handle that.
 *
 * (From Stevens pg 82)
 */

#include "Wait.h"

#ifdef hpux
#define TIOCNOTTY       _IO('t', 113)           /* void tty association */
#endif

void
sig_child()
{
     /*
      * Use the waitpid() system call with the WNOHANG option
      */

     int pid;
     Portawait status;

     /** waitpid only once.. **/

     if ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0)
	  ActiveSessions--;
}


#ifdef SIGCHLD
static RETSIGTYPE
sig_sigchld(int signo)
{
     pid_t pid;
     Portawait  status;

     if (signal(SIGCHLD, sig_sigchld) == SIG_ERR) 
	  err_sys("signal error");
     
     if ((pid = waitpid(-1, &status, WNOHANG)) > 0)
	  ActiveSessions--;

}
#endif /* SIGCHLD */

#ifdef SIGCLD
static RETSIGTYPE
sig_sigcld(int signo)
{
     pid_t pid;
     Portawait  status;

/*     pid = wait(&status);*/


     if ((pid = waitpid(-1, &status, WNOHANG)) > 0)
	  ActiveSessions--;

     signal(SIGCLD, sig_sigcld);
     return;
}
#endif /* SIGCLD */


#if defined(SIGTSTP) && !defined(M_XENIX) && !defined(USG)/* True on a BSD system */
#include <sys/file.h>
#include <sys/ioctl.h>
#endif

/*
 * Detach a daemon process from login session context
 * Nonzero ignsigcld-> nuke zombie children
 */

void
daemon_start(int ignsigcld)
{
     register int childpid, fd;

     /*
      * If we were started by init (process 1) from the /etc/inittab
      * file there's no need to detach.
      */
      
     if (getppid() != 1) {

	  

#ifdef SIGTTOU
	  signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
	  signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTP
	  signal(SIGTSTP, SIG_IGN);
#endif

	  /*
	   * If we were not started in the background, fork and let
	   * the parent exit.  This also guarantees the first child
	   * is not a process group leader.
	   */

	  if ( (childpid = fork()) < 0)
	       err_sys("can't fork first child");
	  else if (childpid >0)
	       exit(0);     /* parent goes bye-bye */
	  
	  /*
	   * First Child process
	   *
	   * Disassociate from controlling terminal and process group.
	   * Ensure the process can't reacquire a new controlling terminal
	   */
	  
/* Need to add defined(TIOCNOTTY) because SCO2.3.2 has SIGTSTP defined
   but is NOT BSD and doesnt have TIOCNOTTY */

#if defined(SIGTSTP) && !defined(USG) && defined(TIOCNOTTY)  /* BSD */
	  

#if defined(HAVE_SETSID)
	  setsid();
#else
	  if (setpgrp(0, getpid()) == -1)
	       err_sys("can't change process group");
	  
	  if ( (fd = uopen("/dev/tty", O_RDWR,000)) >= 0) {
	       ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling TTY*/
	       close(fd);
	  }
#endif /* hpux  et al.*/
	  
#else /* System V */
	  
	  if (setpgrp() == -1)
	       err_sys("Can't change process group");
	  
	  signal(SIGHUP, SIG_IGN);  /* immune from pgrp leader death */
	  
	  if ( (childpid = fork()) < 0)
	       err_sys("Can't fork second child");
	  else if (childpid > 0)
	       exit(0); /* First child */
	  
	  /* second child */
#endif

     }  /* End of if test for ppid == 1 */

     /** Close any file descriptors **/

     for (fd = 0; fd < NOFILE; fd++)
	  close(fd);

     errno = 0;  /* probably set to EBADF from a close */


     /** Change the current directory to / **/

     /* No need for this, since we're already where we want to be */
     /* rchdir("/"); */

     /** Clear inherited file mode creation mask. **/

     umask(0);

     /*
      * See if the caller isn't ineterested in the exit status of its
      * children, and doesn't want to have them become zombies
      */

     if (ignsigcld) {
#if defined(SIGCLD) /*&& !defined(_AIX)*/
	  if (signal(SIGCLD, sig_sigcld))
	       perror("Signal Error..");    /* System V */
#endif

	  /**  Lots of brain dead systems equate SIGCLD with SIGCHLD

	       This is wrong since the semantics are different between the two

	       But to insure no zombies do SIGCLD first, then SIGCHLD... **/

#if defined(SIGCHLD) && !defined(_AUX_SOURCE) && !defined(__svr4__) &&           !defined(USG) && !defined(SYSV) && !defined(hpux) && !defined(sgi) && !defined(_AIX)
	  if (signal(SIGCHLD, sig_sigchld))
	       perror("signal error");
#endif

     }
}