英文:
Why does execve sometimes set errno and not print the error message?
问题
我已经阅读了作业政策此处。
请注意,在ls ls
的情况下,它会打印错误消息,但是对于cd test
(test不存在),它会将errno设置为2(没有这样的文件或目录),但不会打印错误消息。为什么会有这种行为上的差异?
我正在尝试使用子进程实现一个简单的Shell。我的操作系统是Ubuntu Desktop 22 LTS。execve
似乎有时允许程序打印错误消息,但其他时候只会设置errno。
这是在子进程中运行的代码。
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");
}
英文:
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");
}
答案1
得分: 3
Sure, here is the translated text:
execve
似乎有时允许程序打印其错误消息,但其他时候只会设置 errno。
execve()
并不特别限制它启动的程序的行为。毕竟,它涉及启动几乎每一个程序,无论何时。您所看到的是
execve()
失败与execve()
成功但结果程序失败之间的区别。如果execve()
成功加载并启动了一个新的程序映像,那么它的工作就完成了。它不会返回,部分原因是因为没有什么可返回的地方了。新映像已经取代了调用execve()
的那个映像。执行的任何错误报告都将由新进程执行,这就是您在ls ls
的情况下看到的情况。仅当
execve()
失败时才会返回。这通常是因为第一个参数未标识出execve()
能够启动的现有文件。当它失败时,是的,它会设置errno
。这就是您在cd
情况下观察到的情况——不是因为test
不存在,而是因为/bin/cd
不存在。顺便说一下,您可能想查看
perror()
。它会打印比原始的errno
值更详细的消息。
英文:
> execve
seems to sometimes allow the program to print its error message but other times will just set an errno.
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, and execve()
succeeding, but the resulting program failing on the other. If execve()
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 which execve()
was called. Any error reporting that is performed will be performed by the new process, which is what you see for ls ls
.
Only if execve()
fails does it return. This is most often because the first argument does not identify an existing file that execve()
is capable of launching. When it fails, yes, it sets errno
. This is what you observe in the cd
case -- not because test
does not exist, but because /bin/cd
does not.
By the way, you might want to look into perror()
. It will print a more informative message than the raw errno
value.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论