1 /* Implementation of the SIGNAL and ALARM g77 intrinsics
2    Copyright (C) 2005-2018 Free Software Foundation, Inc.
3    Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
4 
5 This file is part of the GNU Fortran runtime library (libgfortran).
6 
7 Libgfortran is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
11 
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20 
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 <http://www.gnu.org/licenses/>.  */
25 
26 #include "libgfortran.h"
27 
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 
32 #include <signal.h>
33 
34 #ifdef HAVE_INTTYPES_H
35 #include <inttypes.h>
36 #endif
37 
38 #include <errno.h>
39 
40 /* SIGNAL subroutine with PROCEDURE as handler  */
41 extern void signal_sub (int *, void (*)(int), int *);
42 iexport_proto(signal_sub);
43 
44 void
signal_sub(int * number,void (* handler)(int),int * status)45 signal_sub (int *number, void (*handler)(int), int *status)
46 {
47   intptr_t ret;
48 
49   if (status != NULL)
50     {
51       ret = (intptr_t) signal (*number, handler);
52       *status = (int) ret;
53     }
54   else
55     signal (*number, handler);
56 }
57 iexport(signal_sub);
58 
59 
60 /* SIGNAL subroutine with INTEGER as handler  */
61 extern void signal_sub_int (int *, int *, int *);
62 iexport_proto(signal_sub_int);
63 
64 void
signal_sub_int(int * number,int * handler,int * status)65 signal_sub_int (int *number, int *handler, int *status)
66 {
67   intptr_t ptr = *handler, ret;
68 
69   if (status != NULL)
70     {
71       ret = (intptr_t) signal (*number, (void (*)(int)) ptr);
72       *status = (int) ret;
73     }
74   else
75     signal (*number, (void (*)(int)) ptr);
76 }
77 iexport(signal_sub_int);
78 
79 
80 /* SIGNAL function with PROCEDURE as handler  */
81 extern int signal_func (int *, void (*)(int));
82 iexport_proto(signal_func);
83 
84 int
signal_func(int * number,void (* handler)(int))85 signal_func (int *number, void (*handler)(int))
86 {
87   int status;
88   signal_sub (number, handler, &status);
89   return status;
90 }
91 iexport(signal_func);
92 
93 
94 /* SIGNAL function with INTEGER as handler  */
95 extern int signal_func_int (int *, int *);
96 iexport_proto(signal_func_int);
97 
98 int
signal_func_int(int * number,int * handler)99 signal_func_int (int *number, int *handler)
100 {
101   int status;
102   signal_sub_int (number, handler, &status);
103   return status;
104 }
105 iexport(signal_func_int);
106 
107 
108 
109 /* ALARM intrinsic with PROCEDURE as handler  */
110 extern void alarm_sub_i4 (int *, void (*)(int), GFC_INTEGER_4 *);
111 iexport_proto(alarm_sub_i4);
112 
113 void
alarm_sub_i4(int * seconds,void (* handler)(int),GFC_INTEGER_4 * status)114 alarm_sub_i4 (int * seconds __attribute__ ((unused)),
115 	      void (*handler)(int) __attribute__ ((unused)),
116 	      GFC_INTEGER_4 *status)
117 {
118 #if defined (SIGALRM) && defined (HAVE_ALARM)
119   if (status != NULL)
120     {
121       if (signal (SIGALRM, handler) == SIG_ERR)
122 	*status = -1;
123       else
124 	*status = alarm (*seconds);
125     }
126   else
127     {
128       signal (SIGALRM, handler);
129       alarm (*seconds);
130     }
131 #else
132   errno = ENOSYS;
133   if (status != NULL)
134     *status = -1;
135 #endif
136 }
137 iexport(alarm_sub_i4);
138 
139 
140 extern void alarm_sub_i8 (int *, void (*)(int), GFC_INTEGER_8 *);
141 iexport_proto(alarm_sub_i8);
142 
143 void
alarm_sub_i8(int * seconds,void (* handler)(int),GFC_INTEGER_8 * status)144 alarm_sub_i8 (int *seconds __attribute__ ((unused)),
145 	      void (*handler)(int) __attribute__ ((unused)),
146 	      GFC_INTEGER_8 *status)
147 {
148 #if defined (SIGALRM) && defined (HAVE_ALARM)
149   if (status != NULL)
150     {
151       if (signal (SIGALRM, handler) == SIG_ERR)
152 	*status = -1;
153       else
154 	*status = alarm (*seconds);
155     }
156   else
157     {
158       signal (SIGALRM, handler);
159       alarm (*seconds);
160     }
161 #else
162   errno = ENOSYS;
163   if (status != NULL)
164     *status = -1;
165 #endif
166 }
167 iexport(alarm_sub_i8);
168 
169 
170 /* ALARM intrinsic with INTEGER as handler  */
171 extern void alarm_sub_int_i4 (int *, int *, GFC_INTEGER_4 *);
172 iexport_proto(alarm_sub_int_i4);
173 
174 void
alarm_sub_int_i4(int * seconds,int * handler,GFC_INTEGER_4 * status)175 alarm_sub_int_i4 (int *seconds __attribute__ ((unused)),
176 		  int *handler __attribute__ ((unused)),
177 		  GFC_INTEGER_4 *status)
178 {
179 #if defined (SIGALRM) && defined (HAVE_ALARM)
180   if (status != NULL)
181     {
182       if (signal (SIGALRM, (void (*)(int)) (intptr_t) *handler) == SIG_ERR)
183 	*status = -1;
184       else
185 	*status = alarm (*seconds);
186     }
187   else
188     {
189       signal (SIGALRM, (void (*)(int)) (intptr_t) *handler);
190       alarm (*seconds);
191     }
192 #else
193   errno = ENOSYS;
194   if (status != NULL)
195     *status = -1;
196 #endif
197 }
198 iexport(alarm_sub_int_i4);
199 
200 
201 extern void alarm_sub_int_i8 (int *, int *, GFC_INTEGER_8 *);
202 iexport_proto(alarm_sub_int_i8);
203 
204 void
alarm_sub_int_i8(int * seconds,int * handler,GFC_INTEGER_8 * status)205 alarm_sub_int_i8 (int *seconds __attribute__ ((unused)),
206 		  int *handler __attribute__ ((unused)),
207 		  GFC_INTEGER_8 *status)
208 {
209 #if defined (SIGALRM) && defined (HAVE_ALARM)
210   if (status != NULL)
211     {
212       if (signal (SIGALRM, (void (*)(int)) (intptr_t) *handler) == SIG_ERR)
213 	*status = -1;
214       else
215 	*status = alarm (*seconds);
216     }
217   else
218     {
219       signal (SIGALRM, (void (*)(int)) (intptr_t) *handler);
220       alarm (*seconds);
221     }
222 #else
223   errno = ENOSYS;
224   if (status != NULL)
225     *status = -1;
226 #endif
227 }
228 iexport(alarm_sub_int_i8);
229 
230