[英]Does it make sense to exit(0) after a call to execl()?
Consider the following code: 请考虑以下代码:
close(channel_data->pty_master);
if (login_tty(channel_data->pty_slave) != 0) // new terminal session
{
exit(1); // fail
}
execl("/bin/sh", "sh", mode, command, NULL); // replace process image
exit(0);
According to the documentation of execl()
, the current process image is being replaced and the call returns only on errors. 根据
execl()
的文档,当前的进程映像正在被替换,并且调用仅在错误时返回。
But why call exit()
after a call to execl()
if the process image is replaced? 但是,如果更换过程映像,为什么在调用
execl()
exit()
之后调用exit()
?
Exec calls may fail. Exec调用可能会失败。 A common epilogue would be:
一个常见的结局是:
perror("Some eror message");
_exit(127); /*or _exit(1); (127 is what shells return) */
You would usually run _exit
rather than exit
here, in order to skip atexit
hooks and stdio
buffer flushes. 你通常会运行
_exit
而不是在这里exit
,以便跳过atexit
hooks和stdio
buffer fllushes。
It does make sense to call exit
after some exec(3) function because they can fail (eg when execve(2) is failing). 在某些exec(3)函数之后调用
exit
是有意义的,因为它们可能会失败(例如,当execve(2)失败时)。 The execve(2) page lists a number of failure reasons. execve(2)页面列出了许多失败原因。
It should better be exit(EXIT_FAILURE)
or some other (non 0) exit code (conventionally a high exit code like 127 or 126 would be used for that usage, to separate failure of exec
vs errors in the program it would run), and I recommend calling perror
just before that exit
. 最好是
exit(EXIT_FAILURE)
或其他一些(非0)退出代码(通常会使用127或126这样的高退出代码来分隔exec
与它运行的程序中的错误),以及我建议在exit
之前调用perror
。 As explained by PSKocick there are good reasons to call _exit
(but his arguments could be reversed, one would want to run atexit
and standard fflushs by using exit
instead). 正如PSKocick所解释的那样 ,有很好的理由可以调用
_exit
(但是他的论点可以颠倒过来,人们希望通过使用exit
来运行atexit
和标准fflush)。
In your case, failure is unlikely, but imagine however if some other process has removed /bin/sh
(eg the sysadmin making the stupid mistake of running /bin/rm -rf .
in the root directory, or in /bin/
, perhaps in some other terminal window). 在你的情况下,失败是不太可能的,但想象一下,如果其他进程已经删除
/bin/sh
(例如,sysadmin在根目录中或在/bin/
中运行/bin/rm -rf .
犯了愚蠢的错误,也许在其他一些终端窗口)。
Still that execve
could also fail when system resources are (temporarily) exhausted, eg for 当系统资源(暂时)耗尽时,该
execve
也可能失败,例如
ENOMEM
Insufficient kernel memory was available.ENOMEM
内核内存不足。
And (in rare cases) this could even happen for /bin/sh
; 并且(在极少数情况下)这甚至可能发生在
/bin/sh
;
BTW your exec
usage would probably fail (with E2BIG
) if (by mistake) command
was a string of a million of non-null bytes. 如果(错误地)
command
是一百万个非空字节的字符串, E2BIG
你的exec
使用可能会失败(使用E2BIG
)。
As a general coding rule, all important system calls should be checked against failure. 作为通用编码规则,应检查所有重要的系统调用以防止失败。
You'll want to call exit
because you failed to exec
the program in question and you typically don't want that process to hang around since it's not running what you wanted it to run. 你会想要调用
exit
因为你没有exec
有问题的程序,而且你通常不希望这个过程因为它没有运行你想要它运行的东西而挂起。 Since execl
only returns on failure, there's no need to check the return status. 由于
execl
仅在失败时返回,因此无需检查返回状态。
In many cases, it also makes sense to print an error message to see why it failed. 在许多情况下,打印错误消息以查看失败原因也是有意义的。 You should also use an exit code other than 0. A non-zero exit code is used to indicate an abnormal exit, and the parent process can capture that when it calls
wait
. 您还应该使用0以外的退出代码。非零退出代码用于指示异常退出,父进程可以在调用
wait
时捕获它。
execl("/bin/sh", "sh", mode, command, NULL);
perror("command failed");
exit(1);
So yes, it makes sense to cal exit
, but not necessarily exit(0)
. 所以是的,cal
exit
是有意义的,但不一定exit(0)
。
But why call exit() after a call to execl() if the process image is replaced?
但是,如果更换过程映像,为什么在调用execl()之后调用exit()?
As you said, execl()
returns only on errors: 正如您所说,
execl()
仅返回错误:
execl("/bin/sh", "sh", mode, command, NULL); // replace process image
exit(0);
In the code above, exit()
is called only if the execl()
call failed. 在上面的代码中,仅当
execl()
调用失败时才调用exit()
。
As Jonathan Leffler suggested in his comment it may be a very good idea to return a value other than zero , since zero indicates success and the code did indeed fail if the program's control flow ever reached the exit()
call in the code above. 正如Jonathan Leffler在他的评论中建议的那样 ,返回零以外的值可能是一个非常好的主意,因为零表示成功 ,如果程序的控制流在上面的代码中达到了
exit()
调用,则代码确实失败了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.