[2712] in linux-net channel archive

home help back first fref pref prev next nref lref last post

tcp.c, FIONREAD bug?

daemon@ATHENA.MIT.EDU (Stefan Magdalinski)
Mon Apr 29 03:43:58 1996

Date: 	Mon, 29 Apr 1996 00:38:24 +0100 (BST)
From: Stefan Magdalinski <stefan@iandi.demon.co.uk>
To: "'LINUX-NET@vger.rutgers.edu'" <LINUX-NET@vger.rutgers.edu>



Hi, I'm way out of my depth with low-level tcp stuff, but I have to 
enquire about this. I've lurked for a while to see if anything pased 
about this. It appears, and Randy Chapman (the guy porting Sun's JDK 
to Linux) suggested this, that there's a bug in tcp.c, or at least 
something that hasn't been implemented yet. 

I've written a Java application that uses 
TCP sockets, and intermittently checks to see if data is waiting by using 
a call to available() in the Java.net library. available is purported to 
return the number of bytes available to be read on that particular 
socket, which indeed it does, on Solaris, and nearly under linux. 
However, under linux (1.2.13, thru 1.3.91),  available seems to exhibit 
the following behaviour:
As soon as the value of available() becomes non-zero (i.e. some data is 
on the socket), that value sticks, even if more data piles up, until at 
least one call to read() has been performed on the socket. As an example 
execution (each line represents the state at a call to available.
bytes on socket		available() returns
0				0
0				0
5				5
8				5 //should be 8
  
Now, available is (according to Randy) a wrapper for the FIONREAD ioctl, 
the code for which looks like this (from tcp.c)
---------------------------------------
                case TIOCINQ:
#ifdef FIXME    /* FIXME: */
                case FIONREAD:
#endif
                {
                        unsigned long amount;

                        if (sk->state == TCP_LISTEN)
                                return(-EINVAL);

                        lock_sock(sk);
                        amount = tcp_readable(sk);
                        release_sock(sk);
                        err=verify_area(VERIFY_WRITE,(void *)arg, 
sizeof(int));
                        if(err)
                                return err;
                        put_user(amount, (int *)arg);
                        return(0);
                }                                                  
----------------------------
I don't understand this, but the #define FIXME raises my suspicions.

Any ideas/comments?
I'd like to try and fix it myself, but I need a pointer or two in the 
right direction.

*////////////////////////*
Stefan Magdalinski
I&I
stefan@iandi.demon.co.uk
*\\\\\\\\\\\\\\\\\\\\\\\\*





home help back first fref pref prev next nref lref last post