Aggiornamento note copyright
[gapil.git] / sources / SigHand.c
1 /* SigHand.c
2  * 
3  * Copyright (C) 2002 Simone Piccardi
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /*****************************************************************************
20  *
21  * File SigHand.c: define a set of functions for signal manipulation 
22  *
23  * Author: S. Piccardi Dec. 2002
24  *
25  *****************************************************************************/
26 #include <errno.h>       /* error definitions and routines */
27 #include <stdio.h>       /* standard I/O library */
28 #include <signal.h>      /* signal constants, types and functions */
29 #include <sys/types.h>   /* primitive system data types */
30 #include <sys/wait.h>    /* process termination constants and functions */
31
32 #include "Gapil.h"
33 #include "macros.h"
34
35 /*
36  * Function Signal
37  * Initialize a signal handler.
38  * To enable the signal handling a process we need to tell it to
39  * kernel; this is done writing all needed info to a sigaction structure
40  * named sigact, and then calling sigaction() system call passing the
41  * information stored in the sigact structure variable.
42  *
43  * Input:  the signal to handle 
44  *         the signal handler function
45  * Return: the previous signal handler
46  */
47 inline SigHandler * Signal(int signo, SigHandler *func) 
48 {
49     struct sigaction new_handl, old_handl;
50     new_handl.sa_flags=0;                    /* init to 0 all flags */
51     new_handl.sa_handler = func;             /* set signal handler */
52     /* clear signal mask: no signal blocked during execution of func */
53     if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
54         return SIG_ERR;
55     }
56     /* change action for signo signal */
57     if (sigaction(signo, &new_handl, &old_handl)){ 
58         return SIG_ERR;
59     }
60     return (old_handl.sa_handler);
61 }
62
63 /*
64  * Function SignalRestart
65  * Initialize a signal handler.
66  * To enable the signal handling a process we need to tell it to
67  * kernel; this is done writing all needed info to a sigaction structure
68  * named sigact, and then calling sigaction() system call passing the
69  * information stored in the sigact structure variable.
70  * This version enable BSD semantics with SA_RESTART
71  *
72  * Input:  the signal to handle 
73  *         the signal handler function
74  * Return: the previous signal handler
75  */
76 inline SigHandler * SignalRestart(int signo, SigHandler *func) 
77 {
78     struct sigaction new_handl, old_handl;
79     new_handl.sa_flags = SA_RESTART;         /* restart system call */
80     new_handl.sa_handler = func;             /* set signal handler */
81     /* clear signal mask: no signal blocked during execution of func */
82     if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
83         return SIG_ERR;
84     }
85     /* change action for signo signal */
86     if (sigaction(signo, &new_handl, &old_handl)){ 
87         return SIG_ERR;
88     }
89     return (old_handl.sa_handler);
90 }
91
92 /*
93  * Function Action
94  * Initialize a sa_sigaction signal handler.
95  * To enable the signal handling a process we need to tell it to
96  * kernel; this is done writing all needed info to a sigaction structure
97  * named sigact, and then calling sigaction() system call passing the
98  * information stored in the sigact structure variable.
99  *
100  * Input:  the signal to handle 
101  *         the signal handler function (sa_sigaction type)
102  * Return: the previous signal handler
103  */
104 inline SigAction * Action(int signo, SigAction *func) 
105 {
106     struct sigaction new_handl, old_handl;
107     new_handl.sa_flags=SA_SIGINFO;           /* we use sa_sigaction handler */
108     new_handl.sa_sigaction = func;           /* set signal handler */
109     /* clear signal mask: no signal blocked during execution of func */
110     if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
111         return NULL;
112     }
113     /* change action for signo signal */
114     if (sigaction(signo, &new_handl, &old_handl)){ 
115         return NULL;
116     }
117     return (old_handl.sa_sigaction);
118 }
119 /*
120  * Function Action
121  * Initialize a sa_sigaction signal handler.
122  * To enable the signal handling a process we need to tell it to
123  * kernel; this is done writing all needed info to a sigaction structure
124  * named sigact, and then calling sigaction() system call passing the
125  * information stored in the sigact structure variable.
126  *
127  * Input:  the signal to handle 
128  *         the signal handler function (sa_sigaction type)
129  * Return: the previous signal handler
130  */
131 inline SigAction * ActionRestart(int signo, SigAction *func) 
132 {
133     struct sigaction new_handl, old_handl;
134     new_handl.sa_flags=SA_SIGINFO|SA_RESTART;/* flag setup */
135     new_handl.sa_sigaction = func;           /* set signal handler */
136     /* clear signal mask: no signal blocked during execution of func */
137     if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
138         return NULL;
139     }
140     /* change action for signo signal */
141     if (sigaction(signo, &new_handl, &old_handl)){ 
142         return NULL;
143     }
144     return (old_handl.sa_sigaction);
145 }
146
147 /* 
148  * Functions: HandSigCHLD
149  * Generic simple handler for SIGCHLD signal
150  * 
151  * Simone Piccardi Dec. 2002
152  */
153 void HandSigCHLD(int sig)
154 {
155     int errno_save;
156     int status;
157     pid_t pid;
158     /* save errno current value */
159     errno_save = errno;
160     /* loop until no */
161     do {
162         errno = 0;
163         pid = waitpid(WAIT_ANY, &status, WNOHANG);
164 //      if (pid > 0) {
165 //          debug("child %d terminated with status %x\n", pid, status);
166 //      }
167     } while (pid > 0);
168     /* restore errno value*/
169     errno = errno_save;
170     /* return */
171     return;
172 }