C - 使用open()和fdopen()时关闭文件的正确方法

时间:2012-12-03 20:26:58

标签: c unix file-io memory-leaks

所以我在C中构建一个Unix minishell,并且正在实现输入,输出和错误的重定向,并且遇到了文件问题。我在循环中打开我的文件,在那里我找到重定向操作符,并使用open(),它返回一个fd。然后我相应地分配孩子的fd,并调用执行函数。

当我的shell刚出去找程序,并用execvp()执行它们时,我没有太大的问题。唯一的问题是在提示输入下一个命令行之前,我是否需要在文件描述符上调用close()。我担心fd泄漏,但不清楚它是如何工作的。

使用内置命令时出现了真正的问题。我有一个名为“read”的内置命令,它接受一个参数,一个环境变量名称(可能是一个尚不存在的名称)。然后读取提示输入值,并将该值赋给变量。这是一个例子:

% read TESTVAR
test value test value test value
% echo  ${TESTVAR}
test value test value test value

嗯,让我说我尝试这样的事情:

% echo here's another test value > f1
% read TESTVAR < f1
% echo  ${TESTVAR}
here's another test value

这很好用,请记住read在父进程内执行,我不用execvp调用read,因为它是内置的。读取使用获取,需要流变量,而不是fd。所以在浏览了irc论坛之后,我被告知要使用fdopen来从文件描述符中获取流。所以在打电话之前,我打电话给:

rdStream = fdopen(inFD, "r");

然后致电

if(fgets(buffer, envValLen, rdStream) != buffer) 
{
    if(inFD) fclose(rdStream);
    return -1;
}
if(inFD) fclose(rdStream);

正如您所看到的,目前我正在使用fclose()关闭流,除非它等于stdin(为0)。这有必要吗?我需要关闭流吗?或者只是文件描述符?或两者?我很困惑我应该关闭它,因为它们都以不同的方式引用同一个文件。目前我还没有关闭fd,但我认为我绝对应该。我希望有人帮助确保我的shell没有泄漏任何文件,因为我希望它能够在单个会话中执行数千个命令而不会泄漏内存。

谢谢,如果你们想让我发布任何代码,请问。

2 个答案:

答案 0 :(得分:6)

standard说:

  

fclose()函数将执行相当于close() 的操作   与指向的流关联的文件描述符   流。

所以调用fclose就足够了;它也将关闭描述符。

答案 1 :(得分:2)

FILE是标准C库的缓冲对象。当你执行fclose(标准C函数)时,它最终将调用close(Unix系统函数),但只有在确保刷新C库缓冲区之后。所以,我想说,如果您使用fopenfwrite,那么您应该使用fclose,而不仅仅是close,否则您可能会丢失一些数据。