2
void handler ( int sig, siginfo_t * info, void * se)
{

}

int setup_sig(){
    struct sigaction sa;
    sa.sa_sigaction = handler;
    sa.sa_flags = SA_SIGINFO;
    sigfillset(&sa.sa_mask);
    if(-1 == sigaction(SIGCHLD, &sa , NULL)){return 0;} return 1;
}

void main()
{
    printf("before\n");
    setup_sig();
    sleep(3);
    printf("after\n");
}

This code needs to register to signal SIGCHLD and then sleep 3 seconds, and then go out.

This code skip on sleep instruction, why?

paramikoooo
  • 87
  • 15
  • 1
    Properly formatted and indented code is easier to read and understand than what you have here. – Jonathon Reinhart Feb 13 '20 at 13:42
  • So it doesn't wait 3 seconds? – user253751 Feb 13 '20 at 13:43
  • 2
    The compiler should reject `setup_sig()`; you cannot return a value from a function that has `void` as the return type (see also [Reading parameter from file and creating filenames](https://stackoverflow.com/a/60196698/15168), which quotes the relevant part of the standard). Separately [What should `main()` return in C or C++?](https://stackoverflow.com/a/18721336/15168) — the answer is not `void` except, perhaps, on Windows. – Jonathan Leffler Feb 13 '20 at 15:57
  • May we have [minimum, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) with complete headers, complier flags, no compilation warnings, and also a detailed description of the behavior you expect versus the behavior you observe? Like @user253751, I don't quite know what you mean by sleep "doesn't work" or that the code "skip on sleep instruction." – pilcrow Feb 13 '20 at 19:22

1 Answers1

1

The Linux documentation for sleep lists the following attributes at the bottom:

┌──────────┬───────────────┬─────────────────────────────┐
│Interface │ Attribute     │ Value                       │
├──────────┼───────────────┼─────────────────────────────┤
│sleep()   │ Thread safety │ MT-Unsafe sig:SIGCHLD/linux │
└──────────┴───────────────┴─────────────────────────────┘

That sig:SIGCHLD/linux is important in this context. As per here, it's explained as follows (my emphasis):

sig: Functions marked with sig as a MT-Safety issue may temporarily install a signal handler for internal purposes, which may interfere with other uses of the signal, identified after a colon.

This safety problem can be worked around by ensuring that no other uses of the signal will take place for the duration of the call. Holding a non-recursive mutex while calling all functions that use the same temporary signal; blocking that signal before the call and resetting its handler afterwards is recommended.

Blocking a signal can be done with the sigprocmask call, such as with:

// Need signal.h for this stuff.

sigset_t mask;

if ((sigemptyset(&mask) == -1) || (sigaddset(&mask, SIGCHLD) == -1)) {
    // handle failure here.
}

if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
    // handle failure here.
}

sleep(3);

// Probably need to re-establish CHLD signal handler as well as unmasking.

if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) {
    // handle failure here.
}
Community
  • 1
  • 1
paxdiablo
  • 772,407
  • 210
  • 1,477
  • 1,841