C 确定可读文件描述符是否为管道的读取端

C 确定可读文件描述符是否为管道的读取端,c,linux,file-descriptor,splice,zero-copy,C,Linux,File Descriptor,Splice,Zero Copy,我想使用将数据从STDIN_FILENO零拷贝到文件描述符(可以是常规文件、字符或块设备、FIFO或任何可以打开的文件)。为了使用拼接,from file descriptor或to file descriptor必须是管道的适当末端,因此通常创建一个管道作为中间缓冲区,当程序员希望将数据从非管道零拷贝到非管道时。但是,如果STDIN\u FILENO已经是管道的读取端,那么我可以跳过该步骤,尝试直接从STDIN\u FILENO拼接到另一个文件描述符。因此,我希望能够确定STDIN\u FIL

我想使用将数据从
STDIN_FILENO
零拷贝到文件描述符(可以是常规文件、字符或块设备、FIFO或任何可以打开的文件)。为了使用
拼接
,from file descriptor或to file descriptor必须是管道的适当末端,因此通常创建一个管道作为中间缓冲区,当程序员希望将数据从非管道零拷贝到非管道时。但是,如果
STDIN\u FILENO
已经是管道的读取端,那么我可以跳过该步骤,尝试直接从
STDIN\u FILENO
拼接到另一个文件描述符。因此,我希望能够确定
STDIN\u FILENO
是否是管道的读取端


是否有一个Linux系统调用可以确定STDIN\u FILENO是否是管道的读取端?

要获取关于打开的fd的信息,可以使用fstat()。我猜结果的st_模式应该是管道的S_IFFO。或者,/proc/self/fd/和/proc/self/fdinfo/还提供有关文件描述符的一些信息。请记住,/proc是特定于linux的


然而,我认为首先尝试使用splice()可能会更容易,如果它失败(使用EINVAL?),请使用您的魔法。

作为替代方案,
lseek()
将使用
ESPIPE失败,如果“fd与管道、套接字或FIFO关联”。因此,无操作
lseek(fd,0,SEEK\CUR)
将告诉您文件描述符是否为其中任何一个


在我的情况下,这涵盖了我感兴趣的所有案例。

我编写了一个测试程序,创建了一个管道,名为
fstat
,并测试了
S_ISFIFO
:。结果是管道读取端的
st_模式
上的
S_ISFIFO
为真。您的猜测是正确的,实际上是按照POSIX标准:“管道或FIFO特殊文件的S_ISFIFO(m)测试”()