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

writen.c

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

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