reactos/modules/rosapps/applications/net/ncftp/sio/PRead.c

72 lines
1.6 KiB
C

#include "syshdrs.h"
#if !defined(NO_SIGNALS) && defined(SIGPIPE)
extern volatile Sjmp_buf gPipeJmp;
#endif
/* Read up to "size" bytes on sfd.
*
* If "retry" is on, after a successful read of less than "size"
* bytes, it will attempt to read more, upto "size."
*
* Although "retry" would seem to indicate you may want to always
* read "size" bytes or else it is an error, even with that on you
* may get back a value < size. Set "retry" to 0 when you want to
* return as soon as there is a chunk of data whose size is <= "size".
*/
int
PRead(int sfd, char *const buf0, size_t size, int retry)
{
int nread;
volatile int nleft;
char *volatile buf = buf0;
#if !defined(NO_SIGNALS) && defined(SIGPIPE)
vsio_sigproc_t sigpipe;
if (SSetjmp(gPipeJmp) != 0) {
(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
nread = size - nleft;
if (nread > 0)
return (nread);
errno = EPIPE;
return (kBrokenPipeErr);
}
sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);
#endif
errno = 0;
nleft = (int) size;
forever {
nread = read(sfd, buf, nleft);
if (nread <= 0) {
if (nread == 0) {
/* EOF */
nread = size - nleft;
goto done;
} else if (errno != EINTR) {
nread = size - nleft;
if (nread == 0)
nread = -1;
goto done;
} else {
errno = 0;
nread = 0;
/* Try again. */
}
}
nleft -= nread;
if ((nleft <= 0) || (retry == 0))
break;
buf += nread;
}
nread = size - nleft;
done:
#if !defined(NO_SIGNALS) && defined(SIGPIPE)
(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
#endif
return (nread);
} /* PRead */