Lorand
Lorand

Reputation: 29

checking for errors in a program that implements a System V signal API using the standard POSIX API

How can I modify the error checking program? I check or pass the returned value of sigprocmask (), but I don't check the return value of most other sig * () functions. However, it all returns an error code that I should check. How can I do that?

I wrote a program that implements a POSIX signal API. It implements the functions sigset(), sighold(), sigrelse(), sigignore() and sigpause().

#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

#define SIG_HOLD ((__sighandler_t)2)
typedef void (*sighandler_t)(int);

sighandler_t
sigset(int sig, sighandler_t disp);
int sighold(int sig);
int sigrelse(int sig);
int sigignore(int sig);
int sigpause(int sig);

sighandler_t
sigset(int sig, sighandler_t disp)
{
    struct sigaction old_set;
    if (disp == SIG_HOLD)
    {
        sighold(sig);

        sigaction(sig, NULL, &old_set);
        return old_set.sa_handler;
    }

    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    act.sa_handler = disp;
    sigaction(sig, &act, &old_set);
    return old_set.sa_handler;
}

int sighold(int sig)
{
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, sig);
    return sigprocmask(SIG_BLOCK, &set, NULL);
}

int sigrelse(int sig)
{
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, sig);
    return sigprocmask(SIG_UNBLOCK, &set, NULL);
}

int sigignore(int sig)
{
    if (signal(sig, SIG_IGN) == SIG_ERR)
        return -1;
    return 0;
}

int sigpause(int sig)
{
    sigset_t old_set;
    if (sigprocmask(SIG_BLOCK, NULL, &old_set) == -1)
        return -1;
    sigdelset(&old_set, sig);
    return sigsuspend(&old_set);
}

void handler(int sig)
{
    printf("handler\n"); // it's unsafe
}

int main()
{
    sigset(SIGTERM, handler);
    sighold(SIGABRT);
    sigrelse(SIGABRT);
    sigignore(SIGABRT);
    sighold(SIGTERM);
    raise(SIGTERM);
    sigpause(SIGTERM);

    return 0;
}

Upvotes: 0

Views: 47

Answers (1)

Madagascar
Madagascar

Reputation: 7345

However, it all returns an error code that I should check. How can I do that?

Similar to how you check the return value of sigprocmask(), simply check the return values of the rest. Most, if not all, of these functions return -1 on failure. A sample example:

if (sigset(SIGTERM, handler) == -1) {
    perror ("sigset()");
    /* Handle error here. */
}

Upvotes: 0

Related Questions