home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / libncftp / libncftp-3.2.5-src.zip / libncftp-3.2.5 / sio / SWrite.c < prev    next >
C/C++ Source or Header  |  2009-12-17  |  3KB  |  117 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. int
  7. SWrite(int sfd, const char *const buf0, size_t size, int tlen, int swopts)
  8. {
  9.     const char *buf = buf0;
  10.     write_return_t nwrote;
  11.     write_size_t nleft;
  12.     int tleft;
  13.     time_t done, now;
  14.     fd_set ss;
  15.     struct timeval tv;
  16.     int result, firstSelect;
  17.     DECL_SIGPIPE_VARS
  18.     
  19.     if ((buf == NULL) || (size == 0) || (tlen <= 0)) {
  20.         errno = EINVAL;
  21.         return (-1);
  22.     }
  23.     
  24.     IGNORE_SIGPIPE
  25.  
  26.     nleft = (write_size_t) size;
  27.     time(&now);
  28.     done = now + tlen;
  29.     firstSelect = 1;
  30.  
  31.     forever {
  32.         tleft = (done > now) ? ((int) (done - now)) : 0;
  33.         if (tleft < 1) {
  34.             nwrote = (write_return_t) size - (write_return_t) nleft;
  35.             if (nwrote == 0) {
  36.                 nwrote = kTimeoutErr;
  37.                 errno = ETIMEDOUT;
  38.                 SETWSATIMEOUTERR
  39.             }
  40.             goto done;
  41.         }
  42.  
  43.  
  44.         /* Unfortunately this doesn't help when the
  45.          * send buffer fills during the time we're
  46.          * writing to it, so you could still be
  47.          * blocked after breaking this loop and starting
  48.          * the write.
  49.          */
  50.         if (!firstSelect || ((swopts & kNoFirstSelect) == 0)) {
  51.             forever {
  52.                 errno = 0;
  53.                 MY_FD_ZERO(&ss);
  54. #if defined(__DECC) || defined(__DECCXX)
  55. #pragma message save
  56. #pragma message disable trunclongint
  57. #endif
  58.                 MY_FD_SET(sfd, &ss);
  59. #if defined(__DECC) || defined(__DECCXX)
  60. #pragma message restore
  61. #endif
  62.                 tv.tv_sec = (tv_sec_t) tlen;
  63.                 tv.tv_usec = 0;
  64.                 result = select(sfd + 1, NULL, SELECT_TYPE_ARG234 &ss, NULL, SELECT_TYPE_ARG5 &tv);
  65.                 if (result >= 1) {
  66.                     /* ready */
  67.                     break;
  68.                 } else if (result == 0) {
  69.                     /* timeout */        
  70.                     nwrote = (write_return_t) size - (write_return_t) nleft;
  71.                     if (nwrote > 0) {
  72.                         RESTORE_SIGPIPE
  73.                         return ((int) nwrote);
  74.                     }
  75.                     errno = ETIMEDOUT;
  76.                     SETWSATIMEOUTERR
  77.                     RESTORE_SIGPIPE
  78.                     return (kTimeoutErr);
  79.                 } else if (errno != EINTR) {
  80.                     RESTORE_SIGPIPE
  81.                     return (-1);
  82.                 }
  83.             }
  84.             firstSelect = 0;
  85.         }
  86.         
  87. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  88.         nwrote = send(sfd, buf, (send_size_t) nleft, 0);
  89. #else
  90.         nwrote = write(sfd, buf, nleft);
  91. #endif
  92.  
  93.         if (nwrote < 0) {
  94.             if (errno != EINTR) {
  95.                 nwrote = (write_return_t) size - (write_return_t) nleft;
  96.                 if (nwrote == 0)
  97.                     nwrote = (write_return_t) -1;
  98.                 goto done;
  99.             } else {
  100.                 errno = 0;
  101.                 nwrote = 0;
  102.                 /* Try again. */
  103.             }
  104.         }
  105.         nleft -= (write_size_t) nwrote;
  106.         if (nleft == 0)
  107.             break;
  108.         buf += nwrote;
  109.         time(&now);
  110.     }
  111.     nwrote = (write_return_t) size - (write_return_t) nleft;
  112.  
  113. done:
  114.     RESTORE_SIGPIPE
  115.     return ((int) nwrote);
  116. }    /* SWrite */
  117.