]> git.ipfire.org Git - thirdparty/squid.git/blob - tools/purge/signal.cc
Bundle the purge and hexd tools with Squid sources.
[thirdparty/squid.git] / tools / purge / signal.cc
1 //
2 // $Id$
3 //
4 // Author: Jens-S. V?ckler <voeckler@rvs.uni-hannover.de>
5 // File: signal.cc
6 // Date: Sat Feb 28 1998
7 // Compiler: gcc 2.7.2.x series
8 //
9 // Books: W. Richard Steven, "Advanced Programming in the UNIX Environment",
10 // Addison-Wesley, 1992.
11 //
12 // (c) 1998 Lehrgebiet Rechnernetze und Verteilte Systeme
13 // Universit?t Hannover, Germany
14 //
15 // Permission to use, copy, modify, distribute, and sell this software
16 // and its documentation for any purpose is hereby granted without fee,
17 // provided that (i) the above copyright notices and this permission
18 // notice appear in all copies of the software and related documentation,
19 // and (ii) the names of the Lehrgebiet Rechnernetze und Verteilte
20 // Systeme and the University of Hannover may not be used in any
21 // advertising or publicity relating to the software without the
22 // specific, prior written permission of Lehrgebiet Rechnernetze und
23 // Verteilte Systeme and the University of Hannover.
24 //
25 // THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
27 // WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
28 //
29 // IN NO EVENT SHALL THE LEHRGEBIET RECHNERNETZE UND VERTEILTE SYSTEME OR
30 // THE UNIVERSITY OF HANNOVER BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
31 // INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
32 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
33 // ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
34 // ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
35 // SOFTWARE.
36 //
37 // Revision 1.3 1999/01/19 13:11:52 cached
38 // adaptations necessary for AIX.
39 //
40 // Revision 1.2 1999/01/19 11:00:50 voeckler
41 // added psignal(int,const char*) compatibility function.
42 //
43 // Revision 1.1 1998/08/13 21:51:58 voeckler
44 // Initial revision
45 //
46 //
47
48 #if defined(__GNUC__) || defined(__GNUG__)
49 #pragma implementation
50 #endif
51
52 #include "config.h"
53 #include "signal.hh"
54
55 //#include <sys/types.h>
56 #include <errno.h>
57 #include <string.h>
58 #include <memory.h>
59 #include <stdio.h>
60 #include <unistd.h>
61 #include <sys/wait.h>
62 //#include <signal.h>
63
64 SigFunc*
65 Signal( int signo, SigFunc* newhandler, bool doInterrupt )
66 // purpose: install reliable signals
67 // paramtr: signo (IN): signal for which a handler is to be installed
68 // newhandler (IN): function pointer to the signal handler
69 // doInterrupt (IN): interrupted system calls wanted!
70 // returns: the old signal handler, or SIG_ERR in case of error.
71 {
72 struct sigaction action, old;
73
74 memset( &old, 0, sizeof(old) );
75 memset( &action, 0, sizeof(action) );
76
77 // action.sa_handler = newhandler; I HATE TYPE-OVERCORRECTNESS !
78 memmove( &action.sa_handler, &newhandler, sizeof(SigFunc*) );
79 sigemptyset( &action.sa_mask );
80
81 if ( signo == SIGCHLD ) {
82 action.sa_flags |= SA_NOCLDSTOP;
83
84 #ifdef SA_NODEFER
85 action.sa_flags |= SA_NODEFER; // SYSV: don't block current signal
86 #endif
87 }
88
89 if ( signo == SIGALRM || doInterrupt ) {
90 #ifdef SA_INTERRUPT
91 action.sa_flags |= SA_INTERRUPT; // SunOS, obsoleted by POSIX
92 #endif
93 } else {
94 #ifdef SA_RESTART
95 action.sa_flags |= SA_RESTART; // BSD, SVR4
96 #endif
97 }
98
99 return ( sigaction( signo, &action, &old ) < 0 ) ?
100 (SigFunc*) SIG_ERR :
101 (SigFunc*) old.sa_handler;
102 }
103
104 SIGRETTYPE
105 sigChild( int signo )
106 // purpose: supply ad hoc child handler with output on stderr
107 // paramtr: signo (IN): == SIGCHLD
108 // returns: only if OS uses a return type for signal handler
109 // seealso: Stevens, UNP, figure 5.11 *and* Stevens, APUE, figure 8.3
110 {
111 pid_t pid;
112 int status = signo; // to stop GNU from complaining...
113 char line[128];
114
115 int saveerr = errno;
116 while ( (pid = waitpid( -1, &status, WNOHANG )) > 0 ) {
117 if ( WIFEXITED(status) ) {
118 snprintf( line, 128, "child (pid=%ld) reaped, status %d\n%c",
119 (long) pid, WEXITSTATUS(status), 0 );
120 } else if ( WIFSIGNALED(status) ) {
121 snprintf( line, 128, "child (pid=%ld) died on signal %d%s\n%c",
122 (long) pid, WTERMSIG(status),
123 #ifdef WCOREDUMP
124 WCOREDUMP(status) ? " (core generated)" : "",
125 #else
126 "",
127 #endif
128 0 );
129 } else {
130 snprintf( line, 128, "detected dead child (pid=%ld), status %d\n%c",
131 (long) pid, status, 0 );
132 }
133 write( STDERR_FILENO, line, strlen(line) );
134 }
135 errno = saveerr;
136
137 #if SIGRETTYPE != void
138 return 0;
139 #endif
140 }