Applying C - Signals
Written by Harry Fairhead   
Monday, 09 March 2020
Article Index
Applying C - Signals
Controlling Signals
Sending Signals

Sending Signals

Signals are most often thought of as software interrupts that indicate some sort of error has occurred. In fact, any process can use a signal to communicate with another process. It is a matter of opinion how useful this is, but it does have the advantage of being simple.

There are a number of functions which can be used to send a signal to a process.

The function:

kill(pid, sig);

works in the same way as the kill command. You specify the PID number of the process you want to send the signal sig to. If you specify 0 then the signal is sent to every process in the same group as the calling process. If you set it to -1 then the signal is sent to every process that the calling process has permission to send it to. Any other negative PID sends the signal to the process group with that ID. A simpler way of doing this is to use the function:

killpg(pgrp,sig);

which sends sig the process group pgrp. If pgrp is 0 then sig is sent to the calling process’s group. Notice you can set the process group of any process you create using C functions or the command line.

Finally, if sig is 0 then no signal is sent, but error checking is performed as if it had been. You can use this to check that a process, or process group, exists. To send a signal, the sender either has to be running as root or as the same user as the receiving process.

The function:

raise(sig);

is the same as:

kill(getpid(),sig);

i.e. it sends the signal to the calling program.

The function:

sigqueue(pid,sig,value);

will send the signal to the process specified by pid and value will be stored in the sig_value field of the siginfo_t struct.

You can send a signal directly to a thread using:

pthread_kill(thread,sig);

This interrupts the specified thread and performs the action common to all the threads.

Waiting for Signals

There are two functions which cause a process to suspend until a signal occurs. The simplest is:

pause();

and it just pauses the process or thread until a handled or unhandled signal occurs. Slightly more sophisticated is:

sigsuspend(&mask)

which does the same thing as pause, but it sets the signal mask for the duration of the suspension. This means you can use mask to temporarily change what signals are allowed.

Notice that pause and sigsuspend cause a handler to be call asynchronously and the program only continues if the handler returns.

You can also wait for a signal without the help of a handler function.

The process simply waits for the signal and continues when the signal happens i.e. a synchronous signal processing. Another way to think of this is that the process blocks until the signal occurs.

There are three functions that perform a synchronous wait:

sigwait(&mask, &sig);
sigwaitinfo(&mask, &info);
sigtimedwait(&mask, &info, &timeout);

They work in more or less the same way. The mask determines which signals are waited for. For sigwait all that is returned when the signal occurs is its signal number. For sigwaitinfo and sigtimedwait you get a complete siginfo_t struct containing all the information about the signal and sigtimedwait also specifies a timeout via the timespec struct.

There is one subtle point that isn't made very clear in the documentation. The signal that you are waiting for has to be blocked in the calling program and all threads. If it isn't then the result is undefined behavior which in practice generally means that you get default behavior or a handler called.

In chapter but not included in this extract.

  • Real-time Signals
  • Signals as IPC
  • Everything is a File - Including Signals
  • Setjmp Non-local Jumps
  • Are Signals Useful?

Summary

  • Signals are system-generated software interrupts and their default behavior is to terminate the program that receives them.

  • You can write signal handlers that are called asynchronously when the signal occurs.

  • The asynchronous nature of signals means you have to protect against interruptions and restarts. In particular, make sure you block signals when in a signal handler.

  • Syscalls are a particular problem in that a signal can occur while they are executing. It is possible to automatically restart an interrupted syscall, but it is usually better to test manually for a signal interruption and control the restart.

  • Your program can send a signal to another process and a process can wait for a signal.

  • Sending and waiting on a signal can be used as a simple inter-process communication method.

  • Signals can be treated synchronously using a file to access them.

  • Sometime you need setjmp to implement a non-local jump to successfully handle a signal. This can be used to implement a try-catch style of programming.

 

 

Now available as a paperback or ebook from Amazon.

Applying C For The IoT With Linux

  1. C,IoT, POSIX & LINUX
  2. Kernel Mode, User Mode & Syscall
  3. Execution, Permissions & Systemd
    Extract Running Programs With Systemd
  4. Signals & Exceptions
    Extract  Signals
  5. Integer Arithmetic
    Extract: Basic Arithmetic As Bit Operations
  6. Fixed Point
    Extract: Simple Fixed Point Arithmetic
  7. Floating Point
  8. File Descriptors
    Extract: Simple File Descriptors 
    Extract: Pipes 
  9. The Pseudo-File System
    Extract: The Pseudo File System
    Extract: Memory Mapped Files ***NEW
  10. Graphics
    Extract: framebuffer
  11. Sockets
    Extract: Sockets The Client
    Extract: Socket Server
  12. Threading
    Extract:  Pthreads
    Extract:  Condition Variables
    Extract:  Deadline Scheduling
  13. Cores Atomics & Memory Management
    Extract: Applying C - Cores 
  14. Interupts & Polling
    Extract: Interrupts & Polling 
  15. Assembler
    Extract: Assembler

Also see the companion book: Fundamental C

<ASIN:1871962609>

<ASIN:1871962463>

<ASIN:1871962617>

<ASIN:1871962455>

Related Articles

Remote C/C++ Development With NetBeans

Raspberry Pi And The IoT In C

Getting Started With C/C++ On The Micro:bit

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


Call For Code 2024 Focuses On Generative AI
01/03/2024

This year's Call for Code challenge has been launched with a theme of the use of generative AI technology for solutions that aim to improve equitable access to resources and opportunities for historic [ ... ]



Chainguard Joins Docker Verified Publisher Program
15/03/2024

Chainguard has joined the Docker Verified Publisher (DVP) program, meaning its Chainguard Developer Images are now officially available on Docker's container image registry.


More News

raspberry pi books

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Monday, 09 March 2020 )