SIGCHLD causing EOF in parent process
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 returnEOF(as written in the manual page). - (Ad hoc) Solution: check
errnoforEINTR.
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
|
show 2 more comments
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 returnEOF(as written in the manual page). - (Ad hoc) Solution: check
errnoforEINTR.
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
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 usesigactionwith theSA_RESTARTflag 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_SOURCEor_GNU_SOURCE(leading to__USE_MISCinternally) causessignalto 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
|
show 2 more comments
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 returnEOF(as written in the manual page). - (Ad hoc) Solution: check
errnoforEINTR.
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
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 returnEOF(as written in the manual page). - (Ad hoc) Solution: check
errnoforEINTR.
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
c linux process signals fork
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 usesigactionwith theSA_RESTARTflag 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_SOURCEor_GNU_SOURCE(leading to__USE_MISCinternally) causessignalto 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
|
show 2 more comments
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 usesigactionwith theSA_RESTARTflag 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_SOURCEor_GNU_SOURCE(leading to__USE_MISCinternally) causessignalto 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
|
show 2 more comments
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
sigactionwith theSA_RESTARTflag 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_SOURCEor_GNU_SOURCE(leading to__USE_MISCinternally) causessignalto 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