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 / PRead.c < prev    next >
C/C++ Source or Header  |  2001-11-19  |  2KB  |  78 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. #if !defined(NO_SIGNALS) && defined(SIGPIPE)
  7. extern Sjmp_buf gPipeJmp;
  8. #endif
  9.  
  10. /* Read up to "size" bytes on sfd.
  11.  *
  12.  * If "retry" is on, after a successful read of less than "size"
  13.  * bytes, it will attempt to read more, upto "size."
  14.  *
  15.  * Although "retry" would seem to indicate you may want to always
  16.  * read "size" bytes or else it is an error, even with that on you
  17.  * may get back a value < size.  Set "retry" to 0 when you want to
  18.  * return as soon as there is a chunk of data whose size is <= "size".
  19.  */
  20.  
  21. int
  22. PRead(int sfd, char *const buf0, size_t size, int retry)
  23. {
  24.     read_return_t nread;
  25. #if defined(NO_SIGNALS) || !defined(SIGPIPE)
  26.     read_size_t nleft;
  27.     char *buf = buf0;
  28. #else
  29.     char *volatile buf = buf0;
  30.     volatile read_size_t nleft;
  31.     vsio_sigproc_t sigpipe;
  32.  
  33.     if (SSetjmp(gPipeJmp) != 0) {
  34.         (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  35.         nread = (read_return_t) size - (read_return_t) nleft;
  36.         if (nread > 0)
  37.             return ((int) nread);
  38.         errno = EPIPE;
  39.         return (kBrokenPipeErr);
  40.     }
  41.  
  42.     sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);
  43. #endif
  44.     errno = 0;
  45.  
  46.     nleft = (read_size_t) size;
  47.     forever {
  48.         nread = read(sfd, buf, nleft);
  49.         if (nread <= 0) {
  50.             if (nread == 0) {
  51.                 /* EOF */
  52.                 nread = (read_return_t) size - (read_return_t) nleft;
  53.                 goto done;
  54.             } else if (errno != EINTR) {
  55.                 nread = (read_return_t) size - (read_return_t) nleft;
  56.                 if (nread == 0)
  57.                     nread = (read_return_t) -1;
  58.                 goto done;
  59.             } else {
  60.                 errno = 0;
  61.                 nread = 0;
  62.                 /* Try again. */
  63.             }
  64.         }
  65.         nleft -= (read_size_t) nread;
  66.         if ((nleft == 0) || (retry == 0))
  67.             break;
  68.         buf += nread;
  69.     }
  70.     nread = (read_return_t) size - (read_return_t) nleft;
  71.  
  72. done:
  73. #if !defined(NO_SIGNALS) && defined(SIGPIPE)
  74.     (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
  75. #endif
  76.     return ((int) nread);
  77. }    /* PRead */
  78.