I have to start off with an apology.  Over a year ago, I submitted a
READ_DATA_PENDING patch to use __fpending() [ruby-core:3766].  I then
failed to notice the discussion starting at [ruby-core:3785], and even
failed to notice later that my patch had been backed out.  Guy Decoux
was completely correct: __fpending() only works for output streams!

So, sorry to anyone whose time was wasted either by my broken patch or
by the fact that I didn't follow up and come up with a correct version
sooner (i.e. anyone who tried to compile 64-bit on Solaris in the last
year).  I'm only figuring this out now due to [ruby-talk:153006].

Here's something that actually works (for me):


--- io.c.orig       2006-01-05 16:12:19.634441000 -0800
+++ io.c        2006-01-05 11:15:50.907474000 -0800
@@ -156,6 +156,19 @@
 #  define READ_DATA_PENDING_COUNT(fp) ((unsigned int)(*(fp))->_cnt)
 #  define READ_DATA_PENDING(fp)       (((unsigned int)(*(fp))->_cnt) > 0)
 #  define READ_DATA_BUFFERED(fp) 0
+#elif defined(__sparc) && defined(_LP64) && defined(__SVR4)
+typedef struct _FILE64 {
+  unsigned char        *_ptr;  /* next character from/to here in buffer */
+  unsigned char        *_base; /* the buffer */
+  unsigned char        *_end;  /* the end of the buffer */
+  ssize_t      _cnt;   /* number of available characters in buffer */
+  int          _file;  /* UNIX System file descriptor */
+  unsigned int _flag;  /* the state of the stream */
+  char         __fill[80];     /* filler to bring size to 128 bytes */
+} FILE64;
+#  define READ_DATA_PENDING(fp) (((FILE64*)(fp))->_cnt > 0)
+#  define READ_DATA_PENDING_COUNT(fp) (((FILE64*)(fp))->_cnt)
+#  define READ_DATA_PENDING_PTR(fp) ((char *)((FILE64*)(fp))->_ptr)
 #else
 /* requires systems own version of the ReadDataPending() */
 extern int ReadDataPending();


It's not very nice, but Solaris doesn't provide anything like
__fpending() for reads.  Thankfully, they do now provide the Solaris
source, so we can get the struct from the internal header[1].

Without this patch, DRb tests hang forever, and many other tests
fail.  With it:

% gmake check
test succeeded
[...]
1224 tests, 13482 assertions, 0 failures, 0 errors

(Yay!)

I get the same result using Sun C 5.6 2004/07/15 with
-xtarget=ultrasparc3cu -xarch=v9a and GCC 3.4.3 with -mcpu=ultrasparc3
-m64.  This is Solaris 8/SPARC.

I also checked just READ_DATA_PENDING_COUNT against the regular
FILE_COUNT version for the 32-bit case using a simple C program.

Hopefully, this or something like it can find its way in.  In the
meantime, please test this if you have access to Solaris!

Steve

[1] http://cvs.opensolaris.org/source/xref/on/usr/src/lib/libc/inc/file64.h