tags:

views:

99

answers:

5

I'm writing a shell which forks, with the parent reading the input and the child process parsing and executing it with execvp.

pseudocode of main method:

do{
 pid = fork();
 print pid;
 if (p<0) { error; exit; }
 if (p>0) { wait for child to finish; read input; }
 else { call function to parse input; exit; }
}while condition
return;

what happens is that i never seem to enter the child process (pid printed is always positive, i never enter the else). however, if i don't call the parse function and just have else exit, i do correctly enter parent and child alternatingly.

full code:
int main(int argc, char *argv[]){

 char input[500];
 pid_t p;
 int firstrun = 1;

 do{

  p = fork();

  printf("PID: %d", p);

  if (p < 0) {printf("Error forking"); exit(-1);}

  if (p > 0){

   wait(NULL);
   firstrun = 0;
   printf("\n> ");
   bzero(input, 500);
   fflush(stdout);
   read(0, input, 499);
   input[strlen(input)-1] = '\0';

  }

  else exit(0);

  else { if (parse(input) != 0 && firstrun != 1) { printf("Error parsing"); exit(-1); } exit(0); }

 }while(strcmp(input, "exit") != 0);

 return 0;
}

EDIT:

-that else exit(0) just something i forgot there from playing around

-adding a newlines to the prints shows that it does in fact correctly fork and enter the child process; thank you, the problem seems to be in the parse

+2  A: 

One culprit is else exit(0);

That would execute in the child shell, which means it never gets to the parsing stage. The code is also syntactically invalid because after that you have another else.

Matthew Flaschen
'Tis interesting - the code shown won't compile; the else just before the while doesn' have an if that it belongs with, does it?
Jonathan Leffler
It looks to me like that's an attempt to debug stuff. The code doesn't even compile with it left in, so it was probably added in to show what's been done so far, but the other stuff wasn't commented out.
cHao
A: 

Your core is a tad messy with all the nested if's and else's. There are some dangling else statements as well (else exit(0);). I'd start by cleaning those up. I can't see any other logical problems with your code. It's simple enough.

Noufal Ibrahim
A: 

Swap the lines

else exit(0);

and

else { if (parse(input) != 0 && firstrun != 1) { printf("Error parsing"); exit(-1); } exit(0); }
Loxley
That's still syntactically invalid.
Matthew Flaschen
+1  A: 

`if (p >= 0) {

if (p == 0) {/* chile process */}

else if (p > 0) {/* parent process */}

} else {

/* handle the error returned by fork() */

}`

I'd do it like the above pseudo code.

else exit(0); is what the child process is doing in your code.

vpit3833
A: 

Apart from everything everybody else has said about the fact that the else's are a complete mess, there are some other issues you will hit when you have fixed them.

In the child, the input array will be garbage on the first run because you don't put anything in it before forking.

It seems completely pointless to fork at all since you are not exec'ing anything in the child but you are waiting for the child to finish in the parent. Why not just call parse from the parent?

JeremyP