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 / SWrite.c < prev    next >
C/C++ Source or Header  |  2002-03-27  |  4KB  |  193 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. SWrite(int sfd, const char *const buf0, size_t size, int tlen, int swopts)
  15. {
  16.     const char *volatile buf = buf0;
  17.     write_return_t nwrote;
  18.     volatile write_size_t nleft;
  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.         nwrote = (write_return_t) size - (write_return_t) nleft;
  28.         if (nwrote > 0)
  29.             return ((int) nwrote);
  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.         nwrote = (write_return_t) size - (write_return_t) nleft;
  39.         if (nwrote > 0)
  40.             return ((int) nwrote);
  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.  
  48.     nleft = (write_size_t) size;
  49.     time(&now);
  50.     done = now + tlen;
  51.     forever {
  52.         tleft = (done < now) ? ((alarm_time_t) (done - now)) : 0;
  53.         if (tleft < 1) {
  54.             nwrote = (write_return_t) size - (write_return_t) nleft;
  55.             if (nwrote == 0) {
  56.                 nwrote = kTimeoutErr;
  57.                 errno = ETIMEDOUT;
  58.             }
  59.             goto done;
  60.         }
  61.         (void) alarm(tleft);
  62.         nwrote = write(sfd, buf, nleft);
  63.         (void) alarm(0);
  64.         if (nwrote < 0) {
  65.             if (errno != EINTR) {
  66.                 nwrote = (write_return_t) size - (write_return_t) nleft;
  67.                 if (nwrote == 0)
  68.                     nwrote = (write_return_t) -1;
  69.                 goto done;
  70.             } else {
  71.                 errno = 0;
  72.                 nwrote = 0;
  73.                 /* Try again. */
  74.             }
  75.         }
  76.         nleft -= (write_size_t) nwrote;
  77.         if (nleft == 0)
  78.             break;
  79.         buf += nwrote;
  80.         time(&now);
  81.     }
  82.     nwrote = (write_return_t) size - (write_return_t) nleft;
  83.  
  84. done:
  85.     (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
  86.     (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  87.  
  88.     return ((int) nwrote);
  89. }    /* SWrite */
  90.  
  91. #else
  92.  
  93. int
  94. SWrite(int sfd, const char *const buf0, size_t size, int tlen, int swopts)
  95. {
  96.     const char *buf = buf0;
  97.     write_return_t nwrote;
  98.     write_size_t nleft;
  99.     int tleft;
  100.     time_t done, now;
  101.     fd_set ss;
  102.     struct timeval tv;
  103.     int result, firstWrite;
  104.  
  105.     nleft = (write_size_t) size;
  106.     time(&now);
  107.     done = now + tlen;
  108.     firstWrite = 1;
  109.  
  110.     forever {
  111.         tleft = (int) (done - now);
  112.         if (tleft < 1) {
  113.             nwrote = (write_return_t) size - (write_return_t) nleft;
  114.             if (nwrote == 0) {
  115.                 nwrote = kTimeoutErr;
  116.                 errno = ETIMEDOUT;
  117.                 SETWSATIMEOUTERR
  118.             }
  119.             goto done;
  120.         }
  121.  
  122.  
  123.         /* Unfortunately this doesn't help when the
  124.          * send buffer fills during the time we're
  125.          * writing to it, so you could still be
  126.          * blocked after breaking this loop and starting
  127.          * the write.
  128.          */
  129.         if (!firstWrite || ((swopts & kNoFirstSelect) == 0)) {
  130.             forever {
  131.                 errno = 0;
  132.                 MY_FD_ZERO(&ss);
  133. #if defined(__DECC) || defined(__DECCXX)
  134. #pragma message save
  135. #pragma message disable trunclongint
  136. #endif
  137.                 MY_FD_SET(sfd, &ss);
  138. #if defined(__DECC) || defined(__DECCXX)
  139. #pragma message restore
  140. #endif
  141.                 tv.tv_sec = (tv_sec_t) tlen;
  142.                 tv.tv_usec = 0;
  143.                 result = select(sfd + 1, NULL, SELECT_TYPE_ARG234 &ss, NULL, SELECT_TYPE_ARG5 &tv);
  144.                 if (result == 1) {
  145.                     /* ready */
  146.                     break;
  147.                 } else if (result == 0) {
  148.                     /* timeout */        
  149.                     nwrote = (write_return_t) size - (write_return_t) nleft;
  150.                     if (nwrote > 0)
  151.                         return ((int) nwrote);
  152.                     errno = ETIMEDOUT;
  153.                     SETWSATIMEOUTERR
  154.                         return (kTimeoutErr);
  155.                 } else if (errno != EINTR) {
  156.                     return (-1);
  157.                 }
  158.             }
  159.             firstWrite = 0;
  160.         }
  161.         
  162. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  163.         nwrote = send(sfd, buf, (send_size_t) nleft, 0);
  164. #else
  165.         nwrote = write(sfd, buf, nleft);
  166. #endif
  167.  
  168.         if (nwrote < 0) {
  169.             if (errno != EINTR) {
  170.                 nwrote = (write_return_t) size - (write_return_t) nleft;
  171.                 if (nwrote == 0)
  172.                     nwrote = (write_return_t) -1;
  173.                 goto done;
  174.             } else {
  175.                 errno = 0;
  176.                 nwrote = 0;
  177.                 /* Try again. */
  178.             }
  179.         }
  180.         nleft -= (write_size_t) nwrote;
  181.         if (nleft == 0)
  182.             break;
  183.         buf += nwrote;
  184.         time(&now);
  185.     }
  186.     nwrote = (write_return_t) size - (write_return_t) nleft;
  187.  
  188. done:
  189.     return ((int) nwrote);
  190. }    /* SWrite */
  191.  
  192. #endif
  193.