andreas@hpcvlx.cv.hp.com (Jim Andreas) (02/20/90)
> > I am using X11R4 on our HP 9000/800 with HP-UX 3.1, I am very pleased > everything works perfect, except for the new xmh. I keep getting core > dumps from xmh at the most ill suited moments. As far as I can tell > the problems comes from the following lines taken from the file > command.c. > > > static /*void*/ > CheckReadFromPipe( fd, bufP, lenP ) > int fd; > char **bufP; > int *lenP; > { > long nread; > if (ioctl( fd, FIONREAD, &nread ) /*failed*/) { > SystemError( "couldn't inquire bytes in pipe" ); > } > > > The value returned by the FIONREAD ioctl is sometimes negative and > this causes bad problems later in the routine and finally a coredump > from bcopy(). Sorry but the word from the folks who know is that FIONREAD is broken when applied to pipes in HP-UX. This will be fixed in a release to follow HP-UX 7.0. > I have not been able to find any documentation on the FIONREAD ioctl > at all, so I can not verify the use of it at all. The documentation is cleverly hidden in termio(5), to wit (for those individuals with a desire to know): FIONNREAD Returns in the long integer referenced by arg the number of characters immediately readable from the terminal device file. This command is allowed from a background process; however, the data itself cannot be read from a background process. > > Does anyone have any suggestions or ideas. > Thanks in advance. > > -- > > Arne Lundberg > > European Space Technology Centre, Noordwijk, the Netherlands > arne@yc.estec.nl or ALUNDBER@ESTEC.BITNET > Phone: +31 1719 84865, Fax: +31 1719 12142, Telex: 39098 > ---------- I have attached a work-around code fragment. Replace the CheckReadFromPipe() function in your MIT X11R4 xmh command.c file with the following. The ugly loop at the front inside the #ifdef hpux section puts the pipe into a "O_NDELAY" mode and reads bytes out one-by-one. ----------------------------------------------------------------------- Jim Andreas | andreas@cv.hp.com | INTERNET Hewlett-Packard Company | {backbone}!hplabs!hp-pcd!andreas | UUCP 1000 N.E. Circle | (USA) (503) 750-2860 | VOICE Corvallis, OR 97330 | (USA) (503) 750-3788 | FAX ----------------------------------------------------------------------- This response does not represent the official position of, or statement by, the Hewlett-Packard Company. The above data is provided for informational purposes only. It is supplied without warranty of any kind. ----------------------------------------------------------------------- static /*void*/ CheckReadFromPipe( fd, bufP, lenP ) int fd; char **bufP; int *lenP; { #ifdef hpux int oldflags; int newflags; char c; /* * The FIONREAD ioctl is broken on HP-UX, so substitute * the following workaround. This code sets the O_NDELAY * mode on the pipe, so that we can read from it without * blocking. The code then reads bytes from the pipe * until the read returns with zero bytes. */ if (( oldflags = fcntl( fd, F_GETFL, 0 )) < 0 ) SystemError( "CheckReadFromPipe: error on fcntl F_GETFL" ); newflags = oldflags | O_NDELAY; if ( fcntl( fd, F_SETFL, newflags ) < 0 ) SystemError( "CheckReadFromPipe: error on fcntl F_SETFL" ); if (read( fd, &c, 1 ) == 1 ) { char * pChar; int ByteCount = 1; int old_len = *lenP; *bufP = XtRealloc( *bufP, (Cardinal) ((*lenP += BUFSIZ) + 1) ); pChar = *bufP + old_len; *pChar++ = c; for ( ;; ) { int RetCode; if (( RetCode = read( fd, &c, 1 )) == 0 ) { *pChar = '\0'; break; } if ( RetCode < 0 ) { SystemError( "CheckReadFromPipe: error on read from pipe" ); *pChar = '\0'; break; } if ( ByteCount == BUFSIZ ) { old_len = *lenP; *bufP = XtRealloc( *bufP, (Cardinal) ((*lenP += BUFSIZ) + 1) ); ByteCount = 0; pChar = *bufP + old_len; } *pChar++ = c; ByteCount++; } } if ( fcntl( fd, F_SETFL, oldflags ) < 0 ) SystemError( "CheckReadFromPipe: error on fcntl F_SETFL" ); #else /* hpux */ long nread; if (ioctl( fd, FIONREAD, &nread ) /*failed*/) { SystemError( "couldn't inquire bytes in pipe" ); } else if (nread) { char buf[BUFSIZ]; int old_end = *lenP; *bufP = XtRealloc( *bufP, (Cardinal) ((*lenP += nread) + 1) ); while (nread > BUFSIZ) { read( fd, buf, BUFSIZ ); bcopy( buf, *bufP+old_end, BUFSIZ ); nread -= BUFSIZ; old_end += BUFSIZ; } read( fd, buf, (int) nread ); bcopy( buf, *bufP+old_end, (int) nread ); (*bufP)[old_end+nread] = '\0'; } #endif /* hpux */ }