SIGCHLD causing EOF in parent process












2














A minimalistic example of a program that




  • reads char by char by getchar, until EOF

  • starts a child process when an "a" is encountered.


Curiously, installing a signal handler causes getchar to return an EOF whenever a child exits. A rather unwanted side-effect.



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

void handler() {
//
}

void action() {
if (fork() == 0) {
printf("(action)n");
sleep(1);
exit(0);
}
}

int main(int argc, char** argv) {
char c;
signal(SIGCHLD, handler); // signal
while (EOF != (c = getchar())) {
if (c == 'a') action();
}
printf("End Of Datan");
}


The problem disappears when the signal ligne is commented out.
Can someone please explain why this happens?



Seems the same problem as Handling SIGCHLD will return EOF to the father, why?
which has no clear answer about why, and how to avoid this.





EDIT 1: Was not clear to me doesn't mean that much (friday evening...)




  • The cause is, the system call under getchar() was interrupted, causing it to return EOF (as written in the manual page).

  • (Ad hoc) Solution: check errno for EINTR.


On this example



 while (EOF != (c = getchar()) || errno == EINTR) {




EDIT 2: checking errno works with getchar(), but doesn't make you out of the woods with getline().



The real solution is to forget about the obsolete signal(), and use sigaction() with the SA_RESTART flag.










share|improve this question
























  • Got it, after all. Interrupted system call. Check errno = EINTR.
    – Michel Billaud
    Nov 23 '18 at 17:57










  • @usr Sorry for silly qustion, it's friday.
    – Michel Billaud
    Nov 23 '18 at 18:02








  • 2




    You could use sigaction with the SA_RESTART flag to avoid the problem.
    – Ian Abbott
    Nov 23 '18 at 18:02










  • What libc and version is this? I thought glibc signal() abandoned this awful sysv behavior decades ago.
    – R..
    Nov 24 '18 at 1:10






  • 1




    @MichelBillaud: Uhg, looks like using one of the standard feature test macros without also _BSD_SOURCE or _GNU_SOURCE (leading to __USE_MISC internally) causes signal to get redirected to the awful __sysv_signal... This should probably be treated as a bug in glibc and fixed. The standards do not require or recommend the broken sysv behavior, just allow it.
    – R..
    Nov 24 '18 at 18:31


















2














A minimalistic example of a program that




  • reads char by char by getchar, until EOF

  • starts a child process when an "a" is encountered.


Curiously, installing a signal handler causes getchar to return an EOF whenever a child exits. A rather unwanted side-effect.



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

void handler() {
//
}

void action() {
if (fork() == 0) {
printf("(action)n");
sleep(1);
exit(0);
}
}

int main(int argc, char** argv) {
char c;
signal(SIGCHLD, handler); // signal
while (EOF != (c = getchar())) {
if (c == 'a') action();
}
printf("End Of Datan");
}


The problem disappears when the signal ligne is commented out.
Can someone please explain why this happens?



Seems the same problem as Handling SIGCHLD will return EOF to the father, why?
which has no clear answer about why, and how to avoid this.





EDIT 1: Was not clear to me doesn't mean that much (friday evening...)




  • The cause is, the system call under getchar() was interrupted, causing it to return EOF (as written in the manual page).

  • (Ad hoc) Solution: check errno for EINTR.


On this example



 while (EOF != (c = getchar()) || errno == EINTR) {




EDIT 2: checking errno works with getchar(), but doesn't make you out of the woods with getline().



The real solution is to forget about the obsolete signal(), and use sigaction() with the SA_RESTART flag.










share|improve this question
























  • Got it, after all. Interrupted system call. Check errno = EINTR.
    – Michel Billaud
    Nov 23 '18 at 17:57










  • @usr Sorry for silly qustion, it's friday.
    – Michel Billaud
    Nov 23 '18 at 18:02








  • 2




    You could use sigaction with the SA_RESTART flag to avoid the problem.
    – Ian Abbott
    Nov 23 '18 at 18:02










  • What libc and version is this? I thought glibc signal() abandoned this awful sysv behavior decades ago.
    – R..
    Nov 24 '18 at 1:10






  • 1




    @MichelBillaud: Uhg, looks like using one of the standard feature test macros without also _BSD_SOURCE or _GNU_SOURCE (leading to __USE_MISC internally) causes signal to get redirected to the awful __sysv_signal... This should probably be treated as a bug in glibc and fixed. The standards do not require or recommend the broken sysv behavior, just allow it.
    – R..
    Nov 24 '18 at 18:31
















2












2








2


1





A minimalistic example of a program that




  • reads char by char by getchar, until EOF

  • starts a child process when an "a" is encountered.


Curiously, installing a signal handler causes getchar to return an EOF whenever a child exits. A rather unwanted side-effect.



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

void handler() {
//
}

void action() {
if (fork() == 0) {
printf("(action)n");
sleep(1);
exit(0);
}
}

int main(int argc, char** argv) {
char c;
signal(SIGCHLD, handler); // signal
while (EOF != (c = getchar())) {
if (c == 'a') action();
}
printf("End Of Datan");
}


The problem disappears when the signal ligne is commented out.
Can someone please explain why this happens?



Seems the same problem as Handling SIGCHLD will return EOF to the father, why?
which has no clear answer about why, and how to avoid this.





EDIT 1: Was not clear to me doesn't mean that much (friday evening...)




  • The cause is, the system call under getchar() was interrupted, causing it to return EOF (as written in the manual page).

  • (Ad hoc) Solution: check errno for EINTR.


On this example



 while (EOF != (c = getchar()) || errno == EINTR) {




EDIT 2: checking errno works with getchar(), but doesn't make you out of the woods with getline().



The real solution is to forget about the obsolete signal(), and use sigaction() with the SA_RESTART flag.










share|improve this question















A minimalistic example of a program that




  • reads char by char by getchar, until EOF

  • starts a child process when an "a" is encountered.


Curiously, installing a signal handler causes getchar to return an EOF whenever a child exits. A rather unwanted side-effect.



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

void handler() {
//
}

void action() {
if (fork() == 0) {
printf("(action)n");
sleep(1);
exit(0);
}
}

int main(int argc, char** argv) {
char c;
signal(SIGCHLD, handler); // signal
while (EOF != (c = getchar())) {
if (c == 'a') action();
}
printf("End Of Datan");
}


The problem disappears when the signal ligne is commented out.
Can someone please explain why this happens?



Seems the same problem as Handling SIGCHLD will return EOF to the father, why?
which has no clear answer about why, and how to avoid this.





EDIT 1: Was not clear to me doesn't mean that much (friday evening...)




  • The cause is, the system call under getchar() was interrupted, causing it to return EOF (as written in the manual page).

  • (Ad hoc) Solution: check errno for EINTR.


On this example



 while (EOF != (c = getchar()) || errno == EINTR) {




EDIT 2: checking errno works with getchar(), but doesn't make you out of the woods with getline().



The real solution is to forget about the obsolete signal(), and use sigaction() with the SA_RESTART flag.







c linux process signals fork






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 17:34

























asked Nov 23 '18 at 17:43









Michel Billaud

1,394411




1,394411












  • Got it, after all. Interrupted system call. Check errno = EINTR.
    – Michel Billaud
    Nov 23 '18 at 17:57










  • @usr Sorry for silly qustion, it's friday.
    – Michel Billaud
    Nov 23 '18 at 18:02








  • 2




    You could use sigaction with the SA_RESTART flag to avoid the problem.
    – Ian Abbott
    Nov 23 '18 at 18:02










  • What libc and version is this? I thought glibc signal() abandoned this awful sysv behavior decades ago.
    – R..
    Nov 24 '18 at 1:10






  • 1




    @MichelBillaud: Uhg, looks like using one of the standard feature test macros without also _BSD_SOURCE or _GNU_SOURCE (leading to __USE_MISC internally) causes signal to get redirected to the awful __sysv_signal... This should probably be treated as a bug in glibc and fixed. The standards do not require or recommend the broken sysv behavior, just allow it.
    – R..
    Nov 24 '18 at 18:31




















  • Got it, after all. Interrupted system call. Check errno = EINTR.
    – Michel Billaud
    Nov 23 '18 at 17:57










  • @usr Sorry for silly qustion, it's friday.
    – Michel Billaud
    Nov 23 '18 at 18:02








  • 2




    You could use sigaction with the SA_RESTART flag to avoid the problem.
    – Ian Abbott
    Nov 23 '18 at 18:02










  • What libc and version is this? I thought glibc signal() abandoned this awful sysv behavior decades ago.
    – R..
    Nov 24 '18 at 1:10






  • 1




    @MichelBillaud: Uhg, looks like using one of the standard feature test macros without also _BSD_SOURCE or _GNU_SOURCE (leading to __USE_MISC internally) causes signal to get redirected to the awful __sysv_signal... This should probably be treated as a bug in glibc and fixed. The standards do not require or recommend the broken sysv behavior, just allow it.
    – R..
    Nov 24 '18 at 18:31


















Got it, after all. Interrupted system call. Check errno = EINTR.
– Michel Billaud
Nov 23 '18 at 17:57




Got it, after all. Interrupted system call. Check errno = EINTR.
– Michel Billaud
Nov 23 '18 at 17:57












@usr Sorry for silly qustion, it's friday.
– Michel Billaud
Nov 23 '18 at 18:02






@usr Sorry for silly qustion, it's friday.
– Michel Billaud
Nov 23 '18 at 18:02






2




2




You could use sigaction with the SA_RESTART flag to avoid the problem.
– Ian Abbott
Nov 23 '18 at 18:02




You could use sigaction with the SA_RESTART flag to avoid the problem.
– Ian Abbott
Nov 23 '18 at 18:02












What libc and version is this? I thought glibc signal() abandoned this awful sysv behavior decades ago.
– R..
Nov 24 '18 at 1:10




What libc and version is this? I thought glibc signal() abandoned this awful sysv behavior decades ago.
– R..
Nov 24 '18 at 1:10




1




1




@MichelBillaud: Uhg, looks like using one of the standard feature test macros without also _BSD_SOURCE or _GNU_SOURCE (leading to __USE_MISC internally) causes signal to get redirected to the awful __sysv_signal... This should probably be treated as a bug in glibc and fixed. The standards do not require or recommend the broken sysv behavior, just allow it.
– R..
Nov 24 '18 at 18:31






@MichelBillaud: Uhg, looks like using one of the standard feature test macros without also _BSD_SOURCE or _GNU_SOURCE (leading to __USE_MISC internally) causes signal to get redirected to the awful __sysv_signal... This should probably be treated as a bug in glibc and fixed. The standards do not require or recommend the broken sysv behavior, just allow it.
– R..
Nov 24 '18 at 18:31














0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451014%2fsigchld-causing-eof-in-parent-process%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451014%2fsigchld-causing-eof-in-parent-process%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Lallio

Futebolista

Jornalista