Thread: C/System calls help

  1. #1
    Registered User
    Join Date
    Sep 2010
    Location
    Boston, MA
    Posts
    97

    C/System calls help

    This is on UNIX

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    int main(int argc,char **argv)
    {
    	int pid,pid1,pid2,pid3;
    	
    	pid=fork();
    	if(pid == 0)
    	{
    		printf("C1 -- %d\n",getpid());
    		sleep(5);
    		printf("C1 -- has terminated\n");
    		exit(1);
    	}
    	else if(pid > 0)
    	{
    		pid1=fork();
    		if(pid1 == 0)
    		{
    			printf("C2 -- %d\n",getpid());
    			sleep(5);
    			printf("C2 -- has terminated\n");
    			exit(2);
    		}
    		else if(pid1 > 0)
    		{
    			pid2=fork();
    			if(pid2 == 0)
    			{
    				printf("C3 -- %d\n",getpid());
    				sleep(5);
    				printf("C3 -- has terminated\n");
    				exit(3);
    			}
    			else if(pid2 > 0)
    			{
    				pid3=fork();
    				if(pid3 == 0)
    				{
    					printf("C4 -- %d\n\n\n",getpid());
    					sleep(5);
    					printf("C4 -- has terminated\n");
    					exit(4);
    				}
    				else if(pid3 > 0)
    				{
    					wait(pid3);
    					printf("\nParent -- %d\n",getpid());
    				}
    				else
    				{
    					printf("Error on fork 4.\n");
    					return -4;
    				}
    			}
    			else
    			{
    				printf("Error on fork 3.\n");
    				return -3;
    			}
    		}
    		else
    		{
    			printf("Error on fork 2.\n");
    			return -2;
    		}
    	}
    	else
    	{
    		printf("Error on fork 1.\n");
    		return -1;
    	}
    	
    	return 0;
    }
    I don't understand why this is not generating the following output.

    Code:
    C1 -- ####
    C2 -- ####
    C3 -- ####
    C4 -- ####
    
    
    C1 has terminated
    C2 has terminated
    C3 has terminated 
    C4 has terminated
    Parent -- ####
    I'm getting stuff like this
    Code:
    C1 -- ####
    C3 -- ####
    C2 -- ####
    C4 -- ####
    
    
    C1 has terminated
    Parent -- ####
    C2 has terminated
    C3 has terminated 
    C4 has terminated
    Last edited by omGeeK; 10-15-2012 at 07:44 PM.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Is this on UNIX or Linux? There are some subtle differences between them that often matter in how system calls behave, however I don't think it's an issue here.

    I only have Linux to test on, no UNIXes proper, but this should help:

    Compile with your warnings turned all the way up (-Wall option for gcc):
    Code:
    $ make fork
    gcc -Wall -Wunreachable-code -g -std=c99 -pedantic  -lm -lpthread  fork.c   -o fork
    fork.c: In function ‘main’:
    fork.c:14: warning: implicit declaration of function ‘exit’
    fork.c:14: warning: incompatible implicit declaration of built-in function ‘exit’
    fork.c:24: warning: incompatible implicit declaration of built-in function ‘exit’
    fork.c:34: warning: incompatible implicit declaration of built-in function ‘exit’
    fork.c:44: warning: incompatible implicit declaration of built-in function ‘exit’
    fork.c:48: warning: implicit declaration of function ‘wait’
    Eek! You're missing some header files. From the man pages of exit (link) and wait (link), you need to #include <stdlib.h> and <sys/wait.h>. Fixing that gives:
    Code:
    $ make fork
    gcc -Wall -Wunreachable-code -g -std=c99 -pedantic  -lm -lpthread  fork.c   -o fork
    fork.c: In function ‘main’:
    fork.c:50: warning: passing argument 1 of ‘wait’ makes pointer from integer without a cast
    /usr/include/sys/wait.h:116: note: expected ‘int *’ but argument is of type ‘int’
    Your wait call needs a pointer to int, i.e. the address of an int variable to store the return status.
    Code:
    int status;
    ...
    wait(&status);
    Now we can consider what your program is doing without worry of undefined behavior. All the info you need is in the man pages (sections 2 and 3 for the functions, and section 7 has lots of great system info), but they can be a bit difficult to grok if you're new to all this.

    The fork call creates independent processes. The order the parent and children get scheduled for execution is arbitrary, so any one may execute and finish first. The reason parent isn't always at the end is that there is only one call to wait(). That only waits for one child process (any one of them) to finish. Whichever is first, signals the parent, and the wait call returns, letting the parent finish. So once the first child is done, the parent can finish up, but only once execution returns to the parent process. Sometimes that happens before the rest of the children have executed, sometimes it happens dead last.

    You need to wait separately for each child you spawned. That means, with 4 children function, you must have 4 wait calls in the parent for it to finish last*. If you want to wait for one child in particular, based on it's PID, look into the waitpid function (read the man page).

    * You may actually need more. wait doen't return if and only if a child executes successfully, it may return for other reasons, and you may need to wait again. Again, read the man pages for all the reasons wait may return and how to check for successful exit.
    Last edited by anduril462; 10-15-2012 at 08:04 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. System calls
    By Sn0wcra5h in forum C Programming
    Replies: 10
    Last Post: 02-19-2010, 05:12 AM
  2. system calls
    By kiai_viper in forum Networking/Device Communication
    Replies: 7
    Last Post: 06-13-2007, 11:34 AM
  3. about system calls
    By fnoyan in forum C Programming
    Replies: 1
    Last Post: 02-27-2006, 06:25 AM
  4. help with system calls
    By go4mohit in forum C Programming
    Replies: 4
    Last Post: 06-06-2005, 09:42 AM
  5. Need some help,,system calls
    By kodiak76 in forum Linux Programming
    Replies: 6
    Last Post: 01-25-2005, 12:25 PM