C signal handling

Last updated

In the C Standard Library, signal processing defines how a program handles various signals while it executes. A signal can report some exceptional behavior within the program (such as division by zero), or a signal can report some asynchronous event outside the program (such as someone striking an interactive attention key on a keyboard).

Contents

Standard signals

The C standard defines only 6 signals. They are all defined in signal.h header (csignal header in C++): [1]

Additional signals may be specified in the signal.h header by the implementation. For example, Unix and Unix-like operating systems (such as Linux) define more than 15 additional signals; see Unix signal. [2]

Debugging

Handling

A signal can be generated by calling raise() or kill() system calls. raise() sends a signal to the current process, kill() sends a signal to a specific process.

A signal handler is a function which is called by the target environment when the corresponding signal occurs. The target environment suspends execution of the program until the signal handler returns or calls longjmp().

Signal handlers can be set with signal() or sigaction(). The behavior of signal() has been changed multiple times across history and its use is discouraged. [3] It is only portable when used to set a signal's disposition to SIG_DFL or SIG_IGN. Signal handlers can be specified for all but two signals (SIGKILL and SIGSTOP cannot be caught, blocked or ignored).

If the signal reports an error within the program (and the signal is not asynchronous), the signal handler can terminate by calling abort(), exit(), or longjmp().

Functions

FunctionDescription
raise artificially sends a signal to the calling process
killartificially sends a signal to a specified process
signal sets the action taken when the program receives a specific signal

Example usage

#include<signal.h>#include<stdio.h>#include<stdlib.h>volatilesig_atomic_tstatus=0;staticvoidcatch_function(intsigno){status=signo;}intmain(void){// Set above function as signal handler for the SIGINT signal:if(signal(SIGINT,catch_function)==SIG_ERR){fputs("An error occurred while setting a signal handler.\n",stderr);returnEXIT_FAILURE;}puts("Raising the interactive attention signal.");if(raise(SIGINT)){fputs("Error raising the signal.\n",stderr);returnEXIT_FAILURE;}if(status==SIGINT)puts("Interactive attention signal caught.");puts("Exiting.");returnEXIT_SUCCESS;// exiting after raising signal}

See also

Related Research Articles

In computing, a segmentation fault or access violation is a fault, or failure condition, raised by hardware with memory protection, notifying an operating system (OS) the software has attempted to access a restricted area of memory. On standard x86 computers, this is a form of general protection fault. The operating system kernel will, in response, usually perform some corrective action, generally passing the fault on to the offending process by sending the process a signal. Processes can in some cases install a custom signal handler, allowing them to recover on their own, but otherwise the OS default signal handler is used, generally causing abnormal termination of the process, and sometimes a core dump.

On Unix and Unix-like computer operating systems, a zombie process or defunct process is a process that has completed execution but still has an entry in the process table: it is a process in the "terminated state". This occurs for the child processes, where the entry is still needed to allow the parent process to read its child's exit status: once the exit status is read via the wait system call, the zombie's entry is removed from the process table and it is said to be "reaped". A child process initially becomes a zombie, only then being removed from the resource table. Under normal system operation, zombies are immediately waited on by their parent and then reaped by the system. Processes that stay zombies for a long time are usually an error and can cause a resource leak. Generally, the only kernel resource they occupy is the process table entry, their process ID. However, zombies can also hold buffers open, consuming memory. Zombies can hold handles to file descriptors, which prevents the space for those files from being available to the filesystem. This effect can be seen by a difference between du and df. While du may show a large amount of free disk space, df will show a full partition. If the zombies are not cleaned, this can fill the root partition and crash the system.

Berkeley sockets is an application programming interface (API) for Internet sockets and Unix domain sockets, used for inter-process communication (IPC). It is commonly implemented as a library of linkable modules. It originated with the 4.2BSD Unix operating system, which was released in 1983.

In computer programming, standard streams are preconnected input and output communication channels between a computer program and its environment when it begins execution. The three input/output (I/O) connections are called standard input (stdin), standard output (stdout) and standard error (stderr). Originally I/O happened via a physically connected system console, but standard streams abstract this. When a command is executed via an interactive shell, the streams are typically connected to the text terminal on which the shell is running, but can be changed with redirection or a pipeline. More generally, a child process inherits the standard streams of its parent process.

The C programming language provides many standard library functions for file input and output. These functions make up the bulk of the C standard library header <stdio.h>. The functionality descends from a "portable I/O package" written by Mike Lesk at Bell Labs in the early 1970s, and officially became part of the Unix operating system in Version 7.

errno.h is a header file in the standard library of the C programming language. It defines macros for reporting and retrieving error conditions using the symbol errno.

Signals are standardized messages sent to a running program to trigger specific behavior, such as quitting or error handling. They are a limited form of inter-process communication (IPC), typically used in Unix, Unix-like, and other POSIX-compliant operating systems.

In computing, kill is a command that is used in several popular operating systems to send signals to running processes.

In computing, the exit status, or exit code, of a terminated process is an integer number that is made available to its parent process. In DOS, this may be referred to as an errorlevel.

In computer programming, an entry point is the place in a program where the execution of a program begins, and where the program has access to command line arguments.

<span class="mw-page-title-main">Xlib</span> Client library for the X Window System

Xlib is an X Window System protocol client library written in the C programming language. It contains functions for interacting with an X server. These functions allow programmers to write programs without knowing the details of the X protocol.

In computing, sigaction is a function API defined by POSIX to give the programmer access to what should be a program's behavior when receiving specific OS signals.

In C programming, the functions getaddrinfo and getnameinfo convert domain names, hostnames, and IP addresses between human-readable text representations and structured binary formats for the operating system's networking API. Both functions are contained in the POSIX standard application programming interface (API).

Exception handling syntax is the set of keywords and/or structures provided by a computer programming language to allow exception handling, which separates the handling of errors that arise during a program's operation from its ordinary processes. Syntax for exception handling varies between programming languages, partly to cover semantic differences but largely to fit into each language's overall syntactic structure. Some languages do not call the relevant concept "exception handling"; others may not have direct facilities for it, but can still provide means to implement it.

In computer science, the event loop is a programming construct or design pattern that waits for and dispatches events or messages in a program. The event loop works by making a request to some internal or external "event provider", then calls the relevant event handler. The event loop is also sometimes referred to as the message dispatcher, message loop, message pump, or run loop.

assert.h is a header file in the C standard library. It defines the C preprocessor macro assert and implements runtime assertion in C.

The C date and time functions are a group of functions in the standard library of the C programming language implementing date and time manipulation operations. They provide support for time acquisition, conversion between date formats, and formatted output to strings.

A weak symbol denotes a specially annotated symbol during linking of Executable and Linkable Format (ELF) object files. By default, without any annotation, a symbol in an object file is strong. During linking, a strong symbol can override a weak symbol of the same name. In contrast, in the presence of two strong symbols by the same name, the linker resolves the symbol in favor of the first one found. This behavior allows an executable to override standard library functions, such as malloc(3). When linking a binary executable, a weakly declared symbol does not need a definition. In comparison, a declared strong symbol without a definition triggers an undefined symbol link error.

setjmp.h is a header defined in the C standard library to provide "non-local jumps": control flow that deviates from the usual subroutine call and return sequence. The complementary functions setjmp and longjmp provide this functionality.

mtrace is the memory debugger included in the GNU C Library.

References

  1. ISO/IEC 9899:1999 specification (PDF). p. 258, § 7.14 Signal handling.
  2. "The Open Group Base Specifications Issue 6 – signal.h – signals" . Retrieved 10 January 2012.
  3. https://man7.org/linux/man-pages/man2/signal.2.html Signal(2) manpage