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 / SRecvfrom.c < prev    next >
C/C++ Source or Header  |  2001-11-19  |  3KB  |  140 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. SRecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_in *const fromAddr, int tlen)
  15. {
  16.     recv_return_t nread;
  17.     alarm_time_t tleft;
  18.     vsio_sigproc_t sigalrm, sigpipe;
  19.     time_t done, now;
  20.     sockaddr_size_t alen;
  21.  
  22.     if (SSetjmp(gNetTimeoutJmp) != 0) {
  23.         alarm(0);
  24.         (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  25.         (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  26.         errno = ETIMEDOUT;
  27.         return (kTimeoutErr);
  28.     }
  29.  
  30.     if (SSetjmp(gPipeJmp) != 0) {
  31.         alarm(0);
  32.         (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  33.         (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  34.         errno = EPIPE;
  35.         return (kBrokenPipeErr);
  36.     }
  37.  
  38.     sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
  39.     sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);
  40.  
  41.     time(&now);
  42.     done = now + tlen;
  43.     tleft = (done < now) ? ((alarm_time_t) (done - now)) : 0;
  44.     forever {
  45.         if (tleft < 1) {
  46.             nread = kTimeoutErr;
  47.             errno = ETIMEDOUT;
  48.             break;
  49.         }
  50.         alen = (sockaddr_size_t) sizeof(struct sockaddr_in);
  51.         (void) alarm(tleft);
  52.         nread = recvfrom(sfd, buf, (recv_size_t) size, fl,
  53.             (struct sockaddr *) fromAddr, &alen);
  54.         (void) alarm(0);
  55.         if (nread >= 0)
  56.             break;
  57.         if (errno != EINTR)
  58.             break;        /* Fatal error. */
  59.         errno = 0;
  60.         time(&now);
  61.         tleft = (done < now) ? ((alarm_time_t) (done - now)) : 0;
  62.     }
  63.  
  64.     (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  65.     (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  66.  
  67.     return ((int) nread);
  68. }    /* SRecvfrom */
  69.  
  70. #else
  71.  
  72. int
  73. SRecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_in *const fromAddr, int tlen)
  74. {
  75.     recv_return_t nread;
  76.     int tleft;
  77.     fd_set ss;
  78.     struct timeval tv;
  79.     int result;
  80.     time_t done, now;
  81.     sockaddr_size_t alen;
  82.  
  83.     time(&now);
  84.     done = now + tlen;
  85.     tleft = (done < now) ? ((int) (done - now)) : 0;
  86.     nread = 0;
  87.     forever {
  88.         alen = (sockaddr_size_t) sizeof(struct sockaddr_in);
  89.                 
  90.         forever {
  91.             errno = 0;
  92.             MY_FD_ZERO(&ss);
  93. #if defined(__DECC) || defined(__DECCXX)
  94. #pragma message save
  95. #pragma message disable trunclongint
  96. #endif
  97.             MY_FD_SET(sfd, &ss);
  98. #if defined(__DECC) || defined(__DECCXX)
  99. #pragma message restore
  100. #endif
  101.             tv.tv_sec = (tv_sec_t) tleft;
  102.             tv.tv_usec = 0;
  103.             result = select(sfd + 1, SELECT_TYPE_ARG234 &ss, NULL, NULL, SELECT_TYPE_ARG5 &tv);
  104.             if (result == 1) {
  105.                 /* ready */
  106.                 break;
  107.             } else if (result == 0) {
  108.                 /* timeout */
  109.                 errno = ETIMEDOUT;
  110.                 SETWSATIMEOUTERR
  111.                 return (kTimeoutErr);
  112.             } else if (errno != EINTR) {
  113.                 return (-1);
  114.             }
  115.         }
  116.  
  117.         nread = recvfrom(sfd, buf, (recv_size_t) size, fl,
  118.             (struct sockaddr *) fromAddr, &alen);
  119.  
  120.         if (nread >= 0)
  121.             break;
  122.         if (errno != EINTR)
  123.             break;        /* Fatal error. */
  124.         errno = 0;
  125.         time(&now);
  126.         tleft = (done < now) ? ((int) (done - now)) : 0;
  127.         if (tleft < 1) {
  128.             nread = kTimeoutErr;
  129.             errno = ETIMEDOUT;
  130.             SETWSATIMEOUTERR
  131.             break;
  132.         }
  133.     }
  134.  
  135.     return ((int) nread);
  136. }    /* SRecvfrom */
  137.  
  138. #endif
  139.  
  140.