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 / SRecv.c < prev    next >
C/C++ Source or Header  |  2009-12-17  |  3KB  |  113 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. int
  7. SRecv(int sfd, char *const buf0, size_t size, int fl, int tlen, int retry)
  8. {
  9.     read_return_t nread;
  10.     read_size_t nleft;
  11.     char *buf = buf0;
  12.     int tleft;
  13.     time_t done, now;
  14.     fd_set ss;
  15.     struct timeval tv;
  16.     int result, firstRead;
  17.     DECL_SIGPIPE_VARS
  18.     
  19.     if ((buf == NULL) || (size == 0) || (tlen <= 0)) {
  20.         errno = EINVAL;
  21.         return (-1);
  22.     }
  23.     
  24.     IGNORE_SIGPIPE
  25.     errno = 0;
  26.  
  27.     nleft = (read_size_t) size;
  28.     time(&now);
  29.     done = now + tlen;
  30.     firstRead = 1;
  31.  
  32.     forever {
  33.         tleft = (done > now) ? ((int) (done - now)) : 0;
  34.         if (tleft < 1) {
  35.             nread = (read_return_t) size - (read_return_t) nleft;
  36.             if ((nread == 0) || ((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) != 0)) {
  37.                 nread = kTimeoutErr;
  38.                 errno = ETIMEDOUT;
  39.                 SETWSATIMEOUTERR
  40.             }
  41.             goto done;
  42.         }
  43.         
  44.         if (!firstRead || ((retry & kNoFirstSelect) == 0)) {
  45.             forever {
  46.                 errno = 0;
  47.                 MY_FD_ZERO(&ss);
  48. #if defined(__DECC) || defined(__DECCXX)
  49. #pragma message save
  50. #pragma message disable trunclongint
  51. #endif
  52.                 MY_FD_SET(sfd, &ss);
  53. #if defined(__DECC) || defined(__DECCXX)
  54. #pragma message restore
  55. #endif
  56.                 tv.tv_sec = (tv_sec_t) tleft;
  57.                 tv.tv_usec = 0;
  58.                 result = select(sfd + 1, SELECT_TYPE_ARG234 &ss, NULL, NULL, SELECT_TYPE_ARG5 &tv);
  59.                 if (result >= 1) {
  60.                     /* ready */
  61.                     break;
  62.                 } else if (result == 0) {
  63.                     /* timeout */        
  64.                     nread = (read_return_t) size - (read_return_t) nleft;
  65.                     if ((nread > 0) && ((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast))  == 0)) {
  66.                         RESTORE_SIGPIPE
  67.                         return ((int) nread);
  68.                     }
  69.                     errno = ETIMEDOUT;
  70.                     SETWSATIMEOUTERR
  71.                     RESTORE_SIGPIPE
  72.                     return (kTimeoutErr);
  73.                 } else if (errno != EINTR) {
  74.                     RESTORE_SIGPIPE
  75.                     return (-1);
  76.                 }
  77.             }
  78.             firstRead = 0;
  79.         }
  80.  
  81.         nread = recv(sfd, (char *) buf, (recv_size_t) nleft, fl);
  82.  
  83.         if (nread <= 0) {
  84.             if (nread == 0) {
  85.                 /* EOF */
  86.                 if (retry == ((retry & (kFullBufferRequiredExceptLast)) != 0))
  87.                     nread = (read_return_t) size - (read_return_t) nleft;
  88.                 goto done;
  89.             } else if (errno != EINTR) {
  90.                 nread = (read_return_t) size - (read_return_t) nleft;
  91.                 if (nread == 0)
  92.                     nread = (read_return_t) -1;
  93.                 goto done;
  94.             } else {
  95.                 errno = 0;
  96.                 nread = 0;
  97.                 /* Try again. */
  98.             }
  99.         }
  100.         nleft -= (read_size_t) nread;
  101.         if ((nleft == 0) || (((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) == 0) && (nleft != (read_size_t) size)))
  102.             break;
  103.         buf += nread;
  104.         time(&now);
  105.     }
  106.     nread = (read_return_t) size - (read_return_t) nleft;
  107.  
  108. done:
  109.     RESTORE_SIGPIPE
  110.     return ((int) nread);
  111. }    /* SRecv */
  112.  
  113.