質問

Here is an example piece of my code

signal(SIGCHLD, SIG_IGN);

ret = system("ls -al");

if(ret < 0)
{
    perror("system failed");
    printf("return value is %d\n", ret);
}

The ls -al command can be executed without any problem.

But the return value of system() is always -1. In this case, I can't get the real return value of the command.

Some reference says that ignore SIGCHLD would affect waitpid() in system(), that's why system always returns -1.

But what puzzles me more is that: isn't SIGCHLD ignored by default? So why ignoring SIGCHLD explicitly would result in such case?

Could someone explain this to me?

Thanks to @cnicutar now I understand the effects of ignoring SIGCHLD.

But now I'm wondering is there any methods to get the return value of child process while SIGCHLD is ignored? Or is this just impossible due to the POSIX specification and OS realizaiton?

役に立ちましたか?

解決

But what puzzles me more is that: isn't SIGCHLD ignored by default?

No, by default it is not ignored. By default there is simply no handler and no action is taken.

So why ignoring SIGCHLD explicitly would result in such case?

Ignoring SIGCHLD has an interesting side-effect: children don't become zombies.

POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)), then children that terminate do not become zombies and a call to wait() or waitpid() will block until all children have terminated, and then fail with errno set to ECHILD.

That is, you don't need to wait any longer for children since they get collected automatically. But system(3) expected a child! So waitpid returns an error and system(3) behaves.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top