linux 编程中忽略SIGPIPE信号

linux 编程中忽略SIGPIPE信号

SIGPIPE

简单来说,就是客户端程序向服务器端程序发送了消息,然后关闭客户端,服务器端返回消息的时候就会收到内核给的SIGPIPE信号。
TCP的全双工信道其实是两条单工信道,client端调用close的时候,虽然本意是关闭两条信道,但是其实只能关闭它发送的那一条单工信道,还是可以接受数据,server端还是可以发送数据,并不知道client端已经完全关闭了。
以下为引用:
”’对一个已经收到FIN包的socket调用read方法, 如果接收缓冲已空, 则返回0, 这就是常说的表示连接关闭. 但第一次对其调用write方法时, 如果发送缓冲没问题, 会返回正确写入(发送). 但发送的报文会导致对端发送RST报文, 因为对端的socket已经调用了close, 完全关闭, 既不发送, 也不接收数据. 所以, 第二次调用write方法(假设在收到RST之后), 会生成SIGPIPE信号, 导致进程退出.”’

简单忽略SIGPIPE

    struct sigaction action;
    action.sa_handler = SIG_IGN;
    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;
    sigaction(SIGPIPE, &action, NULL);
    sendBytes = send(Fd, Buff, readBytes, MSG_NOSIGNAL);

以下为一劳永逸,设置多个忽略的信号

/*****************************************************************************
 * NAME: UpdateSignalHandling
 *
 * DESCRIPTION:
 *      this function sets up the signal handling and masking for the daemon
 *      process. the following is done here:
 *
 *      o - change some default signal disposition with sigaction().
 *      o - block all signals. we will use sigwait() in a dedicated thread
 *          to process the signals we are interested in.
 *
 *      the failures in this function are non-fatal. so we keep going after
 *      taking a note of the error code.
 *
 * INPUTS:
 *      NONE.
 *
 * RETURN:
 *      int.
 */
static
int
UpdateSignalHandling(
    void
    )
{

    sigset_t sigset;
    struct sigaction sa = { .sa_handler = SIG_IGN };
    int status = 0;

    if (sigfillset(&sa.sa_mask) == 0)
    {
        static int IGNORE_SIG[] = { SIGINT, SIGTERM, SIGCHLD, SIGHUP, SIGPIPE, SIGIO };
        unsigned int i = 0;

        for (i = 0; i < sizeof(IGNORE_SIG)/sizeof(IGNORE_SIG[0]); i++)
        {
            if (sigaction(IGNORE_SIG[i], &sa, NULL) != 0)
            {
                status = -errno;
            }
        }
    }
    else
    {
        status = -errno;
    }

    if (sigfillset(&sigset) == 0)
    {
        static int UNMASK_SIG[] = { SIGBUS, SIGFPE, SIGILL, SIGSEGV };
        unsigned int i = 0;
        int r = 0;

        for (i = 0; i < sizeof(UNMASK_SIG)/sizeof(UNMASK_SIG[0]); i++)
        {
            (void)sigdelset(&sigset, UNMASK_SIG[i]);
        }

        /*
         * per man page, the use of sigprocmask() is unspecified in MT process.
         * use pthread_sigmask() instead.
         */
        r = pthread_sigmask(SIG_BLOCK, &sigset, NULL);

        if (r != 0)
        {
            status = -r;
        }
    }
    else
    {
        status = -errno;
    }

    return status;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值