Why is execvp () executed twice with fork ()?

I am implementing a shell.

When you try to execute a command other than changing directories, execvp() is executed, the child is completed, and a new child is created. When I change catalogs, the child does not end and a new child is created. Here is an example of my code:

 for(;;) { printf("bash: "); parse(); ... pid_t pid = fork() if (pid == 0) if (!strcmp(line[0], "cd")) if (!line[1]) (void) chdir(getenv("HOME")); else (void) chdir(line[1]); else execvp(line[0], line); ... if (pid > 0) { while (pid == wait(NULL)); printf("%d terminated.\n", pid); } } 

cd ../; ls; runs correctly, except that I have to Ctrl+D to terminate the program twice.

Although, if I pass the same information (i.e. mybash < chdirtest ), it starts correctly once, completes the child, starts again, except for the original directly, and then completes the final child.

+5
source share
1 answer

cd should not be called through a child process, the shell itself must change its current directory (which is a property of the internal command: change the process of the shell itself).

A (primitve) shell should look like this:

 for(;;) { printf("bash: "); parse(); // realize internal commands (here "cd") if (!strcmp(line[0], "cd")) { if (!line[1]) (void) chdir(getenv("HOME")); else (void) chdir(line[1]); continue; // jump back to read another command } // realize external commands pid_t pid = fork() if (pid == 0) { execvp(line[0], line); exit(EXIT_FAILURE); // wrong exec } // synchro on child if (pid > 0) { while (pid == wait(NULL)); printf("%d terminated.\n", pid); } } 
+5
source

Source: https://habr.com/ru/post/1244285/


All Articles