The point of this code is to simulate a shell:
1) Ask for a command from stdin until CTRL+D is pressed or "exit" is entered as input.
2) Fork the process.
3) Parent waits for the command to be executed by the child.
4) Child executes the command.
5) Go to 1
Execvpe works(as p is pointing to PATH), but execve just triggers perror() unless I type in /bin/%command%. What am I doing wrong? Appreciate the help!
Output of /bin/env inside my nano-shell: PATH=/bin
8 #define SIZE 50
9 #define input fgets(buffer, SIZE, stdin)
10 #define exitcheck strcmp(strtok(buffer, "\n"), "exit")
11
12 int main(int argc, char *argv) {
13 char buffer[SIZE] = "echo";
14 char* const command[] = {buffer, NULL};
15 char* const envp[] = {"PATH=/bin", NULL};
16
17 do {
18 printf("nano-shell $ ");
19 pid_t pid = fork();
20 // Parent
21 if (pid > 0) {
22 int status;
23 waitpid(pid, &status, 0);
24 }
25 // Child
26 else if (pid == 0) {
27 execve(command[0], command, envp);
28 perror("Error: ");
29 _exit(1);
30 }
31 } while(input != NULL && exitcheck != 0 );
32
33 exit(EXIT_SUCCESS);
34 }
The execve()
will not search the path finding the executable file. That is to say, the filename
(i.e., the first argument) must be the path name of the file.
As for the third argument, envp
, for one thing, setting path does not make difference, since what has been mentioned above. For another, according to the manual page of execve:
"The argument vector and environment can be accessed by the called program's main function, when it is defined as:
int main(int argc, char *argv[], char *envp[])
Note, however, that the use of a third argument to the main function is not specified in POSIX.1."
That is to say, the envp
is likely not used at all following the POSIX.1. For example, as long as the filename
is absolute path, even though you set the envp to NULL
as: char *envp[] = {NULL};
, your program should still work.