Determining whether a readable file descriptor is the read end of a pipe
Asked Answered
W

2

8

I would like to use splice to zero-copy data from STDIN_FILENO to a file descriptor (which could be to a regular file, char or block device, FIFO, or anything that can be opened with open). In order to use splice, either the from file descriptor or to file descriptor must be the appropriate end of a pipe, so generally a pipe is created to serve as an intermediary buffer when the programmer wants to zero-copy data from non-pipe to non-pipe. However, if STDIN_FILENO is already the read end of a pipe, then I could skip that step and attempt to splice directly from STDIN_FILENO to the other file descriptor. Therefore, I would like to be able to determine whether STDIN_FILENO is the read end of a pipe.

Is there a Linux system call that can determine whether STDIN_FILENO is the read end of a pipe?

Whelp answered 3/9, 2010 at 20:44 Comment(0)
A
9

To get information about an open fd, you can use fstat(). I'd guess that st_mode of the result should be S_IFIFO for a pipe. Alternatively, /proc/self/fd/ and /proc/self/fdinfo/ also provide some information about a file descriptor. Keep in mind that /proc is linux-specific.

However, I think it might be easier to just try to use splice() first and if it fails (with EINVAL?) fall back to your magic.

Ale answered 3/9, 2010 at 22:38 Comment(1)
I coded up a test program that created a pipe, called fstat, and tested S_ISFIFO: pastebin.com/ntauU2b5 . The result is that S_ISFIFO on the st_mode for the read end of a pipe is TRUE. Your guess is correct, and it is actually per the POSIX standard: "S_ISFIFO(m) Test for a pipe or FIFO special file" (opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html)Whelp
R
2

As an alternative, lseek() will fail with ESPIPE if "fd is associated with a pipe, socket, or FIFO." So a no-op lseek(fd, 0, SEEK_CUR) will tell you if the file descriptor is any of these.

In my situation, this covers all of the cases I was interested in.

Restate answered 27/2, 2015 at 21:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.