Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!mips!sgi!rpw3@rigden.wpd.sgi.com From: rpw3@rigden.wpd.sgi.com (Rob Warnock) Newsgroups: comp.sys.sgi Subject: Re: ioctl Message-ID: <105737@sgi.sgi.com> Date: 23 May 91 03:48:46 GMT References: <1991May21.224750.535@murdoch.acc.Virginia.EDU> <1991May22.143844.6858@cs.dal.ca> <1991May22.161432.25064@murdoch.acc.Virginia.EDU> Sender: guest@sgi.sgi.com Reply-To: rpw3@sgi.com (Rob Warnock) Organization: Silicon Graphics, Inc., Mountain View, CA Lines: 96 In article <1991May22.161432.25064@murdoch.acc.Virginia.EDU> acl3k@jade.cs.Virginia.EDU (Allan Christian Long) writes: +--------------- | The problem is that the prototype for ioctl is | int ioctl (int fildes, int request, ...); | That says what the first and second parameters should be, but I need to | find out about the rest, which are dependent upon what request is. The | entry for FIONREAD in ioctl.h is | #define FIONREAD _IOR(f, 127, int) /* get # bytes to read */ | I tried changing charToRead to an int, but that didn't help. I need | documentation for FIONREAD, more than what it says in the header file. +--------------- The third arg for FIONREAD is the *address* of an integer, that is: int num_bytes_avail_to_read; err = ioctl(file_descriptor, FIONREAD, &num_bytes_avail_to_read); Note that the number of bytes actually avilable to read without blocking may change (increase) between the time you do the FIONREAD and the time you actually do the read(). For this reason, I never use the return value (in "num_bytes_avail_to_read", above) for anything but a binary flag to say there's something available to read without blocking. I do the read full-sized and use the return value from the read() to say how much was actually there: int n; char buf[BUFSIZ]; /* or whatever size */ if (ioctl(s, FIONREAD, &n) < 0) { /* "s" is the file descriptor */ ...handle error... } if (n > 0) { n = read(s, buf, sizeof buf); if (n < 0) { ...handle error... } ... } If this is all you are using FIONREAD for, you can alternatively use select(2), though a bit more awkwardly: #include #include fdset in_set; struct timeval t0; int err; t0.tv_sec = 0; t0.tv_usec = 0; FD_ZERO(&in_set); FD_SET(s, &in_set); err = select(s + 1, &in_set, (fd_set *)0, (fd_set *)0, &t0); if (err < 0) { ...handle error... } if (FD_ISSET(s, &in_set)) { n = read(s, buf, sizeof buf); if (n < 0) { ...handle error... } ... } Of course, if there is only one file descriptor being polled, as in the example above, the return value from the select() can be checked (err > 0) instead of the FD_ISSET(). But using FD_ISSET() generalizes nicely to multiple-channel polls: err = select(...) if (err < 0) { ...handle error... } if (err > 0) { /* SOME channel is ready */ if (FD_ISSET(fd1, &in_set)) { n = read(fd1, ...); ... } if (FD_ISSET(fd2, &in_set)) { n = read(fd2, ...); ... } ...and so on... } -Rob ----- Rob Warnock, MS-1L/515 rpw3@sgi.com rpw3@pei.com Silicon Graphics, Inc. (415)335-1673 Protocol Engines, Inc. 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311