stderr is seekable? (lseek(2))
Bruce Evans
bde at zeta.org.au
Tue Sep 14 03:39:15 PDT 2004
On Tue, 14 Sep 2004, Jun Kuriyama wrote:
>
> When I tested this program, it finished successfully. But on Linux,
> lseek(2) returns -1 and errno is ESPIPE.
>
> I expected to be returned ESPIPE as Linux did. Is our behavior
> correct, or there is something wrong?
FreeBSD's behaviour is wrong for at least named pipes. lseek() on
named pipes was fixed in rev.1.52 of vfs_syscalls.c, but was broken
in rev.1.319 of vfs_syscalls.c and rev.1.123 of sys_generic.c. The
DFLAG_SEEKABLE flag added in rev.1.188 of vfs_vnops.c doesn't work,
since the fileops table for named pipes is the same as for vnodes.
% Index: vfs_syscalls.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
% retrieving revision 1.51
% retrieving revision 1.52
% diff -u -2 -r1.51 -r1.52
% --- vfs_syscalls.c 19 Sep 1996 18:20:27 -0000 1.51
% +++ vfs_syscalls.c 19 Dec 1996 19:41:36 -0000 1.52
% @@ -37,5 +37,5 @@
% *
% * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
% - * $Id: vfs_syscalls.c,v 1.50 1996/09/03 14:21:53 bde Exp $
% + * $Id: vfs_syscalls.c,v 1.51 1996/09/19 18:20:27 nate Exp $
% */
%
% @@ -699,7 +699,7 @@
% p->p_dupfd = 0;
% vp = nd.ni_vp;
% -
% +
% fp->f_flag = flags & FMASK;
% - fp->f_type = DTYPE_VNODE;
% + fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE);
% fp->f_ops = &vnops;
% fp->f_data = (caddr_t)vp;
% @@ -2347,5 +2347,5 @@
% (fp = fdp->fd_ofiles[fd]) == NULL)
% return (EBADF);
% - if (fp->f_type != DTYPE_VNODE)
% + if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO)
% return (EINVAL);
% *fpp = fp;
% Index: vfs_syscalls.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
% retrieving revision 1.318
% retrieving revision 1.319
% diff -u -2 -r1.318 -r1.319
% --- vfs_syscalls.c 11 Jun 2003 00:56:59 -0000 1.318
% +++ vfs_syscalls.c 18 Jun 2003 19:53:59 -0000 1.319
% @@ -40,5 +40,5 @@
%
% #include <sys/cdefs.h>
% -__FBSDID("$FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.318 2003/06/11 00:56:59 obrien Exp $");
% +__FBSDID("$FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.319 2003/06/18 19:53:59 phk Exp $");
%
% /* For 4.3 integer FS ID compatibility */
% @@ -1342,5 +1342,5 @@
% 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);
% Index: vfs_vnops.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/kern/vfs_vnops.c,v
% retrieving revision 1.187
% retrieving revision 1.188
% diff -u -2 -r1.187 -r1.188
% --- vfs_vnops.c 18 Jun 2003 18:16:39 -0000 1.187
% +++ vfs_vnops.c 18 Jun 2003 19:53:59 -0000 1.188
% @@ -40,5 +40,5 @@
%
% #include <sys/cdefs.h>
% -__FBSDID("$FreeBSD: src/sys/kern/vfs_vnops.c,v 1.187 2003/06/18 18:16:39 phk Exp $");
% +__FBSDID("$FreeBSD: src/sys/kern/vfs_vnops.c,v 1.188 2003/06/18 19:53:59 phk Exp $");
%
% #include "opt_mac.h"
% @@ -81,5 +81,5 @@
% .fo_stat = vn_statfile,
% .fo_close = vn_closefile,
% - .fo_flags = DFLAG_PASSABLE
% + .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
% };
%
% Index: sys_generic.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/kern/sys_generic.c,v
% retrieving revision 1.122
% retrieving revision 1.123
% diff -u -2 -r1.122 -r1.123
% --- sys_generic.c 11 Jun 2003 00:56:57 -0000 1.122
% +++ sys_generic.c 18 Jun 2003 19:53:59 -0000 1.123
% @@ -40,5 +40,5 @@
%
% #include <sys/cdefs.h>
% -__FBSDID("$FreeBSD: src/sys/kern/sys_generic.c,v 1.122 2003/06/11 00:56:57 obrien Exp $");
% +__FBSDID("$FreeBSD: src/sys/kern/sys_generic.c,v 1.123 2003/06/18 19:53:59 phk Exp $");
%
% #include "opt_ktrace.h"
% @@ -138,5 +138,5 @@
% 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 {
% @@ -361,9 +361,9 @@
%
% 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);
%
Bruce
More information about the freebsd-arch
mailing list