【问题标题】:How to reopen stdout if it is closed by the process who called exec如果 stdout 被调用 exec 的进程关闭,如何重新打开它
【发布时间】:2019-11-16 11:45:18
【问题描述】:

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

例如下面的代码。

#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 中打开标准输出

【问题讨论】:

  • 我猜你的用例比 mcve 复杂一点...在执行之前使用dup 复制stdout。执行并关闭后,在您的副本上使用dup2 使fd 1 再次指向stdout

标签: c linux process exec


【解决方案1】:

首先,重要的是要注意 - 您只是将 fd 1 设置为 CLOEXEC,所以它当然会在调用 'execve' 时关闭。确保你明白这一点。如果您能够编辑“test1” - 您可以删除“fcntl”调用。

但是,另一方面 - 如果您根本无法编辑 'test'1 - 可能有几种方法可以绕过它。

    1234563 .
  1. (Linux 特定)如果在 'execve' 之前以某种方式调用了 'fork',您可能能够使用 procfs 文件系统访问已关闭的 fd。假设'test2'的父进程有你​​想在fd = 1中打开的'stdout',你可以使用getppid()获取它的PID,然后打开/proc/&lt;ppid&gt;/fd/1(当然-dup2结果fd到1)。

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

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-19
    • 2018-11-25
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多