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