如果 stdout 被调用 exec 的进程关闭,如何重新打开它

How to reopen stdout if it is closed by the process who called exec

是否可以重新打开标准输出,如果它已经关闭。

例如下面的代码。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

int main(){
    fcntl(1,F_SETFD,FD_CLOEXEC) ; 
    execve("./test2",NULL, NULL);   
    printf("Can you see me [TWO]\n");
}

以上代码关闭标准输出文件描述符,然后调用execve。 test2的代码如下

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

int main() {
    printf(" standard output\n");
    perror("standard error");
}

输出: 标准错误:错误的文件描述符

有没有办法在 test2.c

中打开标准输出

首先,请务必注意 - 您只需将 fd 1 设置为 CLOEXEC,因此它当然会在 'execve' 调用时关闭。确保你明白这一点。如果您能够编辑 'test1' - 您可以删除 'fcntl' 调用。

但是,另一方面 - 如果您根本无法编辑“test”1 - 可能有几种方法可以解决它。

  1. 如果你同意 'stdout' 和 'stderr' 指向同一个地方(也许它们最初是?) - 你可以将 fd=2 复制到 1,使用以下调用:dup2(2,1).

  2. (Linux 具体)如果 'fork' 在 'execve' 之前以某种方式被调用,您也许可以使用 [=11= 访问已关闭的 fd ] 文件系统。假设 'test2' 的父进程在 fd=1 中有你想要打开的 'stdout',你可以使用 getppid() 获取它的 PID,然后打开 /proc/<ppid>/fd/1(当然- dup2 结果 fd 到 1).

否则 - 可能无法 "reopen" 文件描述符 - 因为它已关闭。显然,从现在开始,您始终可以 open 您希望 stdout 指向的文件(dup2 它指向 1!),并避免 'Bad file descriptor'错误。

祝你好运!