2

Im trying to emulate shell through C program. In my program whenever I run any normal (foreground) commands it works fine. Also I have handled background process with commands ending with '&'. Now to handle this I have avoided the parent waiting for a child process.

The problem is whenever for the first time in my shell I run any background command(i.e ending in '&') then it works fine. But then after that each command(normal) doesnot terminate. I guess it waits for the previously opened process. How to rectify. Please you can ask questions so that i can make myself more clear to you. This is the snippet which is doing the above mentioned task.

child_id=fork();
if(child_id==0){
        //logic fo creating command
        int ret=execvp(subcomm[0],subcomm);
}
//Child will never come here if execvp executed successfully
if(proc_sate!='&'){
        for(i=0;i<count_pipe+1;i++){            
            waitpid(0,&flag,0);
            }
        //something to add to make it not wait for other process in my scenario for second time 
}

Here proc_state just determines whether it is background or foreground.It is just a character. count_pipe is just a variable holding number of pipes (e.g ls -l|wc|wc this contains 2 pipes). Dont worry this all is working fine.

6
  • Please show how you are starting the processes in "your" shell. Commented Sep 12, 2013 at 20:39
  • Edited the question.Please check Commented Sep 12, 2013 at 20:45
  • You should throw an exception or something if execvp fails. Don't let it fall-thru to the next line. You want your child to exit immediately, not waitpid. Commented Sep 12, 2013 at 20:47
  • Don't throw exceptions. Just print an error message and exit(). And use some whitespace, for heaven's sake. Commented Sep 12, 2013 at 20:48
  • Sorry i have not included that but i have handled it. Dont Worry execvp is working fine. Just the above mentioned issue still remains Commented Sep 12, 2013 at 20:48

1 Answer 1

2

waitpid(0, &flag, 0) waits for any child process whose process group ID is equal to that of your shell. So if you have not called setsid() after the fork() of the disconnected child process, the code above will wait for that too.

pid_t pid = fork();
if (pid == 0) { /* child process */
    setsid(); /* Child creates new process group */
    ... /* redirections, etc */
    execvp(...);
}
Sign up to request clarification or add additional context in comments.

6 Comments

setsid I guess creating a process in new session. Which is not returning signal to parent. So now my program is waiting even for foreground process if I try this
I meant this only for programs started with '&'.
Can I have my upvote please? My new hobby is collecting Stackoverflow points, you know... :-)
signal(SIGCHLD,SIG_IGN) even this will work I guess because it removes the children that terminates later. And avoid turning then into zombie.
Im new to stackoverflow. So it is showing not enough points to upvote. Sorry. Thanks for reply anyways :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.