home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / libncftp / older_versions / libncftp-3.1.5-src.tar.gz / libncftp-3.1.5-src.tar / libncftp-3.1.5 / sio / SRecv.c < prev    next >
C/C++ Source or Header  |  2001-11-19  |  4KB  |  191 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. #ifndef NO_SIGNALS
  7. extern Sjmp_buf gNetTimeoutJmp;
  8. extern Sjmp_buf gPipeJmp;
  9. #endif
  10.  
  11. #ifndef NO_SIGNALS
  12.  
  13. int
  14. SRecv(int sfd, char *const buf0, size_t size, int fl, int tlen, int retry)
  15. {
  16.     recv_return_t nread;
  17.     volatile recv_size_t nleft;
  18.     char *volatile buf = buf0;
  19.     alarm_time_t tleft;
  20.     vsio_sigproc_t sigalrm, sigpipe;
  21.     time_t done, now;
  22.  
  23.     if (SSetjmp(gNetTimeoutJmp) != 0) {
  24.         alarm(0);
  25.         (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  26.         (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  27.         nread = (recv_return_t) size - (recv_return_t) nleft;
  28.         if ((nread > 0) && (retry == kFullBufferNotRequired))
  29.             return ((int) nread);
  30.         errno = ETIMEDOUT;
  31.         return (kTimeoutErr);
  32.     }
  33.  
  34.     if (SSetjmp(gPipeJmp) != 0) {
  35.         alarm(0);
  36.         (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  37.         (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  38.         nread = (recv_return_t) size - (recv_return_t) nleft;
  39.         if ((nread > 0) && (retry == kFullBufferNotRequired))
  40.             return ((int) nread);
  41.         errno = EPIPE;
  42.         return (kBrokenPipeErr);
  43.     }
  44.  
  45.     sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
  46.     sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);
  47.     errno = 0;
  48.  
  49.     nleft = (recv_size_t) size;
  50.     time(&now);
  51.     done = now + tlen;
  52.     forever {
  53.         tleft = (done < now) ? ((alarm_time_t) (done - now)) : 0;
  54.         if (tleft < 1) {
  55.             nread = (recv_return_t) size - (recv_return_t) nleft;
  56.             if ((nread == 0) || (retry == kFullBufferRequired)) {
  57.                 nread = kTimeoutErr;
  58.                 errno = ETIMEDOUT;
  59.             }
  60.             goto done;
  61.         }
  62.         (void) alarm(tleft);
  63.         nread = recv(sfd, (char *) buf, nleft, fl);
  64.         (void) alarm(0);
  65.         if (nread <= 0) {
  66.             if (nread == 0) {
  67.                 /* EOF */
  68.                 if (retry == kFullBufferRequiredExceptLast)
  69.                     nread = (recv_return_t) size - (recv_return_t) nleft;
  70.                 goto done;
  71.             } else if (errno != EINTR) {
  72.                 nread = (recv_return_t) size - (recv_return_t) nleft;
  73.                 if (nread == 0)
  74.                     nread = (recv_return_t) -1;
  75.                 goto done;
  76.             } else {
  77.                 errno = 0;
  78.                 nread = 0;
  79.                 /* Try again. */
  80.             }
  81.         }
  82.         nleft -= (recv_size_t) nread;
  83.         if ((nleft == 0) || ((retry == 0) && (nleft != (recv_size_t) size)))
  84.             break;
  85.         buf += nread;
  86.         time(&now);
  87.     }
  88.     nread = (recv_return_t) size - (recv_return_t) nleft;
  89.  
  90. done:
  91.     (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  92.     (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  93.  
  94.     return ((int) nread);
  95. }    /* SRecv */
  96.  
  97. #else
  98.  
  99. int
  100. SRecv(int sfd, char *const buf0, size_t size, int fl, int tlen, int retry)
  101. {
  102.     recv_return_t nread;
  103.     recv_size_t nleft;
  104.     char *buf = buf0;
  105.     int tleft;
  106.     time_t done, now;
  107.     fd_set ss;
  108.     struct timeval tv;
  109.     int result;
  110.  
  111.     errno = 0;
  112.  
  113.     nleft = (recv_size_t) size;
  114.     time(&now);
  115.     done = now + tlen;
  116.     forever {
  117.         tleft = (int) (done - now);
  118.         if (tleft < 1) {
  119.             nread = (recv_return_t) size - (recv_return_t) nleft;
  120.             if ((nread == 0) || (retry == kFullBufferRequired)) {
  121.                 nread = kTimeoutErr;
  122.                 errno = ETIMEDOUT;
  123.                 SETWSATIMEOUTERR
  124.             }
  125.             goto done;
  126.         }
  127.  
  128.         forever {
  129.             errno = 0;
  130.             MY_FD_ZERO(&ss);
  131. #if defined(__DECC) || defined(__DECCXX)
  132. #pragma message save
  133. #pragma message disable trunclongint
  134. #endif
  135.             MY_FD_SET(sfd, &ss);
  136. #if defined(__DECC) || defined(__DECCXX)
  137. #pragma message restore
  138. #endif
  139.             tv.tv_sec = (tv_sec_t) tlen;
  140.             tv.tv_usec = 0;
  141.             result = select(sfd + 1, SELECT_TYPE_ARG234 &ss, NULL, NULL, SELECT_TYPE_ARG5 &tv);
  142.             if (result == 1) {
  143.                 /* ready */
  144.                 break;
  145.             } else if (result == 0) {
  146.                 /* timeout */        
  147.                 nread = (recv_return_t) size - (recv_return_t) nleft;
  148.                 if ((nread > 0) && (retry == kFullBufferNotRequired))
  149.                     return ((int) nread);
  150.                 errno = ETIMEDOUT;
  151.                 SETWSATIMEOUTERR
  152.                 return (kTimeoutErr);
  153.             } else if (errno != EINTR) {
  154.                 return (-1);
  155.             }
  156.         }
  157.  
  158.         nread = recv(sfd, (char *) buf, nleft, fl);
  159.  
  160.         if (nread <= 0) {
  161.             if (nread == 0) {
  162.                 /* EOF */
  163.                 if (retry == kFullBufferRequiredExceptLast)
  164.                     nread = (recv_return_t) size - (recv_return_t) nleft;
  165.                 goto done;
  166.             } else if (errno != EINTR) {
  167.                 nread = (recv_return_t) size - (recv_return_t) nleft;
  168.                 if (nread == 0)
  169.                     nread = (recv_return_t) -1;
  170.                 goto done;
  171.             } else {
  172.                 errno = 0;
  173.                 nread = 0;
  174.                 /* Try again. */
  175.             }
  176.         }
  177.         nleft -= (recv_size_t) nread;
  178.         if ((nleft == 0) || ((retry == 0) && (nleft != (recv_size_t) size)))
  179.             break;
  180.         buf += nread;
  181.         time(&now);
  182.     }
  183.     nread = (recv_return_t) size - (recv_return_t) nleft;
  184.  
  185. done:
  186.     return ((int) nread);
  187. }    /* SRecv */
  188.  
  189. #endif
  190.  
  191.