Advanced Programming in UNIX Environment Episode 48

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/myfather103/article/details/79773850

sigqueue Function

With the real-time extensions to POSIX.1, some systems began adding support for queueing signals. With SUSv4, the queued signal functionality has moved from the real-time extensions to the base specification.

To use queued signals we have to do the following:

1.Specify the SA_SIGINFO flag when we install a signal handler using the sigaction function. If we don’t specify this flag, the signal will be posted, but it is left up to the implementation whether the signal is queued.
2.Provide a signal handler in the sa_sigaction member of the sigaction structure instead of using the usual sa_handler field. Implementations might allow us to use the sa_handler field, but we won’t be able to obtain the extra information sent with the sigqueue function.
3.Use the sigqueue function to send signals.

#include <signal.h>

int sigqueue(pid_t pid,int signo, const union sigval value);

The sigqueue function is similar to the kill function, except that we can only direct signals to a single process with sigqueue, and we can use the value argument to transmit either an integer or a pointer value to the signal handler.

Mac OS X 10.6.8 doesn’t support sigqueue or real-time signals. On Solaris 10, sigqueue is in the real-time library, librt.

Job-Control Signals

Of the signals shown in Figure 10.1, POSIX.1 considers six to be job-control signals:

SIGCHLD Child process has stopped or terminated.
SIGCONT Continue process, if stopped.
SIGSTOP Stop signal (can’t be caught or ignored).
SIGTSTP Interactive stop signal.
SIGTTIN Read from controlling terminal by background process group member.
SIGTTOU Write to controlling terminal by a background process group member.

Except for SIGCHLD, most application programs don’t handle these signals: interactive shells usually do all the work required to handle them. When we type the suspend character (usually Control-Z), SIGTSTP is sent to all processes in the foreground process group. When we tell the shell to resume a job in the foreground or background, the shell sends all the processes in the job the SIGCONT signal. Similarly, if SIGTTIN or SIGTTOU is delivered to a process, the process is stopped by default, and the job-control shell recognizes this and notifies us.

#include "apue.h"

#define BUFFSIZE 1024

static void sig_tstp(int signo)
{
    sigset_t mask;

    sigemptyset(&mask);
    sigaddset(&mask,SIGTSTP);
    sigprocmask(SIG_UNBLOCK,&mask,NULL);

    signal(SIGTSTP,SIG_DEL);
    kill(getpid(),SIGTSTP);

    signal(SIGTSTP,sig_tstp);

}

int main(void)
{
    int n;
    char buf[BUFFSIZE];

    if(signal(SIGTSTP, SIG_IGN)==SIG_DFL)
        signal(SIGTSTP, sig_tstp);
    
    while((n=read(STDIN_FILENO,buf,BUFFSIZE))>0)
        if(write(STDOUT_FILENO,buf,n)!=n)
            err_sys("write error");
    
    if(n<0)
        err_sys("read error");
    
    return 0;
}

How to handle SIGTSTP

Signal Names and Numbers

Some systems provide the array

extern char *sys_siglist[];

The array index is the signal number, giving a pointer to the character string name of the signal.

FreeBSD 8.0, Linux 3.2.0, and Mac OS X 10.6.8 all provide this array of signal names. Solaris 10 does, too, but it uses the name _sys_siglist instead.

To print the character string corresponding to a signal number in a portable manner, we can use the psignal function.

#include <signal.h>

void psignal(int signo, const char *msg);

If you have a siginfo structure from an alternative sigaction signal handler, you can print the signal information with the psiginfo function.

#include <signal.h>

void psiginfo(const siginfo_t *info, const char *msg);

If you only need the string description of the signal and don’t necessarily want to write it to standard error (you might want to write it to a log file, for example), you can use the strsignal function. This function is similar to strerror.

#include <string.h>

char *strsignal(int signo);

All the platforms discussed in this book provide the psignal and strsignal functions, but differences do occur. On Solaris 10, strsignal will return a null pointer if the signal number is invalid, whereas FreeBSD 8.0, Linux 3.2.0, and Mac OS X 10.6.8 return a string indicating that the signal number is unrecognized.
Only Linux 3.2.0 and Solaris 10 support the psiginfo function

Solaris provides a couple of functions to map a signal number to a signal name, and vice versa.

#include <signal.h>

int sig2str(int signo,char *str);
int str2sig(const char *str, int *signop);

These functions are useful when writing interactive programs that need to accept and print signal names and numbers.

猜你喜欢

转载自blog.csdn.net/myfather103/article/details/79773850
今日推荐