所以我正在用 C 构建一个 Unix minishell,并正在实现输入、输出和错误重定向,并且遇到了文件问题。我在找到重定向运算符的循环中打开我的文件,并使用 open(),它返回一个 fd。然后我相应地分配孩子的 fd,并调用执行函数。
当我的 shell 只是出去寻找程序并使用 execvp() 执行它们时,我没有太多问题。唯一的问题是在提示输入下一个命令行之前,我是否需要在文件描述符上调用 close()。我担心 fd 泄漏,但不完全了解它是如何工作的。
使用内置命令时出现了我真正的问题。我有一个名为“read”的内置命令,它接受一个参数,一个环境变量名称(可能是一个尚不存在的)。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,因为它是内置的。读取使用gets,它需要一个流变量,而不是fd。因此,在 irc 论坛上闲逛了一下之后,我被告知使用 fdopen,从文件描述符中获取流。所以在调用 get 之前,我调用:
rdStream = fdopen(inFD, "r");
然后打电话
if(fgets(buffer, envValLen, rdStream) != buffer)
{
if(inFD) fclose(rdStream);
return -1;
}
if(inFD) fclose(rdStream);
如您所见,目前我正在使用 fclose() 关闭流,除非它等于标准输入(即 0)。这是必要的吗?我需要关闭流吗?还是只是文件描述符?或两者?我很困惑我应该关闭哪个,因为它们都以不同的方式引用同一个文件。目前我没有关闭 fd,但我认为我绝对应该。我只是希望有人帮助确保我的 shell 没有泄漏任何文件,因为我希望它能够在单个会话中执行数千个命令而不会泄漏内存。
谢谢,如果你们想让我发布更多代码,请询问。