Bug 71124 - "initlog -c any_cmd" exits with -1 if executed from parent ignoring SIGCHLD
Summary: "initlog -c any_cmd" exits with -1 if executed from parent ignoring SIGCHLD
Keywords:
Status: CLOSED DUPLICATE of bug 64603
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: initscripts
Version: 6.2
Hardware: All
OS: Linux
medium
low
Target Milestone: ---
Assignee: Bill Nottingham
QA Contact: Brock Organ
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2002-08-09 00:49 UTC by Andy Klages
Modified: 2014-03-17 02:29 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2006-02-21 18:49:21 UTC
Embargoed:


Attachments (Terms of Use)

Description Andy Klages 2002-08-09 00:49:31 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)

Description of problem:
If a process sets the SIGCHLD handler  to SIG_IGN and then does a fork/exec of 
initlog with the -c option, initlog will always exit with -1. It is suppose to 
exit with the exit code of the command specified with the -c option. I looked 
at the source for initlog and in process.c (inside the monitor() function), the 
waitpid() is failing with -1 and errno set to ECHILD. This is the expected 
behavior for waitpid() if SIGCHLD is ignored (see waitpid man page). Programs 
using waitpid() should always explicitly set the SIGCHLD handler to something 
other than SIG_IGN.

I modified the version of initlog I was using (initscripts-5.00) by adding 
a "signal(SIGCHLD,SIG_DFL);" inside the function forkCommand()
in process.c and this fixed the problem. I'm using Redhat 6.2. The bug also 
exists in Redhat 7.3.

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1.Compile and run the following program that ignores SIGCHLD and then does a 
fork and exec of  "initlog -c /bin/true" (/bin/true always exits with 0). The 
program then  does a wait() and prints the status.


#include <signal.h>
#include <string.h>
#include <errno.h>

int main()
{

	int rc, pid;
	int status; 

	signal(SIGCHLD, SIG_IGN);

	if ((pid=fork()) > 0) {
		/* parent */
		rc = wait(&status);
		if (rc == pid) {
			printf("status is %d (it should be 0)\n", status);
		} else {
			perror("waitpid");
		}
	} else if (pid == 0) {
		execlp("/sbin/initlog", "initlog", "-c", "/bin/true", 0);
		perror("execlp");
		exit(1);
	}		
}


 
	

Actual Results:  From the above program I get the following output:

status is 65280 (it should be 0)

Expected Results:  I should've seen the following because initlog is suppose to 
exit with the exit code of the command, which is 0:

status is 0 (it should be 0)

Additional info:

Note that the child process, initlog, inherits the ignored signal handling for 
SIGCHLD from the parent. If I change the sample program so that the signal 
handler is set to SIG_DFL, I get the expected output.

I discovered this bug from an rc script "startup failure" logged 
in /var/log/messages. I have a program that ignores SIGCHLD and 
executes "/etc/rc.d/init.d/dhcpd restart". dhcpd is successfully restarted but 
I get a message logged stating that "dhcpd startup failed" 
in /var/log/messages. By changing my program to not ignore SIGCHLD eliminates 
failed message. Regardless, initlog should explicitly set the SIGCHLD handler 
since it uses waitpid().

Comment 1 Andy Klages 2003-05-23 15:59:27 UTC
This is the same problem as described in report #64603. It's fixed with a simple 
1 line addition to initlog.c: signal(SIGCHLD, SIG_DFL).

Comment 2 Bill Nottingham 2003-06-06 22:40:13 UTC

*** This bug has been marked as a duplicate of 64603 ***

Comment 3 Red Hat Bugzilla 2006-02-21 18:49:21 UTC
Changed to 'CLOSED' state since 'RESOLVED' has been deprecated.


Note You need to log in before you can comment on or make changes to this bug.