We may define a signal as an activity that is triggered to alert an operation or thread whenever the time of arrival for a certain significant situation. Whenever a procedure or thread acknowledges a signal, the procedure or thread will halt whatever it is doing and take immediate action. In inter-process coordination, the signal can be effective. In this guide, you will study signal handlers in Linux through the C language.

Standard or Regular Signals:

The header file ‘signal.h’ has signals specified in it as a macro constant. The title of the signal began with “SIG” and is preceded by a brief signal overview. Consequently, any signal does have a distinct numeric value. The program code should use the signal’s name, not several signals. The cause behind it is that the number of signals can vary depending on the system, but the interpretation of names is standard. Below are some regular signals with their functionality defined.

SIGHUP:

This signal will hang-up the processing. The SIGHUP signal is being cast off to indicate user terminal disassociation, likely due to a remote communication being broken or hanging up.

SIGINT:

It will disrupt the process. The SIGINT signal is received whenever the user inputs the INTR key (usually Ctrl C).

SIGQUIT:

It will stop or exit the processing. The SIGQUIT signal is received whenever the user inputs the QUIT key (usually Ctrl ).

SIGILL:

It runs when an illicit command has been made. The SIGILL signal is created whenever an effort is being made to perform a junk or privileged command. Whenever the stack overflows and the machine has problems running a signal controller, SIGILL may also be created.

SIGTRAP:

It is called when some trace trap instruction is being executed. The SIGTRAP signal is created by a breakpoint command and another trap command. The debugger uses such a signal.

SIGABRT:

It is called the Abort signal. The SIGABRT signal is created by calling the abort() method. Such a signal is used to point out the inaccuracy observed by the code the aforementioned and recorded by the abort() method call.

SIGFPE:

Exception for floating-points; The SIGFPE signal is produced when a catastrophic mathematical error occurs.

SIGUSR1 and SIGUSR2:

The SIGUSR1 and SIGUSR2 signals could be used the way you like. It is beneficial for easy interprocess interaction to create a signal handler for such signals in the application that gets the signal.

Default Behavior of Signals:

There is standard behavior or action per each signal, and it is possible to adjust the default behavior using the handler function. The automatic SIGKILL and SIGABRT signal behavior could not be modified or neglected.

Term: It will terminate the operation.

Core: A core dump document will be generated, and the operation will be terminated.

Ign: The process would overlook a signal.

Stop: It’ll halt the operation.

Cont: The operation will be sustained from being halted.

Signal Handling:

The process has a preference of behavior for a signal when it is acknowledged. The process may behave like the following:

The signal is automatically dismissed when the defined signal behavior is overlooked.

Using methods like signal or sigaction, the code may register a handler function. It is called catching a signal from a handler.

If a signal is not being treated or neglected, the standard action may occur.

You can define the Signal Handling function as:

 $ Int signal () int signum, void (*funk)(int))

When the processing obtains a signal signum, the signal() method may call the ‘func’ method. Signal() reverts a pointer to the ‘func’ method if it’s prosperous or an exception is returned to errno and -1 instead.

The ‘func’ pointer is capable of having three values:

SIG_DFL: This is a pointer to the standard SIG DFL() method, defined in the header.h document used for getting the signal’s standard behavior.

SIG_IGN: This is a reference to the SIG IGN() ignore method, specified in the header.h document.

User-defined handler method pointer: The user-defined handler method type void(*)(int), implies that the return category is void and that solitary argument is int.

Create a new file ‘signal.c’ and write below signal handler code in it.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s1.png" data-lazy- height="342" src="data:image/svg xml,” width=”728″>

Link the signal.c file with gcc.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s2.png" data-lazy- height="24" src="data:image/svg xml,” width=”705″>

While running the signal.c file, we have got an endless loop carrying out in the main method. On pressing CTRL C, it started the handler method, and the main method execution stopped. The main method processing continued after the accomplishment of the handler method. Upon hitting Ctrl , the operation quits.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s3.png" data-lazy- height="182" src="data:image/svg xml,” width=”716″>

Signal Ignore:

For overlooking the signal, create a file ‘signal.c’ and write underneath code in it.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s4.png" data-lazy- height="250" src="data:image/svg xml,” width=”730″>

Tie the ignore.c file with gcc.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s5.png" data-lazy- height="18" src="data:image/svg xml,” width=”704″>

Run the signal.c file. Tap CTRL C, SIGNIT signal is created; nevertheless, the behavior is unnoticed because the handler method is enumerated to SIG_IGN() method.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s6.png" data-lazy- height="128" src="data:image/svg xml,” width=”706″>

Reregister Signal Handler:

To re-register the signal handler, create a new file ‘rereg.c’ and inscribe the below code in it:

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s7.png" data-lazy- height="341" src="data:image/svg xml,” width=”721″>

Associate the rereg.c file with gcc.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s8.png" data-lazy- height="21" src="data:image/svg xml,” width=”710″>

Run the rereg.c file. While first time pressing CTRL C handler method raised, and signal handler re-registered to SIG_DFL. While pressing CTRL C again, the execution got terminated.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s9.png" data-lazy- height="127" src="data:image/svg xml,” width=”715″>

Send Signals Using Raise():

Create a file ‘send.c’ and add the below code. For sending signals to the calling method, the raise() method is used.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s10.png" data-lazy- height="308" src="data:image/svg xml,” width=”725″>

Relate the send.c file with gcc.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s11.png" data-lazy- height="21" src="data:image/svg xml,” width=”721″>

The process utilizes the raise() method to transmit the SIGUSR1 signal on its own.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s12.png" data-lazy- height="73" src="data:image/svg xml,” width=”712″>

Send Signals Using Kill():

Add the below code in ‘raise.c’. Use the kill method() to send signals to the process group.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s13.png" data-lazy- height="324" src="data:image/svg xml,” width=”728″>

Link the raise.c file with gcc.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s14.png" data-lazy- height="20" src="data:image/svg xml,” width=”717″>

By using the kill() method, the process directs the SIGUSR1 signal to the aforementioned.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s15.png" data-lazy- height="70" src="data:image/svg xml,” width=”719″>

Parent-Child Interaction:

To watch parent-child interaction, write the below code in a file.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s16.png" data-lazy- height="538" src="data:image/svg xml,” width=”714″>

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s17.png" data-lazy- height="126" src="data:image/svg xml,” width=”718″>

Bond the comm.c file with gcc.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s18.png" data-lazy- height="18" src="data:image/svg xml,” width=”721″>

Fork()/ method generates child, revert zero to the child process, and child ID to parent.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/s19.png" data-lazy- height="109" src="data:image/svg xml,” width=”718″>

Conclusion:

In this guide, we have seen how to create, handle, send, ignore, re-register and use the signal for inter-process interaction in Linux.

About the author

<img alt="Aqsa Yasin" data-lazy-src="https://kirelos.com/wp-content/uploads/2021/02/echo/Author-Image-150×150.jpg601ec91806c29.jpg" height="112" src="data:image/svg xml,” width=”112″>

Aqsa Yasin

I am a self-motivated information technology professional with a passion for writing. I am a technical writer and love to write for all Linux flavors and Windows.