Applying C - Signals
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
  6. Fixed Point
    Extract Simple Fixed Point Arithmetic
  7. Floating Point
  8. File Descriptors
    Extract: Simple File Descriptors ***NEW
  9. The Pseudo-File System
    Extract: The Pseudo File System 
  10. Graphics
    Extract: framebuffer 
  11. Sockets
  12. Threading
    Extract  Condition Variables
    Extract  Deadline Scheduling
  13. Cores Atomics & Memory Management
  14. Interupts & 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


Infragistics Ignite UI For Angular Improves Data Grid
08/09/2020

Infragistics has announced Ignite UI for Angular v 10.1.0, a month after the release by Google of Angular 10.1. The updated UI includes new features and enhancements to its Angular data grid, new [ ... ]



Introduction to OAuth 2.0 and OpenID Connect
17/09/2020

Getting familiar with OpenID and OAuth is really difficult.There are dozens of specifications to go through, and to make things even worse the two protocols involve different terminology. To help out, [ ... ]


More News

graphics

 



 

Comments




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



Last Updated ( Monday, 09 March 2020 )