execve有时会设置errno但不打印错误消息。

huangapple go评论67阅读模式
英文:

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");
}

以下是输出execve有时会设置errno但不打印错误消息。

英文:

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");
			}

Here is the outputexecve有时会设置errno但不打印错误消息。

答案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.

huangapple
  • 本文由 发表于 2023年5月26日 09:02:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76337047.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定