lestrrat has asked for the wisdom of the Perl Monks concerning the following question:

I'm encountering a situation where any call to system fails with $! being set to "No child processes" on a Solaris box. It seems to work fine on Linux...

The interesting thing about this is I can still fork() and exec(). I just can't call system().

the process that calls system() is forked off from a daemon process, which changes uid at run time to a normal user by switching $< and $> to that of the target user. Also, I call setpgrp( 0, $$ ) at the point in which I fork off the child process

Can anybody give me any pointers?

Replies are listed 'Best First'.
Re: system() call failure
by clintp (Curate) on May 15, 2001 at 02:56 UTC
    Your argument for system() may be processed by a shell. In that case you'll get two processes, not one. (Wheras fork() and exec() would give you only one new process.)

    On further thought, your fork() and exec() tests were run in the same script under the same conditions, right? Where I'm going is that the target user may have had reached its process limits where in testing you (personally) still have processes left.

Re: system() call failure
by lestrrat (Deacon) on May 15, 2001 at 01:45 UTC

    here's the bare bone of my code which forks the child process. I also added some debug messages.

    ===

    sub fork_job { my $job = shift; my $system_fail = 0; system( "ls . " ) == 0 || print "system failed before forking\n" my $pid = fork(); if( !defined( $pid ) ) { # bad, bad, error return 0; } elsif ($pid != 0) { # parent return $pid; } elsif ($pid == 0) { # $child system( "ls . " ) == 0 || print "system failed after forking(1)\n"; $> = $job->{'uid'}; $< = $job->{'uid'}; system( "ls . " ) == 0 || print "system failed after forking(2)\n"; setpgrp(0, $$); system( "ls . " ) == 0 || print "system failed after forking(3)\n"; ## doesn't exec, but continues on my $runner = Runner->new( $job ); $runner->run(); exit 1; } }

    ===

    It seems that any system() call fails after setpgrp( 0, $$ ). Is setpgrp() an issue on solaris?

      My bad, the above was completely inacurate. I started doing some searching around to the cause of the annoying error, and I reduced it down to this:

      #!/usr/local/bin/perl $SIG{ 'CHLD' } = sub { my $pid = wait(); print "Got $pid\n"; }; system("/bin/ls > /dev/null") == 0 || print "system exited with $?, error is \"$!\"\n";

      If you take out the signal handler, it works. Now I'm completely lost...

      By the way, this is the uname -a output:

      SunOS xxxxxx 5.7 Generic sun4u sparc SUNW,Ultra-5_10

      ANY ideas??

        system() does a wait() for the /bin/ls process to complete. When the process ends, your handler jumps in and grabs it, and system() gets nothing, which isn't what it wanted. If you run a command that has a side effect, you should see that it actually does get executed.

        It's interesting that it worked on Linux but not Solaris. Must be some difference in the way they deliver signals.

        Best solution is probably not to mix $SIG{CHLD} with system(). There are a couple of threads around here that might be useful... try a search or two.