1 /* $NetBSD: peekfd.c,v 1.2 2017/02/14 01:16:49 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* peekfd 3 6 /* SUMMARY 7 /* determine amount of data ready to read 8 /* SYNOPSIS 9 /* #include <iostuff.h> 10 /* 11 /* ssize_t peekfd(fd) 12 /* int fd; 13 /* DESCRIPTION 14 /* peekfd() attempts to find out how many bytes are available to 15 /* be read from the named file descriptor. The result value is 16 /* the number of available bytes. 17 /* DIAGNOSTICS 18 /* peekfd() returns -1 in case of trouble. The global \fIerrno\fR 19 /* variable reflects the nature of the problem. 20 /* BUGS 21 /* On some systems, non-blocking read() may fail even after a 22 /* positive return from peekfd(). The smtp-sink program works 23 /* around this by using the readable() function instead. 24 /* LICENSE 25 /* .ad 26 /* .fi 27 /* The Secure Mailer license must be distributed with this software. 28 /* AUTHOR(S) 29 /* Wietse Venema 30 /* IBM T.J. Watson Research 31 /* P.O. Box 704 32 /* Yorktown Heights, NY 10598, USA 33 /*--*/ 34 35 /* System library. */ 36 37 #include <sys_defs.h> 38 #include <sys/ioctl.h> 39 #ifdef FIONREAD_IN_SYS_FILIO_H 40 #include <sys/filio.h> 41 #endif 42 #ifdef FIONREAD_IN_TERMIOS_H 43 #include <termios.h> 44 #endif 45 #include <unistd.h> 46 47 #ifndef SHUT_RDWR 48 #define SHUT_RDWR 2 49 #endif 50 51 /* Utility library. */ 52 53 #include "iostuff.h" 54 55 /* peekfd - return amount of data ready to read */ 56 57 ssize_t peekfd(int fd) 58 { 59 60 /* 61 * Anticipate a series of system-dependent code fragments. 62 */ 63 #ifdef FIONREAD 64 int count; 65 66 #ifdef SUNOS5 67 68 /* 69 * With Solaris10, write_wait() hangs in poll() until timeout, when 70 * invoked after peekfd() has received an ECONNRESET error indication. 71 * This happens when a client sends QUIT and closes the connection 72 * immediately. 73 */ 74 if (ioctl(fd, FIONREAD, (char *) &count) < 0) { 75 (void) shutdown(fd, SHUT_RDWR); 76 return (-1); 77 } else { 78 return (count); 79 } 80 #else /* SUNOS5 */ 81 return (ioctl(fd, FIONREAD, (char *) &count) < 0 ? -1 : count); 82 #endif /* SUNOS5 */ 83 #else 84 #error "don't know how to look ahead" 85 #endif 86 } 87