Home | History | Annotate | Line # | Download | only in intrinsics
      1 /* Implementation of the SIGNAL and ALARM g77 intrinsics
      2    Copyright (C) 2005-2024 Free Software Foundation, Inc.
      3    Contributed by Franois-Xavier Coudert <coudert (at) 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
     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
     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
     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
     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
    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
    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
    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
    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