unix 在关闭stdout和stdin文件描述符后重新打开它们

f0ofjuux  于 5个月前  发布在  Unix
关注(0)|答案(3)|浏览(81)

我正在写一个函数,给定一个参数,它将把stdout重定向到一个文件,或者从一个文件中读取stdin。为此,我关闭了与stdout或stdin相关的文件描述符,这样当我打开文件时,它就在我刚刚关闭的描述符下打开。这可以工作,但问题是,一旦完成了这一点,我需要将stdout和stdin恢复到它们真正应该是的样子。
我可以为stdout做的是open("/dev/tty",O_WRONLY);,但我不确定为什么这样做,更重要的是我不知道stdin的等效语句。
因此,对于stdout,

close(1);
if (creat(filePath, O_RDWR) == -1)
{
    exit(1);
}

字符串
对于stdin

close(0);
if (open(filePath, O_RDONLY) == -1)
{
    exit(1);
}

9rbhqvlz

9rbhqvlz1#

您应该使用dup()和dup 2()来克隆文件描述符。

int stdin_copy = dup(0);
int stdout_copy = dup(1);
close(0);
close(1);

int file1 = open(...);
int file2 = open(...);

< do your work. file1 and file2 must be 0 and 1, because open always returns lowest unused fd >

close(file1);
close(file2);
dup2(stdin_copy, 0);
dup2(stdout_copy, 1);
close(stdin_copy);
close(stdout_copy);

字符串
然而,有一个小细节你可能要小心(来自man dup):
这两个描述符不共享文件描述符标志(close-on-exec标志)。重复描述符的close-on-exec标志(FD_CLOEXEC;参见fcntl(2))为关闭。
如果这是一个问题,您可能必须恢复close-on-exec标志,可能使用dup 3()而不是dup 2()来避免竞争条件。
另外,请注意,如果您的程序是多线程的,其他线程可能会意外地写入/读取您重新Map的stdin/stdout。

bwleehnv

bwleehnv2#

我觉得你可以在重定向之前“保存”描述符

int save_in, save_out;

save_in = dup(STDIN_FILENO);
save_out = dup(STDOUT_FILENO);

字符串
稍后,您可以使用dup2来恢复它们:

/* Time passes, STDIN_FILENO isn't what it used to be. */
dup2(save_in, STDIN_FILENO);


在这个例子中我没有做任何错误检查-你应该做。

aoyhnmkz

aoyhnmkz3#

你可以创建一个子进程,只在子进程中设置重定向。然后等待子进程终止,并继续在父进程中工作。这样你就完全不必担心重定向会被逆转。
只需查找使用fork()和wait()的代码示例。

相关问题