* [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
@ 2006-06-19 23:49 Junio C Hamano
2006-06-19 23:57 ` Linus Torvalds
2006-06-20 16:09 ` [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)? Edgar Toernig
0 siblings, 2 replies; 7+ messages in thread
From: Junio C Hamano @ 2006-06-19 23:49 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds
Somebody I met last week in Japan reported that the socks client
he uses to cross the firewall to connect to git:// port from his
company environment seems to do signal(SIGCHLD, SIG_IGN) before
spawning git. When "git clone" is invoked this way, we get a
mysterious failure.
I can reproduce the problem without using funny socks client
like this:
: gitster; trap '' SIGCHLD
: gitster; git clone git://git.kernel.org/pub/scm/git/git.git/ foo.git
error: waitpid failed (No child processes)
fetch-pack from 'git://git.kernel.org/pub/scm/git/git.git/' failed.
: gitster; ls foo.git
ls: foo.git: No such file or directory
We could work this around by having signal(SIGCHLD, SIG_DFL)
upfront in git.c::main(), but I am wondering what the standard
practice for programs that use waitpid() call. Do they protect
themselves from this in order to reliably obtain child exit
status? Or do they simply consider it is a user error to run a
program that use waitpid() with SIGCHLD ignored?
http://www.opengroup.org/onlinepubs/009695399/functions/waitpid.html
explicitly says this is an expected behaviour, so barfing upon
ECHILD sounds like a bug on our part.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
2006-06-19 23:49 [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)? Junio C Hamano
@ 2006-06-19 23:57 ` Linus Torvalds
2006-06-20 0:36 ` Junio C Hamano
2006-06-20 16:09 ` [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)? Edgar Toernig
1 sibling, 1 reply; 7+ messages in thread
From: Linus Torvalds @ 2006-06-19 23:57 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Mon, 19 Jun 2006, Junio C Hamano wrote:
>
> Somebody I met last week in Japan reported that the socks client
> he uses to cross the firewall to connect to git:// port from his
> company environment seems to do signal(SIGCHLD, SIG_IGN) before
> spawning git.
Ok, that sounds pretty broken of it.
> We could work this around by having signal(SIGCHLD, SIG_DFL)
> upfront in git.c::main(), but I am wondering what the standard
> practice for programs that use waitpid() call.
We need the status return, so failing on getting ECHILD is absolutely the
right thing to do, because it implies that we don't know what the status
could have been.
So we need to reset SIGCHLD back to SIG_DFL (or catch it explicitly).
Whether we want to do that in the main() routine or when we actually do
the fork() or whatever is a different issue.
Linus
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
2006-06-19 23:57 ` Linus Torvalds
@ 2006-06-20 0:36 ` Junio C Hamano
2006-06-20 0:44 ` Linus Torvalds
0 siblings, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2006-06-20 0:36 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Linus Torvalds <torvalds@osdl.org> writes:
> Whether we want to do that in the main() routine or when we actually do
> the fork() or whatever is a different issue.
I do not offhand think of a place where we do fork() but not
waitpid(), and it is very tempting to cheat and do that in the
main(), since I do not see a downside to it.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
2006-06-20 0:36 ` Junio C Hamano
@ 2006-06-20 0:44 ` Linus Torvalds
2006-06-20 3:11 ` [PATCH] Restore SIGCHLD to SIG_DFL where we care about waitpid() Junio C Hamano
0 siblings, 1 reply; 7+ messages in thread
From: Linus Torvalds @ 2006-06-20 0:44 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Mon, 19 Jun 2006, Junio C Hamano wrote:
>
> Linus Torvalds <torvalds@osdl.org> writes:
>
> > Whether we want to do that in the main() routine or when we actually do
> > the fork() or whatever is a different issue.
>
> I do not offhand think of a place where we do fork() but not
> waitpid(), and it is very tempting to cheat and do that in the
> main(), since I do not see a downside to it.
Yeah, it probably does make sense. That said, there are several "main()"
functions, so you'd still end up having to verify that we catch all the
paths.. Are all users of fork() built-in by now?
Linus
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] Restore SIGCHLD to SIG_DFL where we care about waitpid().
2006-06-20 0:44 ` Linus Torvalds
@ 2006-06-20 3:11 ` Junio C Hamano
2006-06-20 12:59 ` Petr Baudis
0 siblings, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2006-06-20 3:11 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
It was reported that under one implementation of socks client,
"git clone" fails with "error: waitpid failed (No child
processes)", because "git" is spawned after setting SIGCHLD to
SIG_IGN.
Arguably it may be a broken setting, but we should protect
ourselves so that we can get reliable results from waitpid() for
the children we care about.
This patch resets SIGCHLD to SIG_DFL in three places:
- connect.c::git_connect() - initiators of git native
protocol transfer are covered with this.
- daemon.c::main() - obviously.
- merge-index.c::main() - obviously.
There are other programs that do fork() but do not waitpid():
http-push, imap-send. upload-pack does not either, but in the
case of that program, each of the forked halves runs exec()
another program, so this change would not have much effect
there.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Linus Torvalds <torvalds@osdl.org> writes:
> On Mon, 19 Jun 2006, Junio C Hamano wrote:
>
>> I do not offhand think of a place where we do fork() but not
>> waitpid(), and it is very tempting to cheat and do that in the
>> main(), since I do not see a downside to it.
>
> Yeah, it probably does make sense. That said, there are several "main()"
> functions, so you'd still end up having to verify that we catch all the
> paths.. Are all users of fork() built-in by now?
Not really. But git native protocol initiators all use
git_connect() so they are easy, and there are only few
remaining ones that matter.
connect.c | 5 +++++
daemon.c | 5 +++++
merge-index.c | 5 +++++
3 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/connect.c b/connect.c
index 52d709e..db7342e 100644
--- a/connect.c
+++ b/connect.c
@@ -581,6 +581,11 @@ int git_connect(int fd[2], char *url, co
enum protocol protocol = PROTO_LOCAL;
int free_path = 0;
+ /* Without this we cannot rely on waitpid() to tell
+ * what happened to our children.
+ */
+ signal(SIGCHLD, SIG_DFL);
+
host = strstr(url, "://");
if(host) {
*host = '\0';
diff --git a/daemon.c b/daemon.c
index 2f03f99..1067004 100644
--- a/daemon.c
+++ b/daemon.c
@@ -671,6 +671,11 @@ int main(int argc, char **argv)
int inetd_mode = 0;
int i;
+ /* Without this we cannot rely on waitpid() to tell
+ * what happened to our children.
+ */
+ signal(SIGCHLD, SIG_DFL);
+
for (i = 1; i < argc; i++) {
char *arg = argv[i];
diff --git a/merge-index.c b/merge-index.c
index 024196e..190e12f 100644
--- a/merge-index.c
+++ b/merge-index.c
@@ -99,6 +99,11 @@ int main(int argc, char **argv)
{
int i, force_file = 0;
+ /* Without this we cannot rely on waitpid() to tell
+ * what happened to our children.
+ */
+ signal(SIGCHLD, SIG_DFL);
+
if (argc < 3)
usage("git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)");
--
1.4.0.g275f
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Restore SIGCHLD to SIG_DFL where we care about waitpid().
2006-06-20 3:11 ` [PATCH] Restore SIGCHLD to SIG_DFL where we care about waitpid() Junio C Hamano
@ 2006-06-20 12:59 ` Petr Baudis
0 siblings, 0 replies; 7+ messages in thread
From: Petr Baudis @ 2006-06-20 12:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, git
Dear diary, on Tue, Jun 20, 2006 at 05:11:40AM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> diff --git a/connect.c b/connect.c
> index 52d709e..db7342e 100644
> --- a/connect.c
> +++ b/connect.c
> @@ -581,6 +581,11 @@ int git_connect(int fd[2], char *url, co
> enum protocol protocol = PROTO_LOCAL;
> int free_path = 0;
>
> + /* Without this we cannot rely on waitpid() to tell
> + * what happened to our children.
> + */
> + signal(SIGCHLD, SIG_DFL);
> +
> host = strstr(url, "://");
> if(host) {
> *host = '\0';
It would be nice if at this point of Git development we could already
think about libification when doing things like this (I'd like to do
Git.pm as my little summer project this year). I'd make it part of the
API that the calling application must not defer SIGCHLD, and conversely
put the handler to all the main()s that reach git_connect().
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
A person is just about as big as the things that make them angry.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
2006-06-19 23:49 [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)? Junio C Hamano
2006-06-19 23:57 ` Linus Torvalds
@ 2006-06-20 16:09 ` Edgar Toernig
1 sibling, 0 replies; 7+ messages in thread
From: Edgar Toernig @ 2006-06-20 16:09 UTC (permalink / raw)
To: git
Junio C Hamano wrote:
>
> Somebody I met last week in Japan reported that the socks client
> he uses to cross the firewall to connect to git:// port from his
> company environment seems to do signal(SIGCHLD, SIG_IGN) before
> spawning git.
Similar problems occasionally happen with SIGPIPE. There are apps[1]
that spawn processes with SIGPIPE set to SIG_IGN giving unexpected
results, i.e. child processes that still try to produce output
(getting EPIPE on every printf, but who checks printf errors?) even
if the pipe-reader (e.g. their parent) is long gone.
Ciao, ET.
[1] i.e. KDE had this bug - don't know if it's still there.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-06-20 16:09 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-19 23:49 [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)? Junio C Hamano
2006-06-19 23:57 ` Linus Torvalds
2006-06-20 0:36 ` Junio C Hamano
2006-06-20 0:44 ` Linus Torvalds
2006-06-20 3:11 ` [PATCH] Restore SIGCHLD to SIG_DFL where we care about waitpid() Junio C Hamano
2006-06-20 12:59 ` Petr Baudis
2006-06-20 16:09 ` [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)? Edgar Toernig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).