0

I have the following program, when I run the program, I feel really confused that why my program didn't excute

   int num=i;
       printf("it is No.%d !",num);
       printf("hello , I will excute execvp!");

My program basically create 6 child processes to excute executionbode() function, and then use execvp to overload original program. However, everytime when I run the program, the string "hello, I will execute execvp" never shows up! Also I think those three sentences above also didn't execute in the running program? can someone tell me why? Here is my program

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include "makeargv.h"
#include "redirection.h"
#include <sys/wait.h>



int executionnode(int i);

int main(){
pid_t childpid;
     int i;
     int row=6;
     for(i=0;i<row;i++)
     {   childpid=fork();
         if(childpid==0)
            continue;
         else if (childpid>0)
            executionnode(i);

         else {
           perror("something wrong");
            exit(1);
          }
      }


}


int executionnode(int i){
   sleep(i);
   printf("hello, I am process:%ld\n",(long)getpid());
   wait(NULL);
   char *execArgs[] = { "echo", "Hello, World!", NULL };
   int num=i;
   printf("it is No.%d !",num);
   printf("hello , I will excute execvp!");
   execvp("echo", execArgs);

}

Can someone tell me why? and how to fix it? I feel it is really strange? Is it because of execvp() functions? I just began to learn operating system,so I am really confused about it! Thank you for helping me!

python3
  • 231
  • 3
  • 12
  • 2
    1) use the debugger 2) Read the man-page of `wait` – too honest for this site Sep 27 '15 at 16:15
  • Here's a hint: who are the child processes waiting for and why? Answering that question will go a long way to solving your problem. Also, it's more precise to say that `execvp` overwrites the *current* process image. – tonysdg Sep 27 '15 at 17:08

1 Answers1

1

The issue you are facing is the result of the combination of 2 different things:

1 - As tonysdg mentioned in the comment, execvp overwites the current process image, and to quote this:

execve() does not return on success, and the text, data, bss, and stack of the calling process are overwritten by that of the program loaded.

(execvp() is a front-end for execve())

and

2 - The stdout is a buffered stream, which means that the actual printing takes place when a newline character is found or the buffer is flushed.

(see more on this at Rudd Zwolinski's answer here )


So, now, let's see how these things interact and produce your issue: Just before you call execvp() your output buffer already contains the contents of the 2 previous printf's, however since there is no newline character, nothing is printed on the screen.

Then, execvp() is executed and overwrites everything on your current process, which of course means that the contents of your 'previous' output buffer are lost.

Here you can find many ways to address this issue and, just for completeness, I suggest you add \n to the final printf:

...
printf("hello , I will excute execvp!\n");
...

and then you're good to go:

$ ./soc
hello, I am process:4701
hello, I am process:4702
hello, I am process:4703
hello, I am process:4704
hello, I am process:4705
hello, I am process:4706
it is No.5 !hello , I will excute execvp!
Hello, World!
it is No.4 !hello , I will excute execvp!
Hello, World!
it is No.3 !hello , I will excute execvp!
Hello, World!
it is No.2 !hello , I will excute execvp!
Hello, World!
it is No.1 !hello , I will excute execvp!
Hello, World!
it is No.0 !hello , I will excute execvp!
Hello, World!
Community
  • 1
  • 1
sokin
  • 794
  • 2
  • 12
  • 20