Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

readline.c

Go to the documentation of this file.
00001 /************************************************************************
00002 * File: recvline.c
00003 * Purpose: Provides a C file for the readn function from
00004 * the book Advanced Programming in the UNIX Environment  by Richard Stevens.
00005 * The readn function calls the read function repeatedly until n bytes
00006 * have been read from the file descriptor.
00007 *************************************************************************/
00008 
00009 /* This is neccessary to avoid muliple definitions of fd_set, etc when both
00010 * PCNFS and Windows Sockets are to be available. */
00011 #ifdef USE_PCNFS
00012 #undef USE_PCNFS
00013 #endif
00014 
00015 #include "rcs_defs.hh"          /* _Windows */
00016 
00017 #include "readn.h"              /* readn(int, void *, int, double) */
00018 #ifndef _Windows
00019 #include <unistd.h>             /* read(), select() */
00020 #include <sys/types.h>          /* typedef fd_set, FD_ZERO, FD_SET */
00021 #ifdef VXWORKS
00022 #include <sys/times.h>          /* struct timeval */
00023 #else
00024 #include <sys/time.h>           /* struct timeval */
00025 #endif
00026 #else
00027 #include <io.h>                 /* read() */
00028 #ifdef USE_OLD_WINSOCK
00029 #include <winsock.h>            /* select(), typedef fd_set, FD_ZERO, FD_SET, struct */
00030 #else
00031 #include <winsock2.h>
00032 #endif
00033                                         /* struct timeval */
00034 #endif
00035 #include <stddef.h>             /* size_t */
00036 #include <errno.h>              /* errno */
00037 #include <string.h>             /* strerror() */
00038 #include <math.h>               /* modf() */
00039 #include "rcs_prnt.hh"          /* rcs_print_error() */
00040 #include "sokintrf.h"           /* dl_select() */
00041 
00042 /* Read "n" bytes from a descriptor. */
00043 int
00044 readn (int fd, void *vptr, int n, double _timeout)
00045 {
00046   int nleft, nread;
00047   char *ptr;
00048   double int_part;
00049   struct timeval timeout_tv;
00050   fd_set read_fd_set;
00051   timeout_tv.tv_sec = (long) _timeout;
00052   timeout_timeval.tv_usec = (long) (_timeout * 1000000.0);
00053   if (timeout_timeval.tv_usec >= 1000000)
00054     {
00055       timeout_timeval.tv_usec = timeout_timeval.tv_usec % 1000000;
00056     }
00057   FD_ZERO (&read_fd_set);
00058   RCS_FD_SET (fd, &read_fd_set);
00059 
00060 
00061   ptr = (char *) vptr;
00062   nleft = n;
00063   while (nleft > 0)
00064     {
00065       if (_timeout > 0.0)
00066         {
00067           switch (dl_select
00068                   (fd + 1, &read_fd_set, (fd_set *) NULL, (fd_set *) NULL,
00069                    &timeout_tv))
00070             {
00071             case -1:
00072               rcs_print_error ("Error in select: %d -> %s\n", errno,
00073                                strerror (errno));
00074               return -1;
00075 
00076             case 0:
00077               rcs_print_error ("Read timed out.\n");
00078               return -1;
00079 
00080             default:
00081               break;
00082             }
00083         }
00084       if ((nread = read (fd, ptr, nleft)) == -1)
00085         {
00086           rcs_print_error ("Read error: %d = %s\n", errno, strerror (errno));
00087           return (-1);          /* error, return < 0 */
00088         }
00089       else if (nread == 0)
00090         {
00091           rcs_print_error ("readn: Premature EOF recieved.\n");
00092           return (-1);
00093         }
00094 
00095       nleft -= nread;
00096       ptr += nread;
00097     }
00098   return (n - nleft);           /* return >= 0 */
00099 }

Generated on Sun Dec 2 15:56:51 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001