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