ProDeveloperTutorial.com

Tutorials and Programming Solutions
Menu
  • Shell Scripting
  • System Design
  • Linux System Programming
  • 4g LTE
  • Coding questions
  • C
  • C++
  • DSA
  • GIT
  • 450 DSA Cracker
  • 5G NR
  • O-RAN

Linux System Programming: Linux Signal Handling in C

prodevelopertutorial May 22, 2020

In this chapter we shall learn about:

1. What is a Signal?

2. What is async and sync signal?

3. How a signal can be generated manually or by the program:

4. Different type of signals:

5. Different ways to handle a signal:

6. Different ways for a process to raise a signal:

7. Different ways to handle a signal:

8. Example 1. “sigaction()” system call.

9. Example 2. “signal()” system call.

What is a Signal?

A Signal is a software interrupt sending to a process.

A signal can be generated synchronously or asynchronously.

A signal is generated synchronously, for example, after a timer got expired.

A signal is generated asynchronously, for example, due to executing program segmentation fault.

A signal also be generated manually or by the program:

A signal can be generated manually, by pressing “Ctrl+c” that sends SIGINT

A signal can be generated by the executing program when there is a segmentation fault, that sends a SIGSEGV signal to the program.

Different type of signals:

Linux has defined 64 signals and start with “SIG”.
Below are some of the signals:

Termination Signals:
These signals are used to tell a process to terminate.

SIGTERM
SIGINT
SIGQUIT
SIGKILL

Alarm Signals:
These signals are used to indicate timer expiry.
SIGALRM
SIGVTALRM

Other signals:
SIGSEGV
SIGBUS
SIGABRT
SIGSYS

Different ways to handle a signal:

A signal can be handled in many different ways.

1. First option is to ignore it. Most of the signals can be ignored, not all. Hardware exceptions like “divide by 0” cannot be ignored.

2. Catch the signal and handle the exception.

3. Apply the default action. Many signals will be having an default action. Like terminate, terminate and core dump, stop the program etc.

Different ways for a process to raise a signal:

1. int raise(getpid(), int S)

Sends a signal “S” to a calling thread.

2. int kill(pid_t PID, int S)

It sends a signal “S” to a process or process group.

3. int pthread_kill(pthread_t TID, int S)

It will send a signal S to a specified thread with thread ID TID.

Different ways to handle a signal:

There are 2 ways that you can handle a signal.

1. By using “sigaction()” system call.
2. By using “signal()” system call.

All the signal system calls are defined in the header file:
#include <signal.h>

1. By using “sigaction()” system call.

int sigaction(int S, const struct sigaction * Act, struct sigaction * OldAct)

You need to fill “sigaction” structure as below:

sa_handler: The signal handler function
sa_flags: Flags to modify the behavior of the handler, or 0
sa_mask: A set of signals to block while this one is being handled

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>

void sigint_handler(int sig)
{
    printf("received SIGINT\n");
}

int main(void)
{
    void sigint_handler(int sig); /* prototype */
    char s[200];
    struct sigaction sa; /* set the sigaction structure */

    sa.sa_handler = sigint_handler;
    sa.sa_flags = 0; 
    sigemptyset(&sa.sa_mask);

    if (sigaction(SIGINT, &sa, NULL) == -1) 
    {
        perror("sigaction");
        exit(1);
    }
    
    while(1)
    {
      sleep(1);
    }

    return 0;
}

Output:

^Creceived SIGINT
^Creceived SIGINT
^Creceived SIGINT

Once you enter “ctrl+c”, you will get above output

 

2. By using “signal()” system call.

The “signal()” system call is less standard than “sigaction()”.

It is much simpler version also. Take it as a learning purpose, it is recommended to use “sigaction()”.

sighandler_t signal(int signum, sighandler_t handler);

#include<stdio.h>
#include<signal.h>
#include<unistd.h>

void sig_handler(int signo)
{
  if (signo == SIGINT)
    printf("received SIGINT\n");
}

int main(void)
{
  if (signal(SIGINT, sig_handler) == SIG_ERR)
  printf("\n Cannot catch SIGINT\n");
  

  while(1)
  {
    sleep(1);
  }
  return 0;
}

Output:

^Creceived SIGINT
^Creceived SIGINT
^Creceived SIGINT

Once you enter “ctrl+c”, you will get above output

 

List Of Tutorials available in this website:

C Programming 20+ ChaptersC++ Programming 80+ Chapters
100+ Solved Coding QuestionsData Structures and Algorithms 85+ Chapters
System design 20+ ChaptersShell Scripting 12 Chapters
4g LTE 60+ ChaptersMost Frequently asked Coding questions
5G NR 50+ ChaptersLinux System Programming 20+ chapters
Share
Email
Tweet
Linkedin
Reddit
Stumble
Pinterest
Prev Article

About The Author

prodevelopertutorial

Follow this blog to learn more about C, C++, Linux, Competitive Programming concepts, Data Structures.

ProDeveloperTutorial.com

Tutorials and Programming Solutions
Copyright © 2022 ProDeveloperTutorial.com