当 fclose 使用 popen 创建的文件时发生了什么?

问题描述 投票:0回答:3

我只需要找到一个非常烦人的错误,有人使用

popen
打开管道,但用
fclose
而不是
pclose
关闭C文件。在 Linux 上这没有问题,但后来这个程序在 OSX 上编译,事情就出了问题。

所以我想知道,用

popen
而不是
fclose
关闭由
pclose
创建的管道时会出现什么问题?为什么这可以在 Linux 上运行,但不能在 OSX/BSD 上运行?

linux macos popen fclose
3个回答
3
投票

它可能只看起来适用于Linux,例如,您没有注意到这个问题。这些问题列出了在需要

fclose
的情况下使用
pclose
时程序可能出现故障的一些方式(在各种平台上):

这些有一些关于因未正确关闭管道而可能发生的坏事情(例如,僵尸进程)的评论。在某些情况下,您的程序可能会打开管道一次,然后无法再次打开管道。


0
投票

我不确定您对这些问题能得到什么样的答案,但是……

所以我想知道,用

popen
而不是
fclose
关闭由
pclose
创建的管道时会出现什么问题?

问题在于程序员没有遵守

popen
API 的设计契约。这会导致未定义的行为。您所得到的具体行为是实现细节。从字面上看,除非分析您正在使用的 C 库的实现,否则您无法知道可能会出现什么问题。

为什么这可以在 Linux 上运行,但不能在 OSX/BSD 上运行?

因为未定义的行为可能包括

fclose
显然在
pclose
返回的文件指针上像
popen
一样工作。或者它可能包括它不以您观察到的任何方式工作。而且因为实现方式有很多不同。


0
投票

我认为安全的方法是: if( lseek(fileno(fp), (off_t) 0, SEEK_SET) < 0 ) pclose(fp); else fclose(fp);

为什么库不以这种方式实现 fclose 超出了我的范围。

© www.soinside.com 2019 - 2024. All rights reserved.