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 / URecvfrom.c < prev    next >
C/C++ Source or Header  |  2001-11-19  |  3KB  |  139 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. #ifndef NO_SIGNALS
  7.  
  8. extern Sjmp_buf gNetTimeoutJmp;
  9. extern Sjmp_buf gPipeJmp;
  10.  
  11. int
  12. URecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_un *const fromAddr, int *ualen, int tlen)
  13. {
  14.     recv_return_t nread;
  15.     alarm_time_t tleft;
  16.     vsio_sigproc_t sigalrm, sigpipe;
  17.     time_t done, now;
  18.     sockaddr_size_t ualen2;
  19.  
  20.     if (SSetjmp(gNetTimeoutJmp) != 0) {
  21.         alarm(0);
  22.         (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  23.         (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  24.         errno = ETIMEDOUT;
  25.         return (kTimeoutErr);
  26.     }
  27.  
  28.     if (SSetjmp(gPipeJmp) != 0) {
  29.         alarm(0);
  30.         (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  31.         (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  32.         errno = EPIPE;
  33.         return (kBrokenPipeErr);
  34.     }
  35.  
  36.     sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
  37.     sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);
  38.  
  39.     time(&now);
  40.     done = now + tlen;
  41.     tleft = (done < now) ? ((alarm_time_t) (done - now)) : 0;
  42.     forever {
  43.         if (tleft < 1) {
  44.             nread = kTimeoutErr;
  45.             errno = ETIMEDOUT;
  46.             break;
  47.         }
  48.         ualen2 = sizeof(struct sockaddr_un);
  49.         (void) alarm(tleft);
  50.         nread = recvfrom(sfd, buf, (recv_size_t) size, fl,
  51.             (struct sockaddr *) fromAddr, &ualen2);
  52.         (void) alarm(0);
  53.         *ualen = (int) ualen2;
  54.         if (nread >= 0)
  55.             break;
  56.         if (errno != EINTR)
  57.             break;        /* Fatal error. */
  58.         errno = 0;
  59.         time(&now);
  60.         tleft = (done < now) ? ((alarm_time_t) (done - now)) : 0;
  61.     }
  62.  
  63.     (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  64.     (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  65.  
  66.     return ((int) nread);
  67. }    /* URecvfrom */
  68.  
  69. #else
  70.  
  71. int
  72. URecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_un *const fromAddr, int *ualen, int tlen)
  73. {
  74.     recv_return_t nread;
  75.     int tleft;
  76.     fd_set ss;
  77.     struct timeval tv;
  78.     int result;
  79.     time_t done, now;
  80.     sockaddr_size_t alen;
  81.  
  82.     time(&now);
  83.     done = now + tlen;
  84.     tleft = (done < now) ? ((int) (done - now)) : 0;
  85.     nread = 0;
  86.     forever {
  87.         alen = (sockaddr_size_t) sizeof(struct sockaddr_un);
  88.                 
  89.         forever {
  90.             errno = 0;
  91.             MY_FD_ZERO(&ss);
  92. #if defined(__DECC) || defined(__DECCXX)
  93. #pragma message save
  94. #pragma message disable trunclongint
  95. #endif
  96.             MY_FD_SET(sfd, &ss);
  97. #if defined(__DECC) || defined(__DECCXX)
  98. #pragma message restore
  99. #endif
  100.             tv.tv_sec = (tv_sec_t) tleft;
  101.             tv.tv_usec = 0;
  102.             result = select(sfd + 1, SELECT_TYPE_ARG234 &ss, NULL, NULL, SELECT_TYPE_ARG5 &tv);
  103.             if (result == 1) {
  104.                 /* ready */
  105.                 break;
  106.             } else if (result == 0) {
  107.                 /* timeout */
  108.                 errno = ETIMEDOUT;
  109.                 SETWSATIMEOUTERR
  110.                 return (kTimeoutErr);
  111.             } else if (errno != EINTR) {
  112.                 return (-1);
  113.             }
  114.         }
  115.  
  116.         nread = recvfrom(sfd, buf, (recv_size_t) size, fl,
  117.             (struct sockaddr *) fromAddr, &alen);
  118.         *ualen = (int) 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. }    /* URecvfrom */
  137.  
  138. #endif
  139.