3

I have a Perl script which invokes the sqlldr and loads data to a table from a flat file.

Now, my problem is, even though the sqlldr loads the table fine it is returning exit code as -1(got by using $?), when i tried using $! it says No child processes.

I'm executing this script by using sudo command

sudo -u <uname> bash
<script_name>.pl

This Perl script is working fine if i execute it directly from my user id. I really don't understand why this error shows up only when i execute through sudo user.

Please help me to understand this error.

EDIT:It's working fine if i give $SIG{CHLD} = 'DEFAULT'; in my code. But, if i remove this step, the problem shows up again. I got this code from WWW when i was browsing about this error. Any idea what it does?

FMc
  • 41,963
  • 13
  • 79
  • 132
Vivek
  • 4,452
  • 10
  • 27
  • 45
  • It's very difficult to diagnose this without seeing at least the relevant parts of your perl code. – crazyscot Apr 09 '11 at 17:45
  • Its a 300 lines of code and i really don't know in which part of the code this error arises. – Vivek Apr 09 '11 at 18:17
  • 4
    The [perl documentation for `wait()`](http://perldoc.perl.org/functions/wait.html) may help. – Andy Apr 09 '11 at 18:30
  • $! is altered for errors in the current process. – Horus Apr 10 '11 at 15:11
  • @Horus Can you please provide more detail on what you said? – Vivek Apr 11 '11 at 04:14
  • What I mean is, he is running a child process, and appears to want that error information. The $! variable only stores error information for the current process, it will never store information for the child process. The SQLLDR error information can be collected into the current process a number of ways, but not with $!. – Horus Apr 11 '11 at 13:06
  • I know you mentioned your code is over 300 lines but it would be helpful if you could provide the part of the code around the '$!' part. Can you please provide at least a few lines before and including the line where you are printing or dying with $!? It would be most helpful, but maybe not enough, we won't know until we see it. – wallisds Apr 26 '11 at 13:13
  • 1
    I've seen this error before... you're setting $SIG{CHLD} to 'IGNORE' in this script or setting it as such in a parent process. The problem is that `system` uses `waitpid` (or a form of it) to wait for your command to complete. If you're ignoring child process terminations, then `waitpid` will try to reap a child already disappeared. Using wait when you have no child processes gives this error. – unpythonic Jun 07 '11 at 00:55

1 Answers1

1

On most Unix platforms, the CHLD (sometimes also known as CLD) signal has special behavior with respect to a value of 'IGNORE'. Setting $SIG{CHLD} to 'IGNORE' on such a platform has the effect of not creating zombie processes when the parent process fails to wait() on its child processes (i.e. child processes are automatically reaped). Calling wait() with $SIG{CHLD} set to 'IGNORE' usually returns -1 on such platforms.
Excerpted from http://perl.active-venture.com/pod/perlipc-signal.html

Basically what is happening is that somewhere the CHLD signal has been set to IGNORE probably by sqlldr. When you attempt to check on the status of the child process you receive the -1 which is sometimes referred to as ECHILD. This occurs because the information about the completion status of the child process has been discarded due to the ignoring of the CHLD signal. By setting $SIG{CHLD} = 'DEFAULT'; you are indicating that the CHLD signal should be handled by the DEFAULT handler and not ignored.

I do not know why the CHLD signal is being ignored when the script is executed from sudo user versus being executed directly from your user id.

dave
  • 1,520
  • 11
  • 8