Hi,

I'm currently tinkering with sigtimedwait() to timeout a process I
forked by setting it up to listen for SIGCHLD. 

What strikes me as odd is that I have to define a bogus signal-handler
routine to make it work, otherwise no SIGCHLD is even received by the
parent process.

I attached a simplified example to this mail. All it does is setting up
a signalset for SIGCHLD, fork a process and wait with sigtimedwait() for
the child to exit. Which should happen immediately. However, when
sigaction() with the bogus handler is not called, sigtimedwait() times
out because it receives no SIGCHLD (truss also shows no SIGCHLD raised)

So is there anything wrong with the approach or am I just too stupid?

Any hints or comments would be appreciated

Thanks
Erik

=======================================================================
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

#define USE_SIGACTION

static void
hdl(int sig)
{
        printf(">>> sig handler: %d\n", sig);
}

int
main()
{
        int ret, pid, status;
        pid_t w;
        sigset_t mask;
        sigset_t omask;
        struct timespec to;
        struct sigaction act;

#ifdef USE_SIGACTION
        (void)memset (&act, 0, sizeof(act));
        act.sa_handler = hdl;

        if (sigaction(SIGCHLD, &act, 0)) {
                printf("sigaction err\n");
                return 1;
        }
#endif
        if (sigemptyset (&mask) || 
            sigaddset (&mask, SIGCHLD) || 
            sigprocmask(SIG_BLOCK, &mask, &omask)) {
                printf("sig error\n");
                return 1;
        }
        

        if ((pid = fork()) == 0) {
                /* child exits immediately */
                _exit(0);
        } else if (pid == -1) {
                printf("fork error\n");
                return 1;
        }

        printf("pid: %d\n",(int)pid);
        to.tv_sec = 5;
        to.tv_nsec = 0;

        if ((ret = sigtimedwait(&mask, NULL, &to)) < 0) {
                int err = errno;
                printf("sigtimedwait, ret: %d, err %d\n", ret, err);
                if (err == EAGAIN) {
                        printf("timeout!\n");
                        (void) kill(pid, SIGKILL);
                } else {
                        printf("sigtimedwait unknown error\n");
                        return 1;
                }
        }

        (void) sigprocmask(SIG_SETMASK, &omask, NULL);

        w = waitpid(pid, &status, 0);
        printf("waitpid: %d\n", (int) w);

        ret = WEXITSTATUS(status);

        printf("ret: %d\n", ret);
        return 0;
}


_______________________________________________
opensolaris-code mailing list
opensolaris-code@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to