home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / libncftp / libncftp-3.2.5-src.zip / libncftp-3.2.5 / sio / SRead.c < prev    next >
C/C++ Source or Header  |  2010-10-30  |  4KB  |  138 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. static const char UNUSED(gSioVersion[]) = kSioVersion;
  7. static const char UNUSED(gCopyright[]) = "@(#) libsio Copyright 1992-2011, by Mike Gleason.  All rights reserved.";
  8.  
  9.  
  10. /* Read up to "size" bytes on sfd before "tlen" seconds.
  11.  *
  12.  * If "retry" is on, after a successful read of less than "size"
  13.  * bytes, it will attempt to read more, upto "size."
  14.  *
  15.  * If the timer elapses and one or more bytes were read, it returns
  16.  * that number, otherwise a timeout error is returned.
  17.  *
  18.  * Although "retry" would seem to indicate you may want to always
  19.  * read "size" bytes or else it is an error, even with that on you
  20.  * may get back a value < size.  Set "retry" to 0 when you want to
  21.  * return as soon as there is a chunk of data whose size is <= "size".
  22.  */
  23.  
  24. int
  25. SRead(int sfd, char *const buf0, size_t size, int tlen, int retry)
  26. {
  27.     read_return_t nread;
  28.     read_size_t nleft;
  29.     char *buf = buf0;
  30.     int tleft;
  31.     time_t done, now;
  32.     fd_set ss;
  33.     struct timeval tv;
  34.     int result, firstRead;
  35.     DECL_SIGPIPE_VARS
  36.     
  37.     if ((buf == NULL) || (size == 0) || (tlen <= 0)) {
  38.         errno = EINVAL;
  39.         return (-1);
  40.     }
  41.     
  42.     IGNORE_SIGPIPE
  43.     errno = 0;
  44.  
  45.     nleft = (read_size_t) size;
  46.     time(&now);
  47.     done = now + tlen;
  48.     firstRead = 1;
  49.  
  50.     forever {
  51.         tleft = (done > now) ? ((int) (done - now)) : 0;
  52.         if (tleft < 1) {
  53.             nread = (read_return_t) size - (read_return_t) nleft;
  54.             if ((nread == 0) || ((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) != 0)) {
  55.                 nread = kTimeoutErr;
  56.                 errno = ETIMEDOUT;
  57.                 SETWSATIMEOUTERR
  58.             }
  59.             goto done;
  60.         }
  61.         
  62.         if (!firstRead || ((retry & kNoFirstSelect) == 0)) {
  63.             forever {
  64.                 errno = 0;
  65.                 MY_FD_ZERO(&ss);
  66. #if defined(__DECC) || defined(__DECCXX)
  67. #pragma message save
  68. #pragma message disable trunclongint
  69. #endif
  70.                 MY_FD_SET(sfd, &ss);
  71. #if defined(__DECC) || defined(__DECCXX)
  72. #pragma message restore
  73. #endif
  74.                 tv.tv_sec = (tv_sec_t) tleft;
  75.                 tv.tv_usec = 0;
  76.                 result = select(sfd + 1, SELECT_TYPE_ARG234 &ss, NULL, NULL, SELECT_TYPE_ARG5 &tv);
  77.                 if (result >= 1) {
  78.                     /* ready */
  79.                     break;
  80.                 } else if (result == 0) {
  81.                     /* timeout */        
  82.                     nread = (read_return_t) size - (read_return_t) nleft;
  83.                     if ((nread > 0) && ((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast))  == 0)) {
  84.                         RESTORE_SIGPIPE
  85.                         return ((int) nread);
  86.                     }
  87.                     errno = ETIMEDOUT;
  88.                     SETWSATIMEOUTERR
  89.                     RESTORE_SIGPIPE
  90.                     return (kTimeoutErr);
  91.                 } else if (errno != EINTR) {
  92.                     RESTORE_SIGPIPE
  93.                     return (-1);
  94.                 }
  95.             }
  96.             firstRead = 0;
  97.         }
  98.  
  99. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  100.         nread = recv(sfd, (char *) buf, (recv_size_t) nleft, 0);
  101. #else
  102.         nread = read(sfd, (char *) buf, nleft);
  103. #endif
  104.  
  105.         if (nread <= 0) {
  106.             if (nread == 0) {
  107.                 /* EOF */
  108.                 if (retry == ((retry & (kFullBufferRequiredExceptLast)) != 0))
  109.                     nread = (read_return_t) size - (read_return_t) nleft;
  110.                 goto done;
  111.             } else if (errno != EINTR) {
  112.                 nread = (read_return_t) size - (read_return_t) nleft;
  113.                 if (nread == 0)
  114.                     nread = (read_return_t) -1;
  115.                 goto done;
  116.             } else {
  117.                 errno = 0;
  118.                 nread = 0;
  119.                 /* Try again. */
  120.  
  121.                 /* Ignore these two lines */
  122.                 LIBSIO_USE_VAR(gSioVersion);
  123.                 LIBSIO_USE_VAR(gCopyright);
  124.             }
  125.         }
  126.         nleft -= (read_size_t) nread;
  127.         if ((nleft == 0) || (((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) == 0) && (nleft != (read_size_t) size)))
  128.             break;
  129.         buf += nread;
  130.         time(&now);
  131.     }
  132.     nread = (read_return_t) size - (read_return_t) nleft;
  133.  
  134. done:
  135.     RESTORE_SIGPIPE
  136.     return ((int) nread);
  137. }    /* SRead */
  138.