Yes, I have read the homework policy here.
Notice here how, for ls ls it prints the error message but, for cd test (test does not exist), it sets the errno to 2 (no such file or directory) but does not print the error message. Why is there this difference in behavior?
I am trying to implement a simple shell using child processes. My operating system is Ubuntu Desktop 22lts. execve seems to sometimes allow the program to print its error message but other times will just set an errno.
Here is the code which runs in the child process.
int val;
if(strcmp(tokens[0], "cd") == 0){
val = execve("/bin/cd", tokens, NULL);
}
if(strcmp(tokens[0], "ls") == 0){
val = execve("/bin/ls", tokens , NULL);
}
if(strcmp(tokens[0], "cat") == 0){
val = execve("/bin/cat", tokens, NULL);
}
if(strcmp(tokens[0], "echo") == 0){
val = execve("/bin/echo", tokens, NULL);
}
if(strcmp(tokens[0], "sleep") == 0){
val = execve("/bin/sleep", tokens, NULL);
}
if(strcmp(tokens[0], "date") == 0){
val = execve("/bin/date", tokens, NULL);
}
if(strcmp(tokens[0], "pwd") == 0){
val = execve("/bin/pwd", tokens, NULL);
}
if(val == -1){
int err = errno;
printf("%d", errno);
printf("Incorrect command.\n");
}

execve()does not particularly constrain the behavior of the programs it starts. After all, it is involved in starting almost every program that ever starts.What you're seeing is a difference between
execve()itself failing on one hand, andexecve()succeeding, but the resulting program failing on the other. Ifexecve()succeeds in loading and starting a new program image then its job is done. It does not return, in part because there is nothing left to return to. The new image has replaced the one in whichexecve()was called. Any error reporting that is performed will be performed by the new process, which is what you see forls ls.Only if
execve()fails does it return. This is most often because the first argument does not identify an existing file thatexecve()is capable of launching. When it fails, yes, it setserrno. This is what you observe in thecdcase -- not becausetestdoes not exist, but because/bin/cddoes not.By the way, you might want to look into
perror(). It will print a more informative message than the rawerrnovalue.