Hi guys,

For some reason my application is doing a seg fault when I tell the parent to wait for the child to be done with the process.
Here is the output:
andorian 73% pr5 -a 3 -s 10 -c 1

child_alarm_time = 3
child_processes = 1
child_sleep_time = 10
Installed SIGALRM, SIGINIT,SIGCHLD signals
18740: Tue Oct 14 02:57:45 2008 alarm signal received
18740: Tue Oct 14 02:57:48 2008 alarm signal received
18740: Tue Oct 14 02:57:51 2008 alarm signal received
18740: Tue Oct 14 02:57:52 2008 here is child 0
18740: Tue Oct 14 02:57:52 2008 Killing this child process. 0
18739: Tue Oct 14 02:57:52 2008 child signal received - ignored
Segmentation fault

I also get the seg fault if I do the following:
pr5 -c 1
pr5 -c 2


Here is my code
Code:
static void Sleep(int alarm_time_interval, int total_sleep_time)
{
	int remaining_sleep_time = total_sleep_time;

	while (remaining_sleep_time > 0)
	{
		if (alarm_time_interval > 0)
		{ alarm(alarm_time_interval); }
		remaining_sleep_time = sleep(remaining_sleep_time);
	}
}

/*----------------------------------------------------------------------------*/

/* The functions in this section are intended to demonstrate various usages and
* properties of signals and signal handlers.  They should be removed or modified
* in the final version of the program.
*/

static void generic_signal_handler(int sig)
{
	print_message_1("generic_signal_handler, signal", sig);
}

static void SIGALRM_handler(int sig)
{
	if (sig == SIGALRM)
	{ print_message("alarm signal received"); }
	else
	{ print_message_1("serious error: SIGALRM_handler, received signal", sig); }
}

static void SIGINT_handler(int sig)
{
	if (sig == SIGINT)
	{ print_message("interrupt signal received - ignored"); }
	else
	{ print_message_1("serious error: SIGINT_handler, received signal", sig); }
}

static void SIGCHLD_hanlder(int sig)
{
	if(sig == SIGCHLD)
	{ print_message("child signal received - ignored"); }
	else
	{ print_message_1("serious error: SIGCHLD_handler, received signal", sig); }
}



#ifndef NSIG
#define NSIG 64
#endif

static int generic_signal_handler_installed[NSIG];
/* signal 0 is reserved
* the default handlers for SIGKILL and SIGSTOP cannot be replaced
*/

/* try to replace every default signal handler */
static void signal_setup(void)
{
	/* int i, ret;

	for (i = 0; i < NSIG; i++)
	{
	ret = install_signal_handler(i, generic_signal_handler);
	generic_signal_handler_installed[i] = (ret == 0);
	}*/


	printf("Installed SIGALRM, SIGINIT,SIGCHLD signals\n");
	//just set up these 3 signal handlers
	install_signal_handler(SIGALRM, SIGALRM_handler);
	install_signal_handler(SIGINT, SIGINT_handler);
	install_signal_handler(SIGCHLD,SIGCHLD_hanlder);
}


/*----------------------------------------------------------------------------*/

int main(int argc, char *argv[])
{
	
	//set up the signal handlers
	signal_setup();

	//check to see if no arguments were passed, if there weren't then don't
	//create any children

	//fork children based on what is passed through the command line
	pid_t child_pid;

	//holds an array of the child processes so the parent can wait for them.
	pid_t child_array[MAX_CHILDREN];

	int CHILD_STAT;

	//print_process_table("Table before forking.");

	//creating processes
	for(int i =0; i < child_processes; i++)
	{
		child_pid = fork();
		child_array[i] = child_pid;


		if(child_pid == (pid_t)(-1))
		{
			//this is the parent process.  The fork failed, and there is no child
			print_message_error("fork()", strerror(errno));
			exit(EXIT_FAILURE);
		}
		else if(child_pid == 0)
		{
			//this is a child process.  The fork worked
			//checking to see if alarm/sleep flags were set
			if(a_flag || s_flag)
			{
				Sleep(child_alarm_time,child_sleep_time);
			}
			
			print_message_1("here is child ",i);
			print_message_1("Killing this child process.",i);
			exit(child_exit_status);
		}
		else
		{
			//print_message("here is the parent, all children created.");
			//if this flag is set, then set the parent alarm/sleep 
			if(b_flag || t_flag)
			{
				//set alarm
				//printf("set the alarm: %d set sleep: %d for the process: %d\n",parent_alarm_time,parent_sleep_time,getpid());
				Sleep(parent_alarm_time,parent_sleep_time);
			}

			//this is a parent process.  The fork worked
			//add more code but do not exit yet
			//Wait for the child process to be done
			wait_child(child_pid,CHILD_STAT);


			

			//update the process table
			//printf("added child process %d\n", child_pid);
			insert_process_table(child_pid);
			//print_process_table("Table after inserting the process in parent.");

			//print_process_table("Parent calling this again");
		}
	}

	//tried this didn't work 
	/*for(int i = 0; i < child_processes; i++)
	{
		wait_child(child_array[i],CHILD_STAT);

	}*/

	print_message("here is the parent, all children created");


	if(b_flag || t_flag)
	{
		//set alarm
		//printf("set the alarm: %d set sleep: %d for the process: %d",parent_alarm_time,parent_sleep_time,getpid());
		Sleep(parent_alarm_time,parent_sleep_time);
	}

	return EXIT_SUCCESS;


So basically I'm getting this when I try to create a 1 or more child processes and I tell the parent to wait for the child to be done, so the wait_child is where the error has to be at and I"m not sure why.

My guess is that I'm killing the process and then asking it to wait for a dead process?

Here is what the child_wait process looks like:
Code:
#include <errno.h>

/* for waitpid(2) and wait(2) */
#include <sys/types.h>
#include <sys/wait.h>

#include "pr5_wait.h"

/*----------------------------------------------------------------------------*/

/* wait for a child process whose pid you know
 *
 * return 1 if a child was found
 *    *child_status has been updated, and the child has terminated
 *
 * return 0 if no child was found
 *    *child_status has not been updated
 */

int wait_child(pid_t wait_pid, int *child_status)
{
  int s;

  /* loop because waitpid() can be interrupted by a signal and return early */

  while (waitpid(wait_pid, &s, 0) == (pid_t)(-1))
    {
      if (errno == ECHILD)		/* no more children */
        { return 0; }
    }

  *child_status = s;

  return 1;
}

/*----------------------------------------------------------------------------*/

/* wait for a child process whose pid you do not know
 *    if more than one child has terminated, report only one
 *
 * return 1 if a child was found
 *    *wait_pid and *child_status have been updated, and the child has terminated
 *
 * return 0 if no child was found
 *    *wait_pid and *child_status have not been updated
 */

int wait_any_child(pid_t *wait_pid, int *child_status)
{
  pid_t w;
  int s;

  /* loop because wait() can be interrupted by a signal and return early */

  while ((w = wait(&s)) == (pid_t)(-1))
    {
      if (errno == ECHILD)		/* no more children */
        { return 0; }
    }

  *wait_pid = w;
  *child_status = s;

  return 1;
}

/*----------------------------------------------------------------------------*/

That code is correct, I"m just using it wrong I think.

Any help would be great.