1 /*---------------------------------------------------------------
2 * Copyright (c) 1999,2000,2001,2002,2003
3 * The Board of Trustees of the University of Illinois
4 * All Rights Reserved.
5 *---------------------------------------------------------------
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software (Iperf) and associated
8 * documentation files (the "Software"), to deal in the Software
9 * without restriction, including without limitation the
10 * rights to use, copy, modify, merge, publish, distribute,
11 * sublicense, and/or sell copies of the Software, and to permit
12 * persons to whom the Software is furnished to do
13 * so, subject to the following conditions:
14 *
15 *
16 * Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and
18 * the following disclaimers.
19 *
20 *
21 * Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimers in the documentation and/or other materials
24 * provided with the distribution.
25 *
26 *
27 * Neither the names of the University of Illinois, NCSA,
28 * nor the names of its contributors may be used to endorse
29 * or promote products derived from this Software without
30 * specific prior written permission.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
34 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35 * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
36 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
37 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
38 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE
39 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 * ________________________________________________________________
41 * National Laboratory for Applied Network Research
42 * National Center for Supercomputing Applications
43 * University of Illinois at Urbana-Champaign
44 * http://www.ncsa.uiuc.edu
45 * ________________________________________________________________
46 *
47 * signal.c
48 * by Mark Gates <mgates@nlanr.net>
49 * -------------------------------------------------------------------
50 * standard signal installer
51 * ------------------------------------------------------------------- */
52
53 #include "headers.h"
54 #include "util.h"
55
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59
60 #ifdef WIN32
61
62 /* list of signal handlers. _NSIG is number of signals defined. */
63
64 static SigfuncPtr handlers[ _NSIG ] = { 0};
65
66 /* -------------------------------------------------------------------
67 * sig_dispatcher
68 *
69 * dispatches the signal to appropriate signal handler. This emulates
70 * the signal handling of Unix.
71 *
72 * ------------------------------------------------------------------- */
73
sig_dispatcher(DWORD type)74 BOOL WINAPI sig_dispatcher( DWORD type ) {
75 SigfuncPtr h = NULL;
76 int signo;
77
78 switch ( type ) {
79 case CTRL_C_EVENT:
80 signo = SIGINT;
81 h = handlers[ SIGINT ];
82 break;
83
84 case CTRL_CLOSE_EVENT:
85 case CTRL_LOGOFF_EVENT:
86 case CTRL_SHUTDOWN_EVENT:
87 signo = SIGTERM;
88 h = handlers[ SIGTERM ];
89 break;
90
91 default:
92 break;
93 }
94
95 if ( h != NULL ) {
96 // call the signal handler
97 h( signo );
98 return 1;
99 } else {
100 return 0;
101 }
102 }
103
104 /* -------------------------------------------------------------------
105 * my_signal
106 *
107 * installs a signal handler. I emulate Unix signals by storing the
108 * function pointers and dispatching events myself, using the
109 * sig_dispatcher above.
110 * ------------------------------------------------------------------- */
111
my_signal(int inSigno,SigfuncPtr inFunc)112 SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc ) {
113 SigfuncPtr old = NULL;
114
115 if ( inSigno >= 0 && inSigno < _NSIG ) {
116 old = handlers[ inSigno ];
117 handlers[ inSigno ] = inFunc;
118 }
119
120 return old;
121 } /* end my_signal */
122
123 #else /* not WIN32 */
124
125 /* -------------------------------------------------------------------
126 * my_signal
127 *
128 * installs a signal handler, and returns the old handler.
129 * This emulates the semi-standard signal() function in a
130 * standard way using the Posix sigaction function.
131 *
132 * from Stevens, 1998, section 5.8
133 * ------------------------------------------------------------------- */
134
135 SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc ) {
136 struct sigaction theNewAction, theOldAction;
137
138 assert( inFunc != NULL );
139
140 theNewAction.sa_handler = inFunc;
141 sigemptyset( &theNewAction.sa_mask );
142 theNewAction.sa_flags = 0;
143
144 if ( inSigno == SIGALRM ) {
145 #ifdef SA_INTERRUPT
146 theNewAction.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
147 #endif
148 } else {
149 #ifdef SA_RESTART
150 theNewAction.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
151 #endif
152 }
153
154 if ( sigaction( inSigno, &theNewAction, &theOldAction ) < 0 ) {
155 return SIG_ERR;
156 } else {
157 return theOldAction.sa_handler;
158 }
159 } /* end my_signal */
160
161 #endif /* not WIN32 */
162
163 /* -------------------------------------------------------------------
164 * sig_exit
165 *
166 * Quietly exits. This protects some against being called multiple
167 * times. (TODO: should use a mutex to ensure (num++ == 0) is atomic.)
168 * ------------------------------------------------------------------- */
169
sig_exit(int inSigno)170 void sig_exit( int inSigno ) {
171 static int num = 0;
172 if ( num++ == 0 ) {
173 fflush( 0 );
174 _exit(0);
175 }
176 } /* end sig_exit */
177
disarm_itimer(void)178 void disarm_itimer(void) {
179 #ifdef HAVE_SETITIMER
180 struct itimerval it;
181 memset (&it, 0, sizeof (it));
182 setitimer(ITIMER_REAL, &it, NULL);
183 #endif
184 }
185
186 #ifdef __cplusplus
187 } /* end extern "C" */
188 #endif
189