Computer Networking Notes Module 5
Computer Networking Notes Module 5
Computer Networking Notes Module 5
MODULE-5
Chapter 11 Signals and Daemon Processes
Topics
Signals:
The UNIX kernel support for signals, signal, signal mask, sigaction, the SIGCHLD signal and
the waitpid function, the sigsetjmp and siglongjmp functions, kill, alarm, interval timers,
POSIX.1b Timers.
Daemon Processes:
Introduction, Daemon characteristics, coding rules, error logging, client-server model.
Introduction
Signals are software interrupts. Signals provide a way of handling asynchronous events: a user at
a terminal typing the interrupt key to stop a program or the next program in a pipeline terminating
prematurely.
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 1
Unix Programming (18CS56) V-ISE, MODULE-5
SIGSTOP stop stop process
SIGSYS invalid system call terminate+core
SIGTERM termination terminate
SIGTHAW checkpoint thaw ignore
SIGTRAP hardware fault terminate+core
SIGTSTP terminal stop character stop process
SIGTTIN background read from control tty stop process
When a signal is sent to a process, it is pending on the process to handle it. The process can
react to pending signals in one of three ways:
Accept the default action of the signal, which for most signals will terminate the
process.
Ignore the signal. The signal will be discarded and it has no affect whatsoever on
the recipient process.
Invoke a user-defined function. The function is known as a signal handler routine
and the signal is said to be caught when this function is called.
Process may set up per-signal handling mechanisms – ignores some signals, catches
some other signals and accepts default action from the remaining signals.
Process may change handling of certain signals in its course of execution.
Signal is said to have been delivered if it has been reacted to by the recipient process.
Default action for most signals – terminate a recipient process.
Some signals will generate a core file for the aborted process – users can trace back the
state of the process when it was aborted.
These signals are usually generated when there is an implied program error in the
aborted process.
Most signals can be ignored or caught except SIGKILL and SIGSTOP signals.
Companion signal to SIGSTOP is SIGCONT, which resumes a process execution after it
has been stopped.
Process is allowed to ignore certain signals so that it is not interrupted while doing
certain mission-critical work.
Signal handler function cleans up the work environment of a process before
terminating the process gracefully.
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 2
Unix Programming (18CS56) V-ISE, MODULE-5
If array entry contains a 1 value, the process will ignore the signal and kernel will
discard it.
If array entry contains any other value, it is used as the function pointer for a user-
defined signal handler routine.
UNIX System V.2 - when a signal is caught, kernel will first reset the signal handler in
the recipient process U-area, then call the user signal handling function specified for
that signal.
Multiple instances of a signal being sent to a process at different points – the process
will catch only the first instance of the signal.
All subsequent instances of the signal – handled in the default manner.
Continuously catching multiple occurrences of a signal – process must reinstall the
signal handler function every time the signal is caught.
Time between signal handler invoking and re-establishment of signal handler method -
another instance of signal may be delivered to the process. Leads to race condition.
Solving the unreliability of signal handling in UNIX System V.2 - BSD UNIX 4.2 and
POSIX.1 use alternate method.
When a signal is caught – kernel does not reset the signal handler, so there is no need
for the process to re-establish the signal handling method.
Kernel will block further delivery of the same signal to the process until the signal
handler function has completed execution.
Ensures that signal handler function will not be invoked recursively for multiple
instances of the same signal.
Triggered by events and posted on a process to notify it that something has happened
and requires some action.
Event can be generated from a process, a user or the UNIX kernel.
Parent and child processes can send signals to each other for process synchronization.
Signals are the software version of hardware interrupts.
The function prototype of the signal API is:
#include <signal.h>
void (*signal(int sig_no, void (*handler)(int)))(int);
The formal argument of the API are: sig_no is a signal identifier like SIGINT or SIGTERM.
The handler argument is the function pointer of a user-defined signal handler function.
The following example attempts to catch the SIGTERM signal, ignores the SIGINT signal, and
accepts the default action of the SIGSEGV signal. The pause API suspends the calling process
until it is interrupted by a signal and the corresponding signal handler does a return:
#include<iostream.h>
#include<signal.h>
/*signal handler function*/
void catch_sig(int sig_num)
{
signal (sig_num,catch_sig);
cout<<”catch_sig:”<<sig_num<<endl;
}
/*main function*/
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 3
Unix Programming (18CS56) V-ISE, MODULE-5
int main()
{
signal(SIGTERM,catch_sig);
signal(SIGINT,SIG_IGN);
signal(SIGSEGV,SIG_DFL);
pause( ); /*wait for a signal interruption*/
}
The SIG_IGN specifies a signal is to be ignored, which means that if the signal is generated to the
process, it will be discarded without any interruption of the process.
The SIG_DFL specifies to accept the default action of a signal.
If the actual argument to new_mask argument is a NULL pointer, the cmd argument will be
ignored, and the current process signal mask will not be altered.
If the actual argument to old_mask is a NULL pointer, no previous signal mask will be
returned.
The sigset_t contains a collection of bit flags.
The BSD UNIX and POSIX.1 define a set of API known as sigsetops functions:
#include<signal.h>
int sigemptyset (sigset_t* sigmask);
int sigaddset (sigset_t* sigmask, const int sig_num);
int sigdelset (sigset_t* sigmask, const int sig_num);
int sigfillset (sigset_t* sigmask);
int sigismember (const sigset_t* sigmask, const int sig_num);
The sigemptyset API clears all signal flags in the sigmask argument.
The sigaddset API sets the flag corresponding to the signal_num signal in the sigmask
argument.
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 4
Unix Programming (18CS56) V-ISE, MODULE-5
The sigdelset API clears the flag corresponding to the signal_num signal in the sigmask
argument.
The sigfillset API sets all the signal flags in the sigmask argument.
[ all the above functions return 0 if OK, -1 on error ]
The sigismember API returns 1 if flag is set, 0 if not set and -1 if the call fails.
The following example checks whether the SIGINT signal is present in a process signal mask
and adds it to the mask if it is not there.
#include<stdio.h>
#include<signal.h> int main()
{
sigset_t sigmask;
sigemptyset(&sigmask); /*initialise set*/
A process can query which signals are pending for it via the sigpending API:
#include<signal.h>
int sigpending(sigset_t* sigmask);
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 5
Unix Programming (18CS56) V-ISE, MODULE-5
In addition to the above, UNIX also supports following APIs for signal mask manipulation:
#include<signal.h>
int sighold(int signal_num);
int sigrelse(int signal_num);
int sigignore(int signal_num);
int sigpause(int signal_num);
11.4 SIGACTION
Replacement for signal API in the latest UNIX and POSIX systems.
sigaction API - called by a process to set up a signal handling method for each signal it
wants to deal with.
Passes back the previous signal handling method for a given signal.
The sigaction API blocks the signal it is catching allowing a process to specify additional
signals to be blocked when the API is handling a signal.
The sigaction API prototype is:
#include<signal.h>
int sigaction(int signal_num, struct sigaction* action, struct sigaction*
old_action);
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 6
Unix Programming (18CS56) V-ISE, MODULE-5
signal_num will not be added to the process signal mask when the signal handler
function is executed.
SA_RESTART – If a signal is caught while a process is executing a system call, kernel
will restart the system call after the signal handler returns.
If this flag is not set in the sa_flag field, the system call will be aborted with a return
of -1 after the signal handler returns and errno will be set to EINTR.
The following program illustrates the uses of sigaction:
#include<iostream.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void callme(int sig_num)
{
cout<<”catch signal:”<<sig_num<<endl;
}
int main(int argc, char* argv[])
{
sigset_t sigmask;
struct sigaction action,old_action;
sigemptyset(&sigmask);
if(sigaddset(&sigmask,SIGTERM)==-1 || sigprocmask(SIG_SETMASK,&sigmask,0)==-1)
perror(“set signal mask”);
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask,SIGSEGV);
action.sa_handler=callme;
action.sa_flags=0;
if(sigaction(SIGINT,&action,&old_action)==-1)
perror(“sigaction”);
pause();
cout<<argv[0]<<”exists\n”;
return 0;
}
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 7
Unix Programming (18CS56) V-ISE, MODULE-5
o The signal handler function will be called in the parent process whenever a
child process terminates.
o If the SIGCHLD arrives while the parent process is executing the waitpid
system call, the waitpid API may be restarted to collect the child exit status and
clear its process table slots.
o Depending on parent setup, the API may be aborted and child process table slot
not freed.
Interaction between SIGCHLD and wait API is the same as that between SIGCHLD and
waitpid API.
Earlier versions of UNIX used the SIGCLD signal instead of SIGCHLD.
SIGCLD signal is now obsolete, but most of the latest UNIX systems have defined SIGCLD
to be the same as SIGCHLD for backward compatibility.
The sigsetjmp and siglongjmp are created to support signal mask processing. Specifically, it is
implementation- dependent on whether a process signal mask is saved and restored when it
invokes the setjmp and longjmp APIs respectively.
The only difference between these functions and the setjmp and longjmp functions is that
sigsetjmp has an additional argument.
If savemask is nonzero, then sigsetjmp also saves the current signal mask of the process in env.
When siglongjmp is called, if the env argument was saved by a call to sigsetjmp with a nonzero
savemask, then siglongjmp restores the saved signal mask.
The siglongjmp API is usually called from user-defined signal handling functions.
This is because a process signal mask is modified when a signal handler is called, and
siglongjmp should be called to ensure the process signal mask is restored properly when
“jumping out” from a signal handling function.
The following program illustrates the uses of sigsetjmp and siglongjmp APIs.
#include<iostream.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<setjmp.h>
sigjmp_buf env;
void callme(int sig_num)
{
cout<< “catch signal:” <<sig_num <<endl;
siglongjmp(env,2);
}
int main()
{
sigset_t sigmask;
struct sigaction action,old_action;
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 8
Unix Programming (18CS56) V-ISE, MODULE-5
sigemptyset(&sigmask);
if(sigaddset(&sigmask,SIGTERM)==-1) ||
sigprocmask(SIG_SETMASK,&sigmask,0)==-1)
perror(“set signal mask”);
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask,SIGSEGV);
action.sa_handler=(void(*)())callme;
action.sa_flags=0;
if(sigaction(SIGINT,&action,&old_action)==-1)
perror(“sigaction”);
if(sigsetjmp(env,1)!=0)
{
cerr<<”return from signal interruption”;
return 0;
}
else
cerr<<”return from first time sigsetjmp is called”;
pause();
}
11.7 KILL
A process can send a signal to a related process via the kill API. Sender and recipient
processes must be related such that either the sender process real/effective UID matches
that of recipient process, or sender process has superuser privileges.
Example: parent and child process sending signals to each other.
This is a simple means of inter-process communication or control. The function prototype of the
API is:
#include<signal.h>
int kill(pid_t pid, int signal_num);
Returns: 0 on success, -1 on failure.
The signal_num argument is the integer value of a signal to be sent to one or more processes
designated by pid. The possible values of pid and its use by the kill API are:
pid > 0 The signal is sent to the process whose process ID is pid.
pid == 0 The signal is sent to all processes whose process group ID equals the process group ID of
the sender and for which the sender has permission to send the signal.
pid < 0 The signal is sent to all processes whose process group ID equals the absolute value of pid
and for which the sender has permission to send the signal.
pid == 1 The signal is sent to all processes on the system for which the sender has permission to send
the signal.
The following program illustrates the implementation of the UNIX kill command using the kill
API:
#include<iostream.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<signal.h>
int main(int argc,char** argv)
{
int pid, sig = SIGTERM;
if(argc==3)
{
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 9
Unix Programming (18CS56) V-ISE, MODULE-5
if(sscanf(argv[1],”%d”,&sig)!=1)
{
cerr<<”invalid number:” << argv[1] << endl; return -1;
}
argv++,argc--;
}
while(--argc>0)
if(sscanf(*++argv, “%d”, &pid)==1)
{
if(kill(pid,sig)==-1)
perror(“kill”);
}
else
cerr<<”invalid pid:” << argv[0] <<endl;
return 0;
}
11.8 ALARM
The alarm API can be called by a process to request the kernel to send the SIGALRM signal
after a certain number of real clock seconds. The function prototype of the API is:
#include<signal.h>
Unsigned int alarm(unsigned int time_interval);
Returns: 0 or number of CPU seconds until previously set alarm. time_interval – number of
CPU seconds elapsed time, after which the kernel will send the SIGALRM signal to the calling
process. If time_interval = 0, it turns off the alarm clock.
Effect of previous alarm is cancelled and process timer is reset with new alarm call.
Process alarm clock is not passed on to its forked child, but an exceed process retains the
same alarm clock value as was prior to the exec API call.
alarm API is used to implement sleep API – suspends a calling process for the
specified number of CPU seconds.
Process will be awakened by either the elapsed time exceeding the timer value or
when the process is interrupted by a signal.
BSD UNIX – ualarm function.
Same as that of alarm API, but argument and return values are in microseconds.
Useful for time-critical applications where the resolution of time must be in microsecond
levels.
Can be used to implement BSD-specific usleep function – similar to sleep, but its
argument is in microseconds.
The alarm API can be used to implement the sleep API:
#include<signal.h>
#include<stdio.h>
#include<unistd.h>
void wakeup( )
{ ; }
unsigned int sleep (unsigned int timer )
{
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 10
Unix Programming (18CS56) V-ISE, MODULE-5
Struct sigaction action;
action.sa_handler=wakeup;
action.sa_flags=0;
sigemptyset(&action.sa_mask);
if(sigaction(SIGALARM,&action,0)==-1)
{
perror(“sigaction”);
return -1;
}
(void) alarm (timer);
(void) pause( );
return 0;
}
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 11
Unix Programming (18CS56) V-ISE, MODULE-5
}
In addition to alarm API, UNIX also invented the setitimer API, which can be used to define up to
three different types of timers in a process:
Real time clock timer
Timer based on the user time spent by a process
Timer based on the total user and system times spent by a process
The getitimer API is also defined for users to query the timer values that are set by the setitimer
API. The setitimer and getitimer function prototypes are:
#include<sys/time.h>
int setitimer(int which, const struct itimerval * val, struct itimerval
* old); int getitimer(int which, struct itimerval * old);
The which arguments to the above APIs specify which timer to process. Its possible values and the
corresponding timer types are:
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 12
Unix Programming (18CS56) V-ISE, MODULE-5
if(setitimer(ITIMER_REAL, &val , 0)==-1)
perror(“alarm”);
else while(1)
{
/*do normal operation*/
}
return 0;
}
The setitimer and getitimer APIs return a zero value if they succeed or a -1 value if they fail.
timer_create API – used to dynamically create a timer and return its handler.
clock argument – specifies which system clock the new timer should be based on.
clock value may be CLOCK_REALTIME for creating a real-time clock timer.
spec argument – defines what action to take when the timer expires.
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 13
Unix Programming (18CS56) V-ISE, MODULE-5
12.1 INTRODUCTION
Daemons are processes that live for a long time. They are often started when the system is
bootstrapped and terminate only when the system is shut down. No controlling terminal – daemons
run in the background. Perform day-to-day activities in the UNIX system. Process names of a
daemon usually end with "d". Examples: syslogd – a daemon that implements system logging
facility, sshd – a daemon that serves incoming SSH connections.
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 14
Unix Programming (18CS56) V-ISE, MODULE-5
mark, and the terminal foreground process group is -1.
All the user-level daemons are process group leaders and session leaders and are the only
processes in their process group and session.
The parent of most of these daemons is the init process.
The characteristics of daemons are:
Daemons run in background.
Daemons have super-user privilege.
Daemons don’t have controlling terminal.
Daemons are session and group leaders.
12.3 CODING RULES
Call umask to set the file mode creation mask to 0. The file mode creation mask
that's inherited could be set to deny certain permissions. If the daemon process is
going to create files, it may want to set specific permissions.
Call fork and have the parent exit. This does several things. First, if the daemon
was started as a simple shell command, having the parent terminate makes the shell
think that the command is done. Second, the child inherits the process group ID of
the parent but gets a new process ID, so we're guaranteed that the child is not a process
group leader.
Call setsid to create a new session. The process (a) becomes a session leader of a
new session, (b) becomes the process group leader of a new process group, and (c)
has no controlling terminal.
Change the current working directory to the root directory. The current working
directory inherited from the parent could be on a mounted file system. Since daemons
normally exist until the system is rebooted, if the daemon stays on a mounted file
system, that file system cannot be unmounted.
Unneeded file descriptors should be closed. This prevents the daemon from holding
open any descriptors that it may have inherited from its parent.
Some daemons open file descriptors 0, 1, and 2 to /dev/null so that any library
routines that try to read from standard input or write to standard output or
standard error will have no effect. Since the daemon is not associated with a
terminal device, there is nowhere for output to be displayed; nor is there anywhere to
receive input from an interactive user. Even if the daemon was started from an
interactive session, the daemon runs in the background, and the login session can
terminate without affecting the daemon. If other users log in on the same terminal
device, we wouldn't want output from the daemon showing up on the terminal, and
the users wouldn't expect their input to be read by the daemon.
Example Program:
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
int daemon_initialise( )
{
pid_t pid;
if (( pid = for() ) < 0)
return –1;
else
if ( pid != 0)
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 15
Unix Programming (18CS56) V-ISE, MODULE-5
exit(0); /* parent exits */
/* child continues */
setsid( );
chdir(“/”);
umask(0);
return 0;
}
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 16
Unix Programming (18CS56) V-ISE, MODULE-5
void syslog(int priority, const char *format, ...);
void closelog(void);
int setlogmask(int maskpri);
Returns: previous log priority mask value
Calling openlog is optional.
If it is not called, when syslog is called for the first time, openlog is called automatically.
Calling closelog is also optional.
It just closes the descriptor that was being used to communicate with the syslogd
daemon.
ident – added to each log message.
This is normally the name of the program (cron, inetd, etc.)
option – bit mask specifying various options.
option Description
LOG_CONS If the log message cannot be sent to syslogd via the UNIX domain
datagram, the message is written to the console instead.
LOG_NDELAY Open the UNIX domain datagram socket to the syslogd daemon
immediately;do not wait until the first message is logged.
LOG_NOWAIT Do not wait for child processes that might have been created in the process
of logging the message.
LOG_ODELAY Delay the open of the connection to the syslogd daemon until the first
message is logged.
LOG_PERROR Write the log message to standard error in addition to sending it to syslogd.
LOG_PID Log the process ID with each message. This is intended for daemons that
fork a child process to handle different requests.
facility – lets the configuration file specify that messages from different facilities are to be
handled differently.
If we do not call openlog, or if we call it with a facility of 0, we can still specify the facility
as part of the priority argument to syslog.
Single UNIX Specification – defines only a subset of the facility codes typically available
on a given platform.
facility Description
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 17
Unix Programming (18CS56) V-ISE, MODULE-5
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 18
Unix Programming (18CS56) V-ISE, MODULE-5
Intended for a shell script running non-interactively that needs to generate log messages.
vsyslog – a variant of syslog that handles variable argument lists.
Dr. PS, Dr. BA, Mrs. CSR Dept of ISE, RNSIT, 2022 Page 19