Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Shell Background Processing in C

Posted on 2011-02-18
8
Medium Priority
?
3,529 Views
Last Modified: 2014-07-26
Hey Experts!

I am currently having issues running a background process in my shell that I have created.  Whenever I invoke the background process, by typing an '&' symbol after the commands, the program runs the process in the background, then exits my program.  Can anyone explain why this is happening?

Here is my function that handles new processes:
 
void initProcess()
{
	int status = 0;
    int pid = fork();

    if (pid == 0) {
		// child process
		if(background) {
			fclose(stdin); // close child's stdin
			fopen("/dev/null", "r"); // open a new stdin that is always empty
		}
        execvp(*commandArguments,commandArguments);
       
        // If an error occurs, print error and exit
       fprintf (stderr, "unknown command: %s\n", commandArguments[0]);
       exit(0);
       
    } else {
        // parent process, waiting on child process
        //waitpid(pid, &status, 0); //old code..
		
		if (background) {
			printf("starting background job %d\n", pid);
			childpids [nChildren] = pid;
			nChildren++;
			execvp(*commandArguments,commandArguments);
		} else { 
			waitpid(pid, &status, 0);
		} 
		
        if (status != 0) 				//process exits if error occurs
            fprintf  (stderr, "error: %s exited with status code %d\n", commandArguments[0], status);
    }
}

Open in new window


I do not think that I am implementing this idea correctly.. Any help would be greatly appreciated!!! :D   ~Rob
0
Comment
Question by:RobStl10
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
8 Comments
 
LVL 12

Expert Comment

by:JESii
ID: 34933030
Have you tried running it without the trailing '&' to see what happens?
0
 

Author Comment

by:RobStl10
ID: 34933969
Well, if I don't use the '&' symbol, it runs fine as a normal process.  My issue only occurs when I use the '&' symbol.  It prints out "Starting background process X", where X is the pid of the process.  But then exits my shell.  

Should I include more code so that you are able to see the entire shell process?
0
 
LVL 12

Expert Comment

by:JESii
ID: 34934170
Actually, if you are running in the background, then I'm not sure that you see any output - in the background, the task runs disconnected from a terminal.

Try closing stdout and then opening it to a file (similarly to what you did with stdin except not /def/null ) and see if you get some output.
0
 

Accepted Solution

by:
RobStl10 earned 0 total points
ID: 34941506
I found out the issue.  I am supposed to be closing stdin, opening /dev/null, then executing the command.  This should only be done in the child process though..  

My issue was that I would exit(0), inside the parent process.  This is why my shell would exit, then accept more intput.  I have fixed my code, so please take a look if you are interested :)
void initProcess()
{
	int status = 0;
    int pid = fork();
	//printf("PID: %i\n", pid);
	background = 0;
	
	if(strcmp(commandArguments[commandWordCount-1], "&") == 0) {
		background = 1;
		commandArguments[commandWordCount-1] = NULL;
		commandWordCount -= 1;
	}

	//printf("background: %i\n", background);
    if (pid == 0) {
		// child process
		if(background) {
			//printf("Child background process...");
			
			fclose(stdin); // close child's stdin
			fopen("/dev/null", "r"); // open a new stdin that is always empty
			execvp(*commandArguments,commandArguments);

			
			// If an error occurs, print error and exit
			fprintf (stderr, "unknown command: %s\n", commandArguments[0]);
			exit(1);
			
		} else {
			execvp(*commandArguments,commandArguments);
			
			// If an error occurs, print error and exit
			fprintf (stderr, "unknown command: %s\n", commandArguments[0]);
			exit(1);
		}
               
    } else {
        // parent process, waiting on child process
		
		if (background) {
			
			printf("starting background job %d\n", pid);
			childpids [nChildren] = pid;
			nChildren++;
						
		} else { 
			waitpid(pid, &status, 0);
		} 
		
        if (status != 0) 				//process exits if error occurs
            fprintf  (stderr, "error: %s exited with status code %d\n", commandArguments[0], status);
    }
}

Open in new window

0
 
LVL 12

Expert Comment

by:JESii
ID: 34942210
Excellent! Glad you got it working; and thanks for the updated code.  It looks like properly setting the background variable was a key element...
0

Featured Post

The Orion Papers

Are you interested in becoming an AWS Certified Solutions Architect?

Discover a new interactive way of training for the exam.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The Windows functions GetTickCount and timeGetTime retrieve the number of milliseconds since the system was started. However, the value is stored in a DWORD, which means that it wraps around to zero every 49.7 days. This article shows how to solve t…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

670 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question