Aggiunto esempio di gestione di segnali con la semantica BSD per il restart
[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  * $Id: SigHand.c,v 1.6 2003/05/06 11:29:16 piccardi Exp $
26  *
27  *****************************************************************************/
28 #include <errno.h>                               /* error simbol definitions */
29 #include <stdio.h>                                 /* standard I/O functions */
30 #include <signal.h>                          /* signal handling declarations */
31 #include <sys/types.h>
32 #include <sys/wait.h>
33
34 #include "Gapil.h"
35 #include "macros.h"
36
37 /*
38  * Function Signal
39  * Initialize a signal handler.
40  * To enable the signal handling a process we need to tell it to
41  * kernel; this is done writing all needed info to a sigaction structure
42  * named sigact, and then callind sigaction() system call passing the
43  * information stored in the sigact structure variable.
44  *
45  * Input:  the signal to handle 
46  *         the signal handler function
47  * Return: the previous sigaction structure
48  */
49 inline SigFunc * Signal(int signo, SigFunc *func) 
50 {
51     struct sigaction new_handl, old_handl;
52     new_handl.sa_handler = func;             /* set signal handler */
53     /* clear signal mask: no signal blocked during execution of func */
54     if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
55         return SIG_ERR;
56     }
57     new_handl.sa_flags=0;                    /* init to 0 all flags */
58     /* change action for signo signal */
59     if (sigaction(signo, &new_handl, &old_handl)){ 
60         return SIG_ERR;
61     }
62     return (old_handl.sa_handler);
63 }
64
65 /*
66  * Function SignalRestart
67  * Initialize a signal handler.
68  * To enable the signal handling a process we need to tell it to
69  * kernel; this is done writing all needed info to a sigaction structure
70  * named sigact, and then callind sigaction() system call passing the
71  * information stored in the sigact structure variable.
72  * This version enable BSD semantics with SA_RESTART
73  *
74  * Input:  the signal to handle 
75  *         the signal handler function
76  * Return: the previous sigaction structure
77  */
78 inline SigFunc * SignalRestart(int signo, SigFunc *func) 
79 {
80     struct sigaction new_handl, old_handl;
81     new_handl.sa_handler = func;             /* set signal handler */
82     new_handl.sa_flags = SA_RESTART;         /* restart system call */
83     /* clear signal mask: no signal blocked during execution of func */
84     if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
85         return SIG_ERR;
86     }
87     /* change action for signo signal */
88     if (sigaction(signo, &new_handl, &old_handl)){ 
89         return SIG_ERR;
90     }
91     return (old_handl.sa_handler);
92 }
93
94
95 /* 
96  * Functions: HandSigCHLD
97  * Generic handler for SIGCHLD signal
98  * 
99  * Simone Piccardi Dec. 2002
100  * $Id: SigHand.c,v 1.6 2003/05/06 11:29:16 piccardi Exp $
101  */
102 void HandSigCHLD(int sig)
103 {
104     int errno_save;
105     int status;
106     pid_t pid;
107     /* save errno current value */
108     errno_save = errno;
109     /* loop until no */
110     do {
111         errno = 0;
112         pid = waitpid(WAIT_ANY, &status, WNOHANG);
113         if (pid > 0) {
114             debug("child %d terminated with status %x\n", pid, status);
115         }
116     } while ((pid > 0) && (errno == EINTR));
117     /* restore errno value*/
118     errno = errno_save;
119     /* return */
120     return;
121 }