C - 使用 open() 和 fdopen() 时关闭文件的正确方法 [英] C - Proper way to close files when using both open() and fdopen()

查看:25
本文介绍了C - 使用 open() 和 fdopen() 时关闭文件的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I'm building a Unix minishell in C, and am implementing input, output, and err redirection, and have come across a problem with files. I open my files in a loop where I find redirection operators, and use open(), which returns an fd. I then assign the child's fd accordingly, and call an execute function.

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

When my shell is just going out and finding programs, and executing them with execvp(), I don't have much of a problem. The only problem is knowing whether or not I need to call close() on the file descriptors before prompting for the next command line. I'm worried about having an fd leak, but don't exactly understand how it works.

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

My real problem arises when using builtin commands. I have a builtin command called "read", that takes one argument, an environmental variable name(could be one that doesn't yet exist). Read then prompts for a value, and assigns that value to the variable. Here's an example:

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

好吧,可以说我尝试过这样的事情:

Well lets say that I try something like this:

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

这很好用,请记住 read 在父进程内执行,我不使用 execvp 调用 read,因为它是内置的.Read 使用gets,它需要一个流变量,而不是一个fd.因此,在 irc 论坛上闲逛了一下之后,我被告知使用 fdopen,从文件描述符中获取流.所以在调用gets之前,我调用:

This works great, keep in mind that read executes inside the parent process, I don't call read with execvp since it's builtin. Read uses gets, which requires a stream variable, not an fd. So after poking around on the irc forums a bit I was told to use fdopen, to get the stream from the file descriptor. So before calling gets, I call:

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 没有泄漏任何文件,因为我希望它能够在单个会话中执行数千个命令而不会泄漏内存.

As you can see, at the moment I'm closing the stream with fclose(), unless it is equal to stdin(which is 0). Is this necessary? Do I need to close the stream? Or just the file descriptor? Or both? I'm quite confused on which I should close, since they both refer to the same file, in a different manner. At the moment I'm not closing the fd, however I think that I definitely should. I would just like somebody to help make sure my shell isn't leaking any files, as I want it to be able to execute several thousand commands in a single session without leaking memory.

谢谢,如果你们想让我发布更多代码就问吧.

Thanks, if you guys want me to post anymore code just ask.

推荐答案

标准 说:

fclose() 函数应在与指向的流相关联的文件描述符流.

The fclose() function shall perform the equivalent of a close() on the file descriptor that is associated with the stream pointed to by stream.

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

So calling fclose is enough; it will also close the descriptor.

这篇关于C - 使用 open() 和 fdopen() 时关闭文件的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆