[PATCH] Re: fstat issues

GOTO Masanori (gotom@debian.org)
Sat, 12 Jan 2002 17:01:24 +0900


Hi,

I noticed the following issue posted one month ago that this is
related with pipe implementation. Currently linux uses
inode->i_pipe->len to keep length of pipe data, but if you want to
detect the size of current pipe length, we cannot get any method. I
think to keep compatibility using fstat like SysV is useful for some
applications.

I made the below patch which is cleanly applied for both 2.4.18-pre3
and 2.5.2-pre11. This patch simply substitutes i_pipe->len for
inode->i_size. To replace PIPE_LEN using inode->i_size instead of
inode->i_pipe->len is another way but I don't do that.

--- fs/pipe.c.vanilla Wed Jan 2 04:20:01 2002
+++ fs/pipe.c Fri Jan 4 02:34:55 2002
@@ -21,6 +21,9 @@
*
* Reads with count = 0 should always return 0.
* -- Julian Bradfield 1999-06-07.
+ *
+ * Substitute inode->i_size to follow SysV compatibility.
+ * -- GOTO Masanori 2002-01-12.
*/

/* Drop the inode semaphore and wait for a pipe event, atomically */
@@ -101,6 +104,7 @@
PIPE_START(*inode) += chars;
PIPE_START(*inode) &= (PIPE_SIZE - 1);
PIPE_LEN(*inode) -= chars;
+ inode->i_size = PIPE_LEN(*inode);
count -= chars;
buf += chars;
}
@@ -197,6 +201,7 @@

written += chars;
PIPE_LEN(*inode) += chars;
+ inode->i_size = PIPE_LEN(*inode);
count -= chars;
buf += chars;
space = PIPE_FREE(*inode);
@@ -454,7 +459,7 @@

init_waitqueue_head(PIPE_WAIT(*inode));
PIPE_BASE(*inode) = (char*) page;
- PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
+ PIPE_START(*inode) = PIPE_LEN(*inode) = inode->i_size = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
PIPE_WAITING_READERS(*inode) = PIPE_WAITING_WRITERS(*inode) = 0;
PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1;

Regards,
-- gotom

At Sat, 8 Dec 2001 13:17:04 -0500,
James Moss <moss@brutesquad.org> wrote:
> I noticed recently that the following no longer works. I was wondering if
> this is internal to the kernel or if perhaps this is a glibc issue. Also
> wondering if this was an intential change. It did 'used to work' but I
> realize that may hold little to no ground since it does seem to be on a per
> implementation basis. Anyway looking forward to hearing back, feel free to
> show a better way to go about doing what I'm attempting to do.
> -James Moss
>
> -------foo.c------------
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/file.h>
> #include <sys/stat.h>
> #include <sys/errno.h>
> #include <fcntl.h>
>
> main(argc, argv)
> int argc;
> char **argv;
> {
> struct stat sb;
> if (0 == fstat( fileno(stdin), &sb )) {
> printf( "size %d\n", sb.st_size );
> } else {
> printf( "size %d\n", sb.st_size );
> }
> exit( 0 );
> }
>
> -------------------
>
> On HP, Solaris, etc...
> cc foo.c
> echo "abc" > ftext.txt
> ./a.out < ftext.txt
> size 4
> cat ftext.txt | ./a.out
> size 4
>
> On Debian Unstable, latest release of Suse, and latest release of Redhat...
> gcc foo.c
> echo "abc" > ftext.txt
> ./a.out < ftext.txt
> size 4
> cat ftext.txt | ./a.out
> size 0
>
> Page 90, 4.12 "File Size"
> Advanced Programming in the UNIX Environment states that it's posix compliant
> in SVR4 to have the ability to read file size from a pipe and the st_size of
> the sb struct is defined.... does Linux break SVR4 compliance? Is there a
> better or new way to do this?
>
> SVID Vol: 1a Version 4
>
> Since a pipe is bi-directional, there are two separate flows of data.
> Therefore, the size (st_size) returned by a call to fstat with argument
> fildes[0] or fildes[1] is the number of bytes available for reading from
> fildes[0] or fildes[1] respectively.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/