execve 重定向到哪个文件描述符?
To which file descriptor execve redirect?
int main (void) {
int rc=fork();
if(rc==0){
close(1); //close stdout BEFORE opening my file
open("./c.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
//execve "wc"
char *cmd[3];
cmd[0] = strdup("wc"); //file to execuable
cmd[1]=strdup("c.c"); //first arg to command 'wc' -> c.c
cmd[2]=NULL;
execvp(cmd[0], cmd);
}
如果我关闭 () 标准输出,那么 execve ("wc") 的输出将在文件 c.txt
中,但前提是我在打开 () 之前关闭标准输出。如果我在
之后调用它
open("./c.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
close(1);
然后 -> wc: write error: Bad file descriptor
.
我读过,对于 open()(在我的情况下可能是 wc
输出)是 OS 从 0 到达文件描述符,因此它首先找到 1
作为标准输出到 printf() 到屏幕。所以我需要 close() 它,以便使用来自 open("./c.txt") for wc
的文件描述符。但如果那是正确的(我不知道我在哪里理解正确),那么我在 open() 调用之前或之后关闭 stdout 并不重要,不是吗?一旦关闭,OS 就没有其他 FD 可以用作输出。可能我没看清楚。
问题:为什么必须先关闭 fd1 才能重定向到 c.txt?
首先要建立的几个概念。
stdout
是作为程序启动的一部分自动打开的流之一。程序启动代码使用文件描述符 1
for stdout
).
execve
使用与 parent/calling 进程相同的打开文件描述符创建一个新进程(可以从 execve man page.
open
将寻找要使用的 lowest available file descriptor。
好的,现在开始你的代码。
案例 1 - 关闭、打开、执行
在这种情况下,会发生以下事件序列:
- 程序开始于
stdout
=>fd 1
。
close(1)
使 fd 1
可用。
open("c.txt")
returns 1
有效地将 stdout
重定向到文件。
execve
创建一个新进程,其中 1
打开并重定向到文件。
wc
写入 fd 1
现在在文件中结束。
案例 2 - 打开、关闭、执行
在这种情况下,会发生以下事件序列:
- 程序开始于
stdout
=>fd 1
。
open("c.txt")
被调用但 fd 1
不可用所以它 returns 2
.
close(1)
意味着现在实际上没有 stdout
.
execve
创建一个在 fd 1
上没有开放流的新进程(即没有 stdout
)。
wc
尝试写入 fd 1
并收到 bad file descriptor
错误,因为 fd 1
未打开。
int main (void) {
int rc=fork();
if(rc==0){
close(1); //close stdout BEFORE opening my file
open("./c.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
//execve "wc"
char *cmd[3];
cmd[0] = strdup("wc"); //file to execuable
cmd[1]=strdup("c.c"); //first arg to command 'wc' -> c.c
cmd[2]=NULL;
execvp(cmd[0], cmd);
}
如果我关闭 () 标准输出,那么 execve ("wc") 的输出将在文件 c.txt
中,但前提是我在打开 () 之前关闭标准输出。如果我在
open("./c.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
close(1);
然后 -> wc: write error: Bad file descriptor
.
我读过,对于 open()(在我的情况下可能是 wc
输出)是 OS 从 0 到达文件描述符,因此它首先找到 1
作为标准输出到 printf() 到屏幕。所以我需要 close() 它,以便使用来自 open("./c.txt") for wc
的文件描述符。但如果那是正确的(我不知道我在哪里理解正确),那么我在 open() 调用之前或之后关闭 stdout 并不重要,不是吗?一旦关闭,OS 就没有其他 FD 可以用作输出。可能我没看清楚。
问题:为什么必须先关闭 fd1 才能重定向到 c.txt?
首先要建立的几个概念。
stdout
是作为程序启动的一部分自动打开的流之一。程序启动代码使用文件描述符1
forstdout
).execve
使用与 parent/calling 进程相同的打开文件描述符创建一个新进程(可以从 execve man page.open
将寻找要使用的 lowest available file descriptor。
好的,现在开始你的代码。
案例 1 - 关闭、打开、执行
在这种情况下,会发生以下事件序列:
- 程序开始于
stdout
=>fd 1
。 close(1)
使fd 1
可用。open("c.txt")
returns1
有效地将stdout
重定向到文件。execve
创建一个新进程,其中1
打开并重定向到文件。wc
写入fd 1
现在在文件中结束。
案例 2 - 打开、关闭、执行
在这种情况下,会发生以下事件序列:
- 程序开始于
stdout
=>fd 1
。 open("c.txt")
被调用但fd 1
不可用所以它 returns2
.close(1)
意味着现在实际上没有stdout
.execve
创建一个在fd 1
上没有开放流的新进程(即没有stdout
)。wc
尝试写入fd 1
并收到bad file descriptor
错误,因为fd 1
未打开。