diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 0f3e3a93f0b0..e3393f3b3dfd 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -137,7 +137,7 @@ pread(td, uap) if ((error = fget_read(td, uap->fd, &fp)) != 0) return (error); - if (fp->f_type != DTYPE_VNODE) { + if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) { error = ESPIPE; } else { error = dofileread(td, fp, uap->fd, uap->buf, uap->nbyte, @@ -360,11 +360,11 @@ pwrite(td, uap) int error; if ((error = fget_write(td, uap->fd, &fp)) == 0) { - if (fp->f_type == DTYPE_VNODE) { + if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) { + error = ESPIPE; + } else { error = dofilewrite(td, fp, uap->fd, uap->buf, uap->nbyte, uap->offset, FOF_OFFSET); - } else { - error = ESPIPE; } fdrop(fp, td); } else { diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 2d123efad751..6d42736479d3 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -1341,7 +1341,7 @@ lseek(td, uap) if ((error = fget(td, uap->fd, &fp)) != 0) return (error); - if (fp->f_type != DTYPE_VNODE) { + if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) { fdrop(fp, td); return (ESPIPE); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 2d123efad751..6d42736479d3 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1341,7 +1341,7 @@ lseek(td, uap) if ((error = fget(td, uap->fd, &fp)) != 0) return (error); - if (fp->f_type != DTYPE_VNODE) { + if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) { fdrop(fp, td); return (ESPIPE); } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 51cd23199226..786fad150185 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -80,7 +80,7 @@ struct fileops vnops = { .fo_kqfilter = vn_kqfilter, .fo_stat = vn_statfile, .fo_close = vn_closefile, - .fo_flags = DFLAG_PASSABLE + .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE }; int diff --git a/sys/sys/file.h b/sys/sys/file.h index bcc418ea2639..17bdc81d744c 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -94,6 +94,7 @@ struct fileops { }; #define DFLAG_PASSABLE 0x01 /* may be passed via unix sockets. */ +#define DFLAG_SEEKABLE 0x02 /* seekable / nonsequential */ /* * Kernel descriptor table.