Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

signal - Signal processing control

&pagelevel(4)&pagelevel

Definition

#include <signal.h>

void (*signal(int sig, void (*fct) (int))) (int);

The signal function is provided for the handling of signals.

Signals that can be received and processed by a program can be distinguished into two
types, depending on the way in which they are triggered. The internal handling of a signal
varies in implementation on the basis of its type.

  1. STXIT events

    STXIT events are triggered

    • by program errors, e.g. address error, execution of invalid instructions, division by zero etc.

    • by the alarm function

    • externally, e.g. by pressing the K2 key, entering specific commands (ABEND, INFORM-PROGRAM etc.)

    The handling of these events is implemented internally via the BS2000-specific STXIT contingency mechanism. This mechanism as well as the STXIT event classes are
    described in detail in the "Executive Macros" manual.

  2. raise signals

    All events that can be triggered by the raise function are grouped under this type of signal. raise can be used to simulate STXIT events and to send (user-own and predefined) signals unrelated to STXIT events.

    The handling of this type of signal is C-specific, i.e. not implemented via the mechanism mentioned above.

If there is no provision for the handling of signals in a program, the program will be aborted when a signal arrives.

A program can, however, also intercept a signal. This is achieved by calling the signal function and by passing to it a function fct as its argument.
This makes it possible to respond to a signal in the following ways:

  • If fct is the default function SIG_DFL, the program is aborted.

  • If fct is the predefined function SIG_IGN, the signal is ignored.

  • If fct is a user-defined routine, the signal is handled as defined by this routine.

These three signal handling options are discussed below in somewhat greater detail in order to underline the differences in the handling of STXIT events and raise signals.

Program abortion

Program abortion occurs if the program does not provide for signal handling or if signal is called with the SIG_DFL function.

STXIT event:

The implementation-defined default termination response is executed by the operating system. The program is aborted, and information on the interruption address and the severity of the error is output together with a DUMP message:

... PROCESSING INTERRUPTED AT address ..., EC=severity

... DUMP DESIRED? REPLY(Y=YES,N=NO)?

raise signal:

A C-specific program termination is effected via exit(-1), and the following messages are output:

"CCM0101 signal occurred: signal"

"CCM0999 Exit -1"

Ignore signal

A signal is ignored if the signal function is called with the predefined function SIG_IGN. Program execution continues as if no signal had occurred. No distinction is made in this case between the handling of STXIT events and raise signals.

Handling the signal with a user-defined function fct

A signal is handled in accordance with a user-defined function fct if the signal function is called with the name of this function. When a signal arrives, the calling program is interrupted and the function fct is executed. On termination of signal processing, the program is continued at the point at which it was interrupted (unless the exit or longjmp functions were called in fct).

STXIT event:

fct is implemented internally as an independent STXIT contingency process; the rest of the program as a so called "basic task". Control is effected by the operating system.

raise signal:

fct is treated internally as a "normal" C function and is not implemented via the contingency mechanism. Control is under the C runtime system.

Further details pertaining to the different implementation of signal calls and their various related options are provided in the "Notes".

Parameters

int sig

Signal to be processed.

The symbolic constants listed under "SIGNR" in the following table may be used for sig. These constants are defined in the include file <signal.h>.
In its last column, the table additionally lists the various ways in which the signal can be triggered. The particular STXIT event class is specified for STXIT events.

SIGNR

Meaning

Signal triggered via

SIGHUP

Disconnection of link to terminal

ABEND / raise

SIGINT

Interrupt from the terminal (K2)

ESCPBRK / raise

SIGILL

Execution of an invalid instruction

PROCHK / raise

SIGABRT

raise signal for program abortion with
_exit(-1); abort

raise / abort

SIGFPE

Error in a floating-point operation

PROCHK / raise

SIGKILL

raise signal for program abortion with
_exit(-1); abort

raise

SIGSEGV

Memory access with invalid segment access

ERROR / raise

SIGALARM

A time interval has elapsed (real time)

RTIMER / raise / alarm

SIGTERM

Program termination

TERM / raise

SIGUSR1

Defined by the user

raise

SIGUSR2

Defined by the user

raise

SIGDVZ

Division by 0

PROCHK / raise

SIGXCPU

CPU time has run out

RUNOUT / raise

SIGBPT

Breakpoint (not supported)

SVC

SIGTIM

A time interval has elapsed (CPU time, SETIC)

TIMER / raise

SIGINTR

SEND-MESSAGE command

INTR / raise

SIGSVC

SVC call (not supported)

SVC

The symbolic constant for the signal number can be supplemented with an additional symbolic name, e.g. signal(SIGDVZ + SIG_PSK, fct). This addition (“+ SIG_PSK” in the example) controls whether the function fct is to be activated only on the basis of an STXIT event or also on the basis of a raise signal. In addition, it also determines whether fct is to be temporarily or permanently assigned to the associated signal. Technical details on this topic are provided in the “Notes”. The symbolic names are defined in <signal.h>.

If no addition is specified, the system defaults to SIG_TSK.

Symbolic name

Assignment

Activation via

SIG_TSK

temporary

STXIT / raise (default)

SIG_TS

temporary

STXIT

SIG_PSK

permanent

STXIT / raise

SIG_PS

permanent

STXIT

void (*fct)(int)

Name of the function to be called if a signal occurs. This function receives the signal number of type int as its only argument. The function must be defined before the corresponding signal call!

There are two predefined functions in <signal.h>:

SIG_DFL

This function is the default and causes the program to abort. The manner of termination depends on whether an STXIT event or a raise signal is involved (see above).

SIG_IGN

The signal is ignored.

Return val.

The signal handling function valid prior to the signal call,



if successful. signal returns the last setting for signal handling, which can be SIG_DFL, SIG_IGN, or a user-defined function fct.


SIG_ERR (= 1)

in case of error, e.g. if sig is not a valid signal number or fct points to an invalid address.
In addition, errno is set to the appropriate error code:
EINVAL (invalid argument)
EFAULT (invalid address).

Notes

The signal SIGKILL cannot be intercepted, i.e. neither a user-defined function nor SIG_IGN may be assigned to it.

If a second function for signal handling is registered for a signal that already has a signal handling function assigned to it, the first function is unassigned before the new function is registered. Consequently, there will be no signal handling registered for that signal for a brief 
period of time.

It is not possible to use a longjmp call to return from a function assigned to the signal SIGTERM. This is because entries in the C runtime stack have already been cleared for all functions, including main, at the time the signal is triggered.

Temporary/permanent allocation :
Provisions for the temporary assignment of a signal to a function have been made in many implementations (e.g. UNIX) as well as in the ANSI standard. This means that the userdefined assignment of a function to a signal number is only valid temporarily, i.e. for a single occurrence of the signal. The assignment is cancelled after the signal arrives, and the system resets to the default SIG_DFL (abort program).
Only the SIG_IGN assignment (ignore signal) is permanently valid for multiple occurrences of the associated signal.

  • In BS2000, signal handling for "STXIT event" type signals is implemented via the STXIT contingency mechanism. This mechanism is based on a permanent assignment of an STXIT event to an STXIT contingency routine, i.e. a temporary assignment can only be achieved by explicitly deactivating the routine.

  • In order to provide for the temporary assignment of many implementations on one hand, and to effectively support the permanent nature of BS2000 implementations on the other, both options have been made available, i.e. the user may choose whether a signal routine is assigned temporarily or permanently.

  • For performance reasons, the user is additionally offered the option of deciding whether a signal routine can only be triggered by STXIT events (which is more efficient), or whether it may also be triggered by raise signals.

  • The options noted above are implemented by means of symbolic additions to the actual signal number: SIG_TSK, SIG_TS, SIG_PSK, SIG_PS (see the parameter description for sig).

  • If you want to intercept a signal with fct without exception, the following signal calls are among those that can be used:

    signal(SIGDVZ + SIG_PSK, fct);  /* fct is activated by the STXIT */
                                    /* event and the raise signal SIGDVZ */
    signal(SIGDVZ + SIG_PS, fct);   /* fct is activated only by the STXIT */
                                    /* event SIGDVZ. */ 

    The following calls are equivalent, i.e. both provide for temporary assignment and cause the signal routine to be activated by an STXIT event as well as a raise signal:

    signal(SIGDVZ, fct);
    signal(SIGDVZ + SIG_TSK, fct);

Problems may arise in the case of the three different signal numbers that are mapped by the same STXIT event class (PROCHK). The following signal calls are handled differently, depending on the way in which the signal was triggered:

signal(SIGILL, fct1);
signal(SIGFPE, fct2);
signal(SIGDVZ, fct3);

SIG_DFL is the default for all signals at the start of a program.

In order to execute, a function which is assigned to a signal requires an intact C environment. Consequently, when a program terminates properly, all signal routines are logged off immediately before the C environment is cleared down. No events which occur after this – not even SIGTERM – are then intercepted.

STXIT event:

fct3 is called in any case if the SIGILL and SIGFPE signals are intercepted via the STXIT contingency mechanism. In fact, even if a signal call is only provided for one signal, the assigned routine is activated when any of the three signals arrives.

raise-Signal:

If the signals are triggered with the raise function, on the other hand, the currently assigned function is activated. Signals for which no signal call has been provided are handled as defined by the default setting (SIG_DFL, program abortion).

SIG_DFL is the default for all signals at the start of a program.

In order to execute, a function which is assigned to a signal requires an intact C environment. Consequently, when a program terminates properly, all signal routines are logged off immediately before the C environment is cleared down. No events which occur after this – not even SIGTERM – are then intercepted.

Example

The following program intercepts the STXIT events SIGDVZ (division by 0) and SIGINT (interrupt with the K2 key) with the function fct and outputs a corresponding error message.
After handling both interrupt events (which occur at different positions in the program), the program continues to execute at the same program location (new input prompt) by using the setjmp and longjmp functions.

#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf env;
void fct(int sig)
{
  if(sig == SIGDVZ + SIG_PS)
    printf("Division error, please repeat input\n");
  if(sig == SIGINT + SIG_PS)
    printf("K2 key pressed, please repeat input\n");
  longjmp(env, 1);
}
int main(void)
{
  float a;
  float b;
  double z;
  signal(SIGDVZ + SIG_PS, fct);
  signal(SIGINT + SIG_PS, fct);
  setjmp(env);
  printf("Please enter a and b\n");    /* Interrupt with K2 possible */
  scanf("%f %f", &a, &b);
  z = a / b;                           /* Division by 0 possible, */
                                       /* if b = 0 */
  printf("z = %f\n", z);
  printf ("End of program\n");
  return 0;
}

See also

alarm, longjmp, raise, setjmp