After the Ubuntu 20.04 successful login, you need to launch the shell of the Ubuntu 20.04 system first after the login. So, try out the “Ctrl+Alt+T” shortcut simply on the desktop screen. It will launch the terminal shell for you in some seconds. Make sure to update your system using the apt package of your system. After that, you have to execute the “touch” instruction along with the file name you want to generate, i.e., to create the C file via the shell. This newly created file can be found in the “home” folder of your system’s file explorer. You can try opening it with the “text” editor to create code in it. Another way to open it in the shell is using the “GNU Nano” editor using the “nano” keyword with a file name as demonstrated beneath.
We have started our code in the “nano” editor by including some necessary C headers. These headers might be the most common headers like “stdio.h”, “unistd.h”, and “stdlib.h”. Other than that, the most important header file “signal.h” has been added to utilize the signal handling functions in C code. All the work has been done in this program’s main() method. So, after starting the method, we have initialized some signal construct variables using the “sigset_t” object, i.e., s, os, and ps. The “s” stands for signal, “os” stands for an original signal set, and the “ps” stands for a pending signal set.
The “sigemptyset” has been using the “s” construct to initialize or declare a signal mask and disregard all the signals. After this, the “sigaddset” function has been utilized to add the initialized signal “s” to the specified SIGINT signal set. The SIGINT signal handler routine refers to the “Ctrl+C,” i.e., interrupt character. It will stop the execution of the current process and come back to the main loop.
Now comes the sigprocmask function here using three parameters. The SIG_BLOCK parameter shows that all the signals found in a signal set “s” will be added to the current signal set. The &s indicates the pointer to a specific signal set that has been used to alter the signal mask as per the “SIGINT” construct. The “os” parameter points towards the signal set storing the signal mask for a particular method. The printf statement is here to display the old signal mask of the signal set. The “sigpending” function is here to save data regarding the signals within the signal set that are pending. The printf statement is again here to show the pending signal set on the shell using the “ps” construct. The “kill” method came up here to kill the current process using the process ID via the “getpid()” function. The sigpending function is again called to get the pending signals in the set, and the printf statement will display those. The sigprocmask function uses the “SIG_UNBLOCK” predefined set to continue unblocking and raising the function in the pending list. The “s” signal set will be released with the help of signal mask “os.”
Compile your C code file using the shown-below instruction in the shell.
Your file has been executed. It will show you the old signal set on the shell, “os.” But, as the signals of set “s” are now blocked, we will see the signals are receiving but pending and not executing. We cannot kill the process as the processing of signals is blocked. At last, we have released the signals.
Let’s look at another example of the “sigprocmask” function is C to block and unblock the specific signal set. So, we have added a new file and tried a new code. First, you need to add the same header files in the code file, as shown below. The user-defined “catcher” function is here to simply display that we are inside this function using its printf function.
The main execution starts from the main() function of our code. It contains two arguments. First of all, we have utilized time constructs “s” for start and “f” for finish via the ‘time_t” keyword. The structure sigaction is declared as “sact” to set nature for a signal for doing something. The “sigset_t” construct is used to declare two signal sets, i.e., “ns” for a new set and “os” for old sets. The double type variable “dif” is declared. First of all, the sigemptyset function is used to initialize the signal mask for “sact” structure and exclude all signals. The sa_flags handler has been used for bitmask of sigaction and initialized to zero. The “sa_handler” has been used to declare the “catcher” function as signal handler using the “sact” sigaction object. The sigaction function is called here using the SIGALRM to set the alarm for the signal “sact” here.
The “sigemptyset” has been utilized on the “ns” signal set to initialize a signal mask and exclude all the signals. The sigaddset function adds the SIGALRM to the “ns” signal set. The sigprocmask adds the “ns” signals to the current signal set. The “os” signal set represents the signal mask for a particular process. The start time has been noted and printed out using the “ctime()” function in printf. The alarm for 1 second is initialized, and the finish time has been noted. The difference between finish and start times has been calculated using the “difftime” function. If the difference is less than 10 seconds, the sigprocmask function will use the “os” signal set to replace the present signal mask for a particular process using SIG_SETMASK. The last printf statement is here to show the time when a signal set is released for alarms.
After compiling and running the file, it shows us the time when the alarm signal set is blocked. After a few seconds, the catcher function is called, and another statement shows the unblocking time of the alarm signal set to release.
This article shows the explanation regarding sigprocmask function usage in the C language. We have discussed 2 brief and straightforward examples to illustrate the working of the sigprocmask function along with other signal functions. We hope that this article would be a bonus to every user who is new to signals.