ReactOS  0.4.13-dev-249-gcba1a2f
SRead.c
Go to the documentation of this file.
1 #include "syshdrs.h"
2 
3 static char UNUSED(gSioVersion[]) = "@(#) sio 6.0.3 ** Copyright 1992-2001 Mike Gleason. All rights reserved.";
4 
5 #ifdef NO_SIGNALS
6 static char UNUSED(gNoSignalsMarker[]) = "@(#) sio - NO_SIGNALS";
7 #else
8 extern volatile Sjmp_buf gNetTimeoutJmp;
9 extern volatile Sjmp_buf gPipeJmp;
10 #endif
11 
12 /* Read up to "size" bytes on sfd before "tlen" seconds.
13  *
14  * If "retry" is on, after a successful read of less than "size"
15  * bytes, it will attempt to read more, upto "size."
16  *
17  * If the timer elapses and one or more bytes were read, it returns
18  * that number, otherwise a timeout error is returned.
19  *
20  * Although "retry" would seem to indicate you may want to always
21  * read "size" bytes or else it is an error, even with that on you
22  * may get back a value < size. Set "retry" to 0 when you want to
23  * return as soon as there is a chunk of data whose size is <= "size".
24  */
25 
26 #ifndef NO_SIGNALS
27 
28 int
29 SRead(int sfd, char *const buf0, size_t size, int tlen, int retry)
30 {
31  int nread;
32  volatile int nleft;
33  char *volatile buf = buf0;
34  int tleft;
35  vsio_sigproc_t sigalrm, sigpipe;
36  time_t done, now;
37 
38  if (SSetjmp(gNetTimeoutJmp) != 0) {
39  alarm(0);
40  (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
41  (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
42  nread = size - nleft;
43  if ((nread > 0) && ((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) == 0))
44  return (nread);
45  errno = ETIMEDOUT;
46  return (kTimeoutErr);
47  }
48 
49  if (SSetjmp(gPipeJmp) != 0) {
50  alarm(0);
51  (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
52  (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
53  nread = size - nleft;
54  if ((nread > 0) && ((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) == 0))
55  return (nread);
56  errno = EPIPE;
57  return (kBrokenPipeErr);
58  }
59 
60  sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
62  errno = 0;
63 
64  nleft = (int) size;
65  time(&now);
66  done = now + tlen;
67  forever {
68  tleft = (int) (done - now);
69  if (tleft < 1) {
70  nread = size - nleft;
71  if ((nread == 0) || ((retry & (kFullBufferRequired)) != 0)) {
72  nread = kTimeoutErr;
73  errno = ETIMEDOUT;
74  }
75  goto done;
76  }
77  (void) alarm((unsigned int) tleft);
78  nread = read(sfd, (char *) buf, nleft);
79  (void) alarm(0);
80  if (nread <= 0) {
81  if (nread == 0) {
82  /* EOF */
83  if (retry == ((retry & (kFullBufferRequiredExceptLast)) != 0))
84  nread = size - nleft;
85  goto done;
86  } else if (errno != EINTR) {
87  nread = size - nleft;
88  if (nread == 0)
89  nread = -1;
90  goto done;
91  } else {
92  errno = 0;
93  nread = 0;
94  /* Try again. */
95 
96  /* Ignore this line... */
97  LIBSIO_USE_VAR(gSioVersion);
98  }
99  }
100  nleft -= nread;
101  if ((nleft <= 0) || (((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) == 0) && (nleft != (int) size)))
102  break;
103  buf += nread;
104  time(&now);
105  }
106  nread = size - nleft;
107 
108 done:
109  (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
110  (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
111 
112  return (nread);
113 } /* SRead */
114 
115 #else
116 
117 int
118 SRead(int sfd, char *const buf0, size_t size, int tlen, int retry)
119 {
120  int nread;
121  volatile int nleft;
122  char *buf = buf0;
123  int tleft;
124  time_t done, now;
125  fd_set ss;
126  struct timeval tv;
127  int result, firstRead;
128 
129  errno = 0;
130 
131  nleft = (int) size;
132  time(&now);
133  done = now + tlen;
134  firstRead = 1;
135 
136  forever {
137  tleft = (int) (done - now);
138  if (tleft < 1) {
139  nread = size - nleft;
140  if ((nread == 0) || ((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) != 0)) {
141  nread = kTimeoutErr;
142  errno = ETIMEDOUT;
144  }
145  goto done;
146  }
147 
148  if (!firstRead || ((retry & kNoFirstSelect) == 0)) {
149  forever {
150  errno = 0;
151  FD_ZERO(&ss);
152  FD_SET(sfd, &ss);
153  tv.tv_sec = tlen;
154  tv.tv_usec = 0;
156  if (result == 1) {
157  /* ready */
158  break;
159  } else if (result == 0) {
160  /* timeout */
161  nread = size - nleft;
162  if ((nread > 0) && ((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) == 0))
163  return (nread);
164  errno = ETIMEDOUT;
166  return (kTimeoutErr);
167  } else if (errno != EINTR) {
168  return (-1);
169  }
170  }
171  firstRead = 0;
172  }
173 
174 #if defined(WIN32) || defined(_WINDOWS)
175  nread = recv(sfd, (char *) buf, nleft, 0);
176 #else
177  nread = read(sfd, (char *) buf, nleft);
178 #endif
179 
180  if (nread <= 0) {
181  if (nread == 0) {
182  /* EOF */
183  if (retry == ((retry & (kFullBufferRequiredExceptLast)) != 0))
184  nread = size - nleft;
185  goto done;
186  } else if (errno != EINTR) {
187  nread = size - nleft;
188  if (nread == 0)
189  nread = -1;
190  goto done;
191  } else {
192  errno = 0;
193  nread = 0;
194  /* Try again. */
195 
196  /* Ignore these two lines */
197  LIBSIO_USE_VAR(gSioVersion);
199  }
200  }
201  nleft -= nread;
202  if ((nleft <= 0) || (((retry & (kFullBufferRequired|kFullBufferRequiredExceptLast)) == 0) && (nleft != (int) size)))
203  break;
204  buf += nread;
205  time(&now);
206  }
207  nread = size - nleft;
208 
209 done:
210  return (nread);
211 } /* SRead */
212 
213 #endif
Definition: winsock.h:66
#define EPIPE
Definition: acclib.h:91
#define SELECT_TYPE_ARG234
Definition: wincfg.h:4
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
volatile sio_sigproc_t vsio_sigproc_t
Definition: sio.h:124
int SRead(int sfd, char *const buf0, size_t size, int tlen, int retry)
Definition: SRead.c:118
#define LIBSIO_USE_VAR(a)
Definition: sio.h:140
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define EINTR
Definition: acclib.h:80
unsigned long tv_sec
Definition: linux.h:1738
char gNoSignalsMarker[]
Definition: ftp.c:14
#define kNoFirstSelect
Definition: sio.h:52
int errno
__u16 time
Definition: mkdosfs.c:366
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
#define Sjmp_buf
Definition: sio.h:41
#define kFullBufferRequired
Definition: sio.h:50
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
time_t now
Definition: finger.c:65
smooth NULL
Definition: ftsmooth.c:416
unsigned long tv_usec
Definition: linux.h:1739
#define kTimeoutErr
Definition: sio.h:58
GLsizeiptr size
Definition: glext.h:5919
static char UNUSED(gSioVersion[])
#define SIGPIPE
Definition: signal.h:35
#define SSetjmp(a)
Definition: sio.h:39
#define SELECT_TYPE_ARG5
Definition: wincfg.h:7
#define forever
Definition: ncftp.h:73
#define kBrokenPipeErr
Definition: sio.h:59
#define SETWSATIMEOUTERR
Definition: sio.h:120
__kernel_time_t time_t
Definition: linux.h:252
void(*)(int) SSignal(int signum, void(*handler)(int))
Definition: sio.h:237
#define kFullBufferRequiredExceptLast
Definition: sio.h:51
#define ETIMEDOUT
Definition: errno.h:121
#define ss
Definition: i386-dis.c:432
GLuint64EXT * result
Definition: glext.h:11304
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
void(* sio_sigproc_t)(int)
Definition: sio.h:123
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
void SIOHandler(int)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31