This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 73c14db2052dad87585396159f8ffb724698d0a4 Author: Marco Casaroli <[email protected]> AuthorDate: Thu Oct 29 19:58:17 2026 +0100 fs/vfs: Fail lseek() of a pipe, a FIFO or a socket with ESPIPE. The pipe, FIFO and socket drivers have no seek method, so lseek() set the common file position and returned it: lseek(fd, 10, SEEK_CUR) of a pipe returned 10, and SEEK_END failed with ENOSYS. POSIX specifies ESPIPE for a pipe, a FIFO or a socket. A program that skips data in a stream with lseek() and reads it only when lseek() fails took the skip for done and lost the data. Return -ESPIPE for these inodes (INODE_IS_NOSEEK()) before the seek method or the common file position. pread(), pwrite() and sendfile() with an offset then also fail with ESPIPE for them, as POSIX and Linux specify. The sendfile() path of a TCP socket (CONFIG_NET_SENDFILE) seeks its input to send data again. For an input that cannot seek, sendfile() does not use that path: it uses the read and write copy. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- fs/vfs/fs_lseek.c | 11 +++++++++++ fs/vfs/fs_sendfile.c | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/fs/vfs/fs_lseek.c b/fs/vfs/fs_lseek.c index 2d1ceeb549b..0b6061e35bf 100644 --- a/fs/vfs/fs_lseek.c +++ b/fs/vfs/fs_lseek.c @@ -64,6 +64,17 @@ off_t file_seek(FAR struct file *filep, off_t offset, int whence) DEBUGASSERT(filep); inode = filep->f_inode; + /* A pipe, a FIFO or a socket has no file position (POSIX: ESPIPE). + * Without this, the common file position below took any offset, and a + * program that skips data with lseek() and reads only when it fails + * lost the data. + */ + + if (inode != NULL && INODE_IS_NOSEEK(inode)) + { + return -ESPIPE; + } + /* Invoke the file seek method if available */ if (inode && inode->u.i_ops && inode->u.i_ops->seek) diff --git a/fs/vfs/fs_sendfile.c b/fs/vfs/fs_sendfile.c index ea14c03dbda..397d0341afd 100644 --- a/fs/vfs/fs_sendfile.c +++ b/fs/vfs/fs_sendfile.c @@ -264,7 +264,12 @@ ssize_t file_sendfile(FAR struct file *outfile, FAR struct file *infile, FAR struct socket *psock; psock = file_socket(outfile); - if (psock != NULL) + + /* psock_sendfile() seeks the input to send its data again: an input that + * cannot seek (a pipe, a FIFO or a socket) uses the slow path. + */ + + if (psock != NULL && !INODE_IS_NOSEEK(infile->f_inode)) { /* Then let psock_sendfile do the work. */
