1181254a7Smrg /* Implementation of the SIGNAL and ALARM g77 intrinsics
2*b1e83836Smrg Copyright (C) 2005-2022 Free Software Foundation, Inc.
3181254a7Smrg Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
4181254a7Smrg
5181254a7Smrg This file is part of the GNU Fortran runtime library (libgfortran).
6181254a7Smrg
7181254a7Smrg Libgfortran is free software; you can redistribute it and/or
8181254a7Smrg modify it under the terms of the GNU General Public
9181254a7Smrg License as published by the Free Software Foundation; either
10181254a7Smrg version 3 of the License, or (at your option) any later version.
11181254a7Smrg
12181254a7Smrg Libgfortran is distributed in the hope that it will be useful,
13181254a7Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14181254a7Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15181254a7Smrg GNU General Public License for more details.
16181254a7Smrg
17181254a7Smrg Under Section 7 of GPL version 3, you are granted additional
18181254a7Smrg permissions described in the GCC Runtime Library Exception, version
19181254a7Smrg 3.1, as published by the Free Software Foundation.
20181254a7Smrg
21181254a7Smrg You should have received a copy of the GNU General Public License and
22181254a7Smrg a copy of the GCC Runtime Library Exception along with this program;
23181254a7Smrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24181254a7Smrg <http://www.gnu.org/licenses/>. */
25181254a7Smrg
26181254a7Smrg #include "libgfortran.h"
27181254a7Smrg
28181254a7Smrg #ifdef HAVE_UNISTD_H
29181254a7Smrg #include <unistd.h>
30181254a7Smrg #endif
31181254a7Smrg
32181254a7Smrg #include <signal.h>
33181254a7Smrg
34181254a7Smrg #ifdef HAVE_INTTYPES_H
35181254a7Smrg #include <inttypes.h>
36181254a7Smrg #endif
37181254a7Smrg
38181254a7Smrg #include <errno.h>
39181254a7Smrg
40181254a7Smrg /* SIGNAL subroutine with PROCEDURE as handler */
41181254a7Smrg extern void signal_sub (int *, void (*)(int), int *);
42181254a7Smrg iexport_proto(signal_sub);
43181254a7Smrg
44181254a7Smrg void
signal_sub(int * number,void (* handler)(int),int * status)45181254a7Smrg signal_sub (int *number, void (*handler)(int), int *status)
46181254a7Smrg {
47181254a7Smrg intptr_t ret;
48181254a7Smrg
49181254a7Smrg if (status != NULL)
50181254a7Smrg {
51181254a7Smrg ret = (intptr_t) signal (*number, handler);
52181254a7Smrg *status = (int) ret;
53181254a7Smrg }
54181254a7Smrg else
55181254a7Smrg signal (*number, handler);
56181254a7Smrg }
57181254a7Smrg iexport(signal_sub);
58181254a7Smrg
59181254a7Smrg
60181254a7Smrg /* SIGNAL subroutine with INTEGER as handler */
61181254a7Smrg extern void signal_sub_int (int *, int *, int *);
62181254a7Smrg iexport_proto(signal_sub_int);
63181254a7Smrg
64181254a7Smrg void
signal_sub_int(int * number,int * handler,int * status)65181254a7Smrg signal_sub_int (int *number, int *handler, int *status)
66181254a7Smrg {
67181254a7Smrg intptr_t ptr = *handler, ret;
68181254a7Smrg
69181254a7Smrg if (status != NULL)
70181254a7Smrg {
71181254a7Smrg ret = (intptr_t) signal (*number, (void (*)(int)) ptr);
72181254a7Smrg *status = (int) ret;
73181254a7Smrg }
74181254a7Smrg else
75181254a7Smrg signal (*number, (void (*)(int)) ptr);
76181254a7Smrg }
77181254a7Smrg iexport(signal_sub_int);
78181254a7Smrg
79181254a7Smrg
80181254a7Smrg /* SIGNAL function with PROCEDURE as handler */
81181254a7Smrg extern int signal_func (int *, void (*)(int));
82181254a7Smrg iexport_proto(signal_func);
83181254a7Smrg
84181254a7Smrg int
signal_func(int * number,void (* handler)(int))85181254a7Smrg signal_func (int *number, void (*handler)(int))
86181254a7Smrg {
87181254a7Smrg int status;
88181254a7Smrg signal_sub (number, handler, &status);
89181254a7Smrg return status;
90181254a7Smrg }
91181254a7Smrg iexport(signal_func);
92181254a7Smrg
93181254a7Smrg
94181254a7Smrg /* SIGNAL function with INTEGER as handler */
95181254a7Smrg extern int signal_func_int (int *, int *);
96181254a7Smrg iexport_proto(signal_func_int);
97181254a7Smrg
98181254a7Smrg int
signal_func_int(int * number,int * handler)99181254a7Smrg signal_func_int (int *number, int *handler)
100181254a7Smrg {
101181254a7Smrg int status;
102181254a7Smrg signal_sub_int (number, handler, &status);
103181254a7Smrg return status;
104181254a7Smrg }
105181254a7Smrg iexport(signal_func_int);
106181254a7Smrg
107181254a7Smrg
108181254a7Smrg
109181254a7Smrg /* ALARM intrinsic with PROCEDURE as handler */
110181254a7Smrg extern void alarm_sub_i4 (int *, void (*)(int), GFC_INTEGER_4 *);
111181254a7Smrg iexport_proto(alarm_sub_i4);
112181254a7Smrg
113181254a7Smrg void
alarm_sub_i4(int * seconds,void (* handler)(int),GFC_INTEGER_4 * status)114181254a7Smrg alarm_sub_i4 (int * seconds __attribute__ ((unused)),
115181254a7Smrg void (*handler)(int) __attribute__ ((unused)),
116181254a7Smrg GFC_INTEGER_4 *status)
117181254a7Smrg {
118181254a7Smrg #if defined (SIGALRM) && defined (HAVE_ALARM)
119181254a7Smrg if (status != NULL)
120181254a7Smrg {
121181254a7Smrg if (signal (SIGALRM, handler) == SIG_ERR)
122181254a7Smrg *status = -1;
123181254a7Smrg else
124181254a7Smrg *status = alarm (*seconds);
125181254a7Smrg }
126181254a7Smrg else
127181254a7Smrg {
128181254a7Smrg signal (SIGALRM, handler);
129181254a7Smrg alarm (*seconds);
130181254a7Smrg }
131181254a7Smrg #else
132181254a7Smrg errno = ENOSYS;
133181254a7Smrg if (status != NULL)
134181254a7Smrg *status = -1;
135181254a7Smrg #endif
136181254a7Smrg }
137181254a7Smrg iexport(alarm_sub_i4);
138181254a7Smrg
139181254a7Smrg
140181254a7Smrg extern void alarm_sub_i8 (int *, void (*)(int), GFC_INTEGER_8 *);
141181254a7Smrg iexport_proto(alarm_sub_i8);
142181254a7Smrg
143181254a7Smrg void
alarm_sub_i8(int * seconds,void (* handler)(int),GFC_INTEGER_8 * status)144181254a7Smrg alarm_sub_i8 (int *seconds __attribute__ ((unused)),
145181254a7Smrg void (*handler)(int) __attribute__ ((unused)),
146181254a7Smrg GFC_INTEGER_8 *status)
147181254a7Smrg {
148181254a7Smrg #if defined (SIGALRM) && defined (HAVE_ALARM)
149181254a7Smrg if (status != NULL)
150181254a7Smrg {
151181254a7Smrg if (signal (SIGALRM, handler) == SIG_ERR)
152181254a7Smrg *status = -1;
153181254a7Smrg else
154181254a7Smrg *status = alarm (*seconds);
155181254a7Smrg }
156181254a7Smrg else
157181254a7Smrg {
158181254a7Smrg signal (SIGALRM, handler);
159181254a7Smrg alarm (*seconds);
160181254a7Smrg }
161181254a7Smrg #else
162181254a7Smrg errno = ENOSYS;
163181254a7Smrg if (status != NULL)
164181254a7Smrg *status = -1;
165181254a7Smrg #endif
166181254a7Smrg }
167181254a7Smrg iexport(alarm_sub_i8);
168181254a7Smrg
169181254a7Smrg
170181254a7Smrg /* ALARM intrinsic with INTEGER as handler */
171181254a7Smrg extern void alarm_sub_int_i4 (int *, int *, GFC_INTEGER_4 *);
172181254a7Smrg iexport_proto(alarm_sub_int_i4);
173181254a7Smrg
174181254a7Smrg void
alarm_sub_int_i4(int * seconds,int * handler,GFC_INTEGER_4 * status)175181254a7Smrg alarm_sub_int_i4 (int *seconds __attribute__ ((unused)),
176181254a7Smrg int *handler __attribute__ ((unused)),
177181254a7Smrg GFC_INTEGER_4 *status)
178181254a7Smrg {
179181254a7Smrg #if defined (SIGALRM) && defined (HAVE_ALARM)
180181254a7Smrg if (status != NULL)
181181254a7Smrg {
182181254a7Smrg if (signal (SIGALRM, (void (*)(int)) (intptr_t) *handler) == SIG_ERR)
183181254a7Smrg *status = -1;
184181254a7Smrg else
185181254a7Smrg *status = alarm (*seconds);
186181254a7Smrg }
187181254a7Smrg else
188181254a7Smrg {
189181254a7Smrg signal (SIGALRM, (void (*)(int)) (intptr_t) *handler);
190181254a7Smrg alarm (*seconds);
191181254a7Smrg }
192181254a7Smrg #else
193181254a7Smrg errno = ENOSYS;
194181254a7Smrg if (status != NULL)
195181254a7Smrg *status = -1;
196181254a7Smrg #endif
197181254a7Smrg }
198181254a7Smrg iexport(alarm_sub_int_i4);
199181254a7Smrg
200181254a7Smrg
201181254a7Smrg extern void alarm_sub_int_i8 (int *, int *, GFC_INTEGER_8 *);
202181254a7Smrg iexport_proto(alarm_sub_int_i8);
203181254a7Smrg
204181254a7Smrg void
alarm_sub_int_i8(int * seconds,int * handler,GFC_INTEGER_8 * status)205181254a7Smrg alarm_sub_int_i8 (int *seconds __attribute__ ((unused)),
206181254a7Smrg int *handler __attribute__ ((unused)),
207181254a7Smrg GFC_INTEGER_8 *status)
208181254a7Smrg {
209181254a7Smrg #if defined (SIGALRM) && defined (HAVE_ALARM)
210181254a7Smrg if (status != NULL)
211181254a7Smrg {
212181254a7Smrg if (signal (SIGALRM, (void (*)(int)) (intptr_t) *handler) == SIG_ERR)
213181254a7Smrg *status = -1;
214181254a7Smrg else
215181254a7Smrg *status = alarm (*seconds);
216181254a7Smrg }
217181254a7Smrg else
218181254a7Smrg {
219181254a7Smrg signal (SIGALRM, (void (*)(int)) (intptr_t) *handler);
220181254a7Smrg alarm (*seconds);
221181254a7Smrg }
222181254a7Smrg #else
223181254a7Smrg errno = ENOSYS;
224181254a7Smrg if (status != NULL)
225181254a7Smrg *status = -1;
226181254a7Smrg #endif
227181254a7Smrg }
228181254a7Smrg iexport(alarm_sub_int_i8);
229181254a7Smrg
230