irix porting problem

Gilles Zunino Gilles.Zunino@hei.fupl.asso.fr
Thu Jul 1 09:47:00 GMT 1999


jmc@cmpharm.ucsf.edu wrote:
 
> [..] available() method for a FileInputStream is always zero. [..]

>From the Unix FAQ : 

% ------------------------- Begin FAQ snippet ------------------
4.2)  How do I check to see if there are characters to be read
without actually reading?
                   
Certain versions of UNIX provide ways to check whether characters      
are currently available to be read from a file descriptor.  In      
BSD, you can use select(2).  You can also use the FIONREAD ioctl,     
which returns the number of characters waiting to be read, but       
only works on terminals, pipes and sockets.  In System V Release      
3, you can use poll(2), but that only works on streams.
In Xenix  - and therefore Unix SysV r3.2 and later - the rdchk()
system call reports whether a read() call on a given file descriptor
will block. 
                   
There is no way to check whether characters are available to be      
read from a FILE pointer.  (You could poke around inside stdio       
data structures to see if the input buffer is nonempty, but that       
wouldn't work since you'd have no way of knowing what will happen     
the next time you try to fill the buffer.)
% ------------------------- Begin FAQ snippet ------------------

So, I understand that FIONREAD does not work for files
at least for regular files (i.e. your test case) on some Unixes. 
Fixing the bug under IRIX maybe done by first fstat()ing the file 
descriptor to know if it is a socket, pipe, terminal of regular
file. If it is a regular file, maybe can we lseek() to get the
remaining bytes to be red.

Here is a modified version of your code that implements the previous
(primitive) algorithm. This code is not perfect (especially for
the regular file case) since I'm calling lseek() three times which
can decrease performances. Any comments/suggestions or solutions are
welcomme !

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#include <stropts.h>

int main(int argc, char **argv) {
    int fd;
    int rv;
    size_t num;
    struct stat st;
    

    fd = open(argv[1],O_RDONLY);  /* O_NDELAY also? no change in result.
*/
    if (fd== -1)
      {
	perror("fd open()");
	exit(1);
      }

    /* Test if the fd points to regular file or socket, pipe, terminal
*/
    if (fstat(fd,&st) == -1)
      {
	perror("fd fstat()");
	exit(1);
      }

    if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))
      {
	off_t pos,pos2;

	/* Regular file */
	pos = lseek(fd,0,SEEK_CUR);
	if (pos == -1)
	  {
	    perror("fd lseek()");
	    exit(1);
	  }
	
	pos2 = lseek(fd,0,SEEK_END);
	if (pos2 == -1)
	  {
	    perror("fd lseek()");
	    exit(1);
	  }

	/* Reset to correct pos */
	pos = lseek(fd,pos,SEEK_SET);
	if (pos == -1)
	  {
	    perror("fd lseek()");
	    exit(1);
	  }
	
	printf("pos2 - pos is %d\n",pos2 - pos);
      }
    else
      {
	/* ioctl call will work */
	rv = ioctl(fd,FIONREAD,&num);
	printf("rv is %d; num is %ld\n",rv,num);
      }

    close(fd);
}
_________________________________________________________________
Gilles Zunino - (Gilles.Zunino@hei.fupl.asso.fr)   (A 506)  7636

HEI, 13 rue de Toul, 59 046 LILLE CEDEX FRANCE
Phone : (+33) 3 28.38.48.58  Fax : (+33) 3 28.38.48.04


More information about the Java mailing list