213 int _rtl_read(); |
213 int _rtl_read(); |
214 int _rtl_write(); |
214 int _rtl_write(); |
215 |
215 |
216 # define READ(ret,f, cp, n, handleType) \ |
216 # define READ(ret,f, cp, n, handleType) \ |
217 { int __res;\ |
217 { int __res;\ |
218 HANDLE h; \ |
218 HANDLE h; \ |
219 h = _get_osfhandle(fileno(f)); \ |
219 h = _get_osfhandle(fileno(f)); \ |
220 if ((handleType == @symbol(socketFilePointer)) \ |
220 if ((handleType == @symbol(socketFilePointer)) \ |
221 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
221 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
222 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
222 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
223 } else { \ |
223 } else { \ |
224 (ret) = __STX_C_NOINT_CALL3("_rtl_read", _rtl_read, fileno(f), (cp), (n));\ |
224 (ret) = __STX_C_NOINT_CALL3("_rtl_read", _rtl_read, fileno(f), (cp), (n));\ |
225 } \ |
225 } \ |
226 } |
226 } |
227 |
227 |
228 # define WRITE(ret,f, cp, n, handleType) \ |
228 # define WRITE(ret,f, cp, n, handleType) \ |
229 { int __res;\ |
229 { int __res;\ |
230 HANDLE h; \ |
230 HANDLE h; \ |
231 h = _get_osfhandle(fileno(f)); \ |
231 h = _get_osfhandle(fileno(f)); \ |
232 if ((handleType == @symbol(socketFilePointer)) \ |
232 if ((handleType == @symbol(socketFilePointer)) \ |
233 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
233 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
234 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
234 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
235 } else { \ |
235 } else { \ |
236 (ret) = __STX_C_NOINT_CALL3("_rtl_write", _rtl_write, fileno(f), (cp), (n));\ |
236 (ret) = __STX_C_NOINT_CALL3("_rtl_write", _rtl_write, fileno(f), (cp), (n));\ |
237 } \ |
237 } \ |
238 } |
238 } |
239 |
239 |
240 # else /* MSC */ |
240 # else /* MSC */ |
241 |
241 |
242 # define READ(ret,f, cp, n, handleType) \ |
242 # define READ(ret,f, cp, n, handleType) \ |
243 { int __res;\ |
243 { int __res;\ |
244 int fd; \ |
244 int fd; \ |
245 HANDLE h; \ |
245 HANDLE h; \ |
246 fd = fileno(f); \ |
246 fd = fileno(f); \ |
247 if ((handleType == @symbol(socketFileDescriptor)) \ |
247 if ((handleType == @symbol(socketFileDescriptor)) \ |
248 || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \ |
248 || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \ |
249 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, fd, (cp), (n), 0);\ |
249 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, fd, (cp), (n), 0);\ |
250 } else { \ |
250 } else { \ |
251 h = _get_osfhandle(fd); \ |
251 h = _get_osfhandle(fd); \ |
252 if ((handleType == @symbol(socketFilePointer)) \ |
252 if ((handleType == @symbol(socketFilePointer)) \ |
253 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
253 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
254 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
254 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
255 } else { \ |
255 } else { \ |
256 (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\ |
256 (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\ |
257 if (ret) \ |
257 if (ret) \ |
258 ret = __res; \ |
258 ret = __res; \ |
259 } \ |
259 } \ |
260 } \ |
260 } \ |
261 } |
261 } |
262 # define WRITE(ret,f, cp, n, handleType) \ |
262 # define WRITE(ret,f, cp, n, handleType) \ |
263 { int __res;\ |
263 { int __res;\ |
264 int fd; \ |
264 int fd; \ |
265 HANDLE h; \ |
265 HANDLE h; \ |
266 fd = fileno(f); \ |
266 fd = fileno(f); \ |
267 if ((handleType == @symbol(socketFileDescriptor)) \ |
267 if ((handleType == @symbol(socketFileDescriptor)) \ |
268 || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \ |
268 || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \ |
269 (ret) = __STX_WSA_NOINT_CALL4("send", send, fd, (cp), (n), 0);\ |
269 (ret) = __STX_WSA_NOINT_CALL4("send", send, fd, (cp), (n), 0);\ |
270 } else {\ |
270 } else {\ |
271 h = _get_osfhandle(fd); \ |
271 h = _get_osfhandle(fd); \ |
272 if ((handleType == @symbol(socketFilePointer)) \ |
272 if ((handleType == @symbol(socketFilePointer)) \ |
273 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
273 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
274 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
274 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
275 } else {\ |
275 } else {\ |
276 (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\ |
276 (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\ |
277 if (ret) \ |
277 if (ret) \ |
278 ret = __res; \ |
278 ret = __res; \ |
279 } \ |
279 } \ |
280 } \ |
280 } \ |
281 } |
281 } |
282 # endif /* MSC */ |
282 # endif /* MSC */ |
283 |
283 |
284 # define FFLUSH(fp) fflush(fp) |
284 # define FFLUSH(fp) fflush(fp) |
285 # undef STDIO_NEEDS_FSEEK |
285 # undef STDIO_NEEDS_FSEEK |
287 # define FILENO(f) fileno(f) |
287 # define FILENO(f) fileno(f) |
288 |
288 |
289 # define __READING__(f) \ |
289 # define __READING__(f) \ |
290 if ((__INST(didWrite) != false) \ |
290 if ((__INST(didWrite) != false) \ |
291 && (__INST(mode) == @symbol(readwrite))) { \ |
291 && (__INST(mode) == @symbol(readwrite))) { \ |
292 __INST(didWrite) = false; \ |
292 __INST(didWrite) = false; \ |
293 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
293 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
294 } |
294 } |
295 |
295 |
296 # define __WRITING__(f) \ |
296 # define __WRITING__(f) \ |
297 if ((__INST(didWrite) != true) \ |
297 if ((__INST(didWrite) != true) \ |
298 && (__INST(mode) == @symbol(readwrite))) { \ |
298 && (__INST(mode) == @symbol(readwrite))) { \ |
299 __INST(didWrite) = true; \ |
299 __INST(didWrite) = true; \ |
300 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
300 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
301 } |
301 } |
302 |
302 |
303 # define __UNGETC__(c, f, isBuffered) \ |
303 # define __UNGETC__(c, f, isBuffered) \ |
304 if (isBuffered) { \ |
304 if (isBuffered) { \ |
305 ungetc((c), (f)); \ |
305 ungetc((c), (f)); \ |
306 } else { \ |
306 } else { \ |
307 __INST(readAhead) = __mkSmallInteger((c)); \ |
307 __INST(readAhead) = __mkSmallInteger((c)); \ |
308 } |
308 } |
309 |
309 |
310 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
310 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
311 if (isBuffered) { \ |
311 if (isBuffered) { \ |
312 for (;;) { \ |
312 for (;;) { \ |
313 CLEAR_ERRNO; \ |
313 CLEAR_ERRNO; \ |
314 (ret) = getc(f); \ |
314 (ret) = getc(f); \ |
315 if ((ret) >= 0) { \ |
315 if ((ret) >= 0) { \ |
316 *(buf) = (ret); \ |
316 *(buf) = (ret); \ |
317 (ret) = 1; \ |
317 (ret) = 1; \ |
318 } else if (ferror(f)) { \ |
318 } else if (ferror(f)) { \ |
319 if (__threadErrno == EINTR) { \ |
319 if (__threadErrno == EINTR) { \ |
320 clearerr(f); \ |
320 clearerr(f); \ |
321 continue; \ |
321 continue; \ |
322 } \ |
322 } \ |
323 } else { \ |
323 } else { \ |
324 (ret) = 0; \ |
324 (ret) = 0; \ |
325 } \ |
325 } \ |
326 break; \ |
326 break; \ |
327 } \ |
327 } \ |
328 } else { \ |
328 } else { \ |
329 OBJ rA = __INST(readAhead); \ |
329 OBJ rA = __INST(readAhead); \ |
330 if (rA != nil) { \ |
330 if (rA != nil) { \ |
331 *(buf) = (char)__intVal(rA); \ |
331 *(buf) = (char)__intVal(rA); \ |
332 __INST(readAhead) = nil; \ |
332 __INST(readAhead) = nil; \ |
333 (ret) = 1; \ |
333 (ret) = 1; \ |
334 } else { \ |
334 } else { \ |
335 for (;;) { \ |
335 for (;;) { \ |
336 CLEAR_ERRNO; \ |
336 CLEAR_ERRNO; \ |
337 READ(ret,f, buf, 1, handleType); \ |
337 READ(ret,f, buf, 1, handleType); \ |
338 if ((ret) >= 0 || __threadErrno != EINTR) \ |
338 if ((ret) >= 0 || __threadErrno != EINTR) \ |
339 break; \ |
339 break; \ |
340 } \ |
340 } \ |
341 } \ |
341 } \ |
342 } |
342 } |
343 |
343 |
344 /* |
344 /* |
345 * read_bytes into a c-buffer |
345 * read_bytes into a c-buffer |
346 * (which may NOT move) |
346 * (which may NOT move) |
347 */ |
347 */ |
348 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
348 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
349 (ret) = 0; \ |
349 (ret) = 0; \ |
350 if (isBuffered) { \ |
350 if (isBuffered) { \ |
351 int __offs = 0; \ |
351 int __offs = 0; \ |
352 while (__offs < (cnt)) { \ |
352 while (__offs < (cnt)) { \ |
353 CLEAR_ERRNO; \ |
353 CLEAR_ERRNO; \ |
354 (ret) = getc(f); \ |
354 (ret) = getc(f); \ |
355 if ((ret) < 0) { \ |
355 if ((ret) < 0) { \ |
356 if (ferror(f)) { \ |
356 if (ferror(f)) { \ |
357 if (__threadErrno == EINTR) { \ |
357 if (__threadErrno == EINTR) { \ |
358 clearerr(f); \ |
358 clearerr(f); \ |
359 continue; \ |
359 continue; \ |
360 } \ |
360 } \ |
361 } else { \ |
361 } else { \ |
362 (ret) = 0; \ |
362 (ret) = 0; \ |
363 } \ |
363 } \ |
364 break; \ |
364 break; \ |
365 } \ |
365 } \ |
366 (buf)[__offs++] = (ret); \ |
366 (buf)[__offs++] = (ret); \ |
367 } \ |
367 } \ |
368 if (__offs > 0) \ |
368 if (__offs > 0) \ |
369 (ret) = __offs; \ |
369 (ret) = __offs; \ |
370 } else { \ |
370 } else { \ |
371 int __offs = 0; \ |
371 int __offs = 0; \ |
372 \ |
372 \ |
373 while (__offs < (cnt)) { \ |
373 while (__offs < (cnt)) { \ |
374 OBJ rA = __INST(readAhead); \ |
374 OBJ rA = __INST(readAhead); \ |
375 if (rA != nil) { \ |
375 if (rA != nil) { \ |
376 (buf)[__offs] = __intVal(rA); \ |
376 (buf)[__offs] = __intVal(rA); \ |
377 __INST(readAhead) = nil; \ |
377 __INST(readAhead) = nil; \ |
378 (ret) = 1; \ |
378 (ret) = 1; \ |
379 } else { \ |
379 } else { \ |
380 CLEAR_ERRNO; \ |
380 CLEAR_ERRNO; \ |
381 READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
381 READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
382 if ((ret) <= 0) { \ |
382 if ((ret) <= 0) { \ |
383 if ((ret) < 0 && __threadErrno == EINTR) { \ |
383 if ((ret) < 0 && __threadErrno == EINTR) { \ |
384 continue; \ |
384 continue; \ |
385 } \ |
385 } \ |
386 break; \ |
386 break; \ |
387 } \ |
387 } \ |
388 } \ |
388 } \ |
389 __offs += (ret); \ |
389 __offs += (ret); \ |
390 } \ |
390 } \ |
391 if (__offs > 0) \ |
391 if (__offs > 0) \ |
392 (ret) = __offs; \ |
392 (ret) = __offs; \ |
393 } |
393 } |
394 |
394 |
395 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
395 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
396 { \ |
396 { \ |
397 int __offs = 0; \ |
397 int __offs = 0; \ |
398 int oldFlags; \ |
398 int oldFlags; \ |
399 \ |
399 \ |
400 (ret) = 0; \ |
400 (ret) = 0; \ |
401 if (isBuffered) { \ |
401 if (isBuffered) { \ |
402 while (__offs < (cnt)) { \ |
402 while (__offs < (cnt)) { \ |
403 CLEAR_ERRNO; \ |
403 CLEAR_ERRNO; \ |
404 (ret) = getc(f); \ |
404 (ret) = getc(f); \ |
405 if ((ret) < 0) { \ |
405 if ((ret) < 0) { \ |
406 if (ferror(f)) { \ |
406 if (ferror(f)) { \ |
407 if (__threadErrno == EINTR) { \ |
407 if (__threadErrno == EINTR) { \ |
408 clearerr(f); \ |
408 clearerr(f); \ |
409 continue; \ |
409 continue; \ |
410 } \ |
410 } \ |
411 } else { \ |
411 } else { \ |
412 (ret) = 0; \ |
412 (ret) = 0; \ |
413 } \ |
413 } \ |
414 break; \ |
414 break; \ |
415 } \ |
415 } \ |
416 (buf)[__offs++] = (ret); \ |
416 (buf)[__offs++] = (ret); \ |
417 } \ |
417 } \ |
418 if (__offs > 0) \ |
418 if (__offs > 0) \ |
419 (ret) = __offs; \ |
419 (ret) = __offs; \ |
420 } else { \ |
420 } else { \ |
421 while (__offs < (cnt)) { \ |
421 while (__offs < (cnt)) { \ |
422 OBJ rA = __INST(readAhead); \ |
422 OBJ rA = __INST(readAhead); \ |
423 if (rA != nil) { \ |
423 if (rA != nil) { \ |
424 (buf)[__offs] = __intVal(rA); \ |
424 (buf)[__offs] = __intVal(rA); \ |
425 __INST(readAhead) = nil; \ |
425 __INST(readAhead) = nil; \ |
426 (ret) = 1; \ |
426 (ret) = 1; \ |
427 __offs += (ret); \ |
427 __offs += (ret); \ |
428 continue; \ |
428 continue; \ |
429 } \ |
429 } \ |
430 CLEAR_ERRNO; \ |
430 CLEAR_ERRNO; \ |
431 { \ |
431 { \ |
432 int res; \ |
432 int res; \ |
433 if ((handleType == @symbol(socketFilePointer)) \ |
433 if ((handleType == @symbol(socketFilePointer)) \ |
434 || ((handleType == nil) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0))) { \ |
434 || ((handleType == nil) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0))) { \ |
435 if (res > 0) { \ |
435 if (res > 0) { \ |
436 if (res > ((cnt)-__offs)) \ |
436 if (res > ((cnt)-__offs)) \ |
437 res = (cnt)-__offs; \ |
437 res = (cnt)-__offs; \ |
438 READ(ret,f, (buf)+__offs, res, handleType); \ |
438 READ(ret,f, (buf)+__offs, res, handleType); \ |
439 } else { \ |
439 } else { \ |
440 (ret) = 0; \ |
440 (ret) = 0; \ |
441 } \ |
441 } \ |
442 } else if ((handleType == @symbol(pipeFilePointer)) \ |
442 } else if ((handleType == @symbol(pipeFilePointer)) \ |
443 || ((handleType == nil) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)))) { \ |
443 || ((handleType == nil) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)))) { \ |
444 if (res > 0) { \ |
444 if (res > 0) { \ |
445 if (res > ((cnt)-__offs)) \ |
445 if (res > ((cnt)-__offs)) \ |
446 res = (cnt)-__offs; \ |
446 res = (cnt)-__offs; \ |
447 READ(ret,f, (buf)+__offs, res, handleType); \ |
447 READ(ret,f, (buf)+__offs, res, handleType); \ |
448 } else \ |
448 } else \ |
449 ret = 0; \ |
449 ret = 0; \ |
450 } else { \ |
450 } else { \ |
451 READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
451 READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
452 } \ |
452 } \ |
453 } \ |
453 } \ |
454 if ((ret) < 0) { \ |
454 if ((ret) < 0) { \ |
455 if (__threadErrno == EINTR) { \ |
455 if (__threadErrno == EINTR) { \ |
456 continue; \ |
456 continue; \ |
457 } \ |
457 } \ |
458 break; \ |
458 break; \ |
459 } \ |
459 } \ |
460 __offs += (ret); \ |
460 __offs += (ret); \ |
461 break; \ |
461 break; \ |
462 } \ |
462 } \ |
463 if (__offs > 0) \ |
463 if (__offs > 0) \ |
464 (ret) = __offs; \ |
464 (ret) = __offs; \ |
465 } \ |
465 } \ |
466 } |
466 } |
467 |
467 |
468 # define IO_BUFFER_SIZE (8*1024) |
468 # define IO_BUFFER_SIZE (8*1024) |
469 |
469 |
470 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
470 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
471 { \ |
471 { \ |
472 int __ooffs = obj_offs; \ |
472 int __ooffs = obj_offs; \ |
473 int __offs = 0; \ |
473 int __offs = 0; \ |
474 char *buf = (char *)(obj); \ |
474 char *buf = (char *)(obj); \ |
475 \ |
475 \ |
476 (ret) = 0; \ |
476 (ret) = 0; \ |
477 if (isBuffered) { \ |
477 if (isBuffered) { \ |
478 while (__offs < (cnt)) { \ |
478 while (__offs < (cnt)) { \ |
479 CLEAR_ERRNO; \ |
479 CLEAR_ERRNO; \ |
480 (ret) = getc(f); \ |
480 (ret) = getc(f); \ |
481 if ((ret) < 0) { \ |
481 if ((ret) < 0) { \ |
482 if (ferror(f)) { \ |
482 if (ferror(f)) { \ |
483 if (__threadErrno == EINTR) { \ |
483 if (__threadErrno == EINTR) { \ |
484 clearerr(f); \ |
484 clearerr(f); \ |
485 /* refetch */ \ |
485 /* refetch */ \ |
486 buf = (char *)(obj); \ |
486 buf = (volatile char *)(obj); \ |
487 continue; \ |
487 continue; \ |
488 } \ |
488 } \ |
489 } else { \ |
489 } else { \ |
490 (ret) = 0; \ |
490 (ret) = 0; \ |
491 } \ |
491 } \ |
492 break; \ |
492 break; \ |
493 } \ |
493 } \ |
494 (buf)[__ooffs+__offs] = (ret); \ |
494 (buf)[__ooffs+__offs] = (ret); \ |
495 __offs++; \ |
495 __offs++; \ |
496 } \ |
496 } \ |
497 if (__offs > 0) \ |
497 if (__offs > 0) \ |
498 (ret) = __offs; \ |
498 (ret) = __offs; \ |
499 } else { \ |
499 } else { \ |
500 while (__offs < (cnt)) { \ |
500 while (__offs < (cnt)) { \ |
501 char __buf[IO_BUFFER_SIZE]; \ |
501 char __buf[IO_BUFFER_SIZE]; \ |
502 OBJ rA = __INST(readAhead); \ |
502 OBJ rA = __INST(readAhead); \ |
503 if (rA != nil) { \ |
503 if (rA != nil) { \ |
504 (buf)[__ooffs+__offs] = __intVal(rA); \ |
504 (buf)[__ooffs+__offs] = __intVal(rA); \ |
505 __INST(readAhead) = nil; \ |
505 __INST(readAhead) = nil; \ |
506 (ret) = 1; \ |
506 (ret) = 1; \ |
507 } else { \ |
507 } else { \ |
508 int l; \ |
508 int l; \ |
509 CLEAR_ERRNO; \ |
509 CLEAR_ERRNO; \ |
510 l = (cnt)-__offs; \ |
510 l = (cnt)-__offs; \ |
511 if ( l > IO_BUFFER_SIZE) \ |
511 if ( l > IO_BUFFER_SIZE) \ |
512 l = IO_BUFFER_SIZE; \ |
512 l = IO_BUFFER_SIZE; \ |
513 READ(ret,f, __buf, l, handleType); \ |
513 READ(ret,f, __buf, l, handleType); \ |
514 if ((ret) <= 0) { \ |
514 if ((ret) <= 0) { \ |
515 if ((ret) < 0 && __threadErrno == EINTR) { \ |
515 if ((ret) < 0 && __threadErrno == EINTR) { \ |
516 continue; \ |
516 continue; \ |
517 } \ |
517 } \ |
518 break; \ |
518 break; \ |
519 } \ |
519 } \ |
520 } \ |
520 } \ |
521 if( (ret) > 0 ) { \ |
521 if( (ret) > 0 ) { \ |
522 /* refetch */ \ |
522 /* refetch */ \ |
523 buf = (volatile char *)(obj); \ |
523 buf = (volatile char *)(obj); \ |
524 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
524 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
525 __offs += (ret); \ |
525 __offs += (ret); \ |
526 } else { \ |
526 } else { \ |
527 (ret) = 0; \ |
527 (ret) = 0; \ |
528 } \ |
528 } \ |
529 } \ |
529 } \ |
530 if (__offs > 0) \ |
530 if (__offs > 0) \ |
531 (ret) = __offs; \ |
531 (ret) = __offs; \ |
532 } \ |
532 } \ |
533 } |
533 } |
534 |
534 |
535 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)\ |
535 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)\ |
536 { \ |
536 { \ |
537 int __ooffs = obj_offs; \ |
537 int __ooffs = obj_offs; \ |
538 int __offs = 0; \ |
538 int __offs = 0; \ |
539 char *buf = (char *)(obj); \ |
539 char *buf = (char *)(obj); \ |
540 \ |
540 \ |
541 (ret) = 0; \ |
541 (ret) = 0; \ |
542 if (isBuffered) { \ |
542 if (isBuffered) { \ |
543 while (__offs < (cnt)) { \ |
543 while (__offs < (cnt)) { \ |
544 CLEAR_ERRNO; \ |
544 CLEAR_ERRNO; \ |
545 (ret) = getc(f); \ |
545 (ret) = getc(f); \ |
546 if ((ret) < 0) { \ |
546 if ((ret) < 0) { \ |
547 if (ferror(f)) { \ |
547 if (ferror(f)) { \ |
548 if (__threadErrno == EINTR) { \ |
548 if (__threadErrno == EINTR) { \ |
549 clearerr(f); \ |
549 clearerr(f); \ |
550 /* refetch */ \ |
550 /* refetch */ \ |
551 buf = (char *)(obj); \ |
551 buf = (volatile char *)(obj);\ |
552 continue; \ |
552 continue; \ |
553 } \ |
553 } \ |
554 } else { \ |
554 } else { \ |
555 (ret) = 0; \ |
555 (ret) = 0; \ |
556 } \ |
556 } \ |
557 break; \ |
557 break; \ |
558 } \ |
558 } \ |
559 (buf)[__ooffs+__offs] = (ret); \ |
559 (buf)[__ooffs+__offs] = (ret); \ |
560 __offs++; \ |
560 __offs++; \ |
561 } \ |
561 } \ |
562 if (__offs > 0) \ |
562 if (__offs > 0) \ |
563 (ret) = __offs; \ |
563 (ret) = __offs; \ |
564 } else { \ |
564 } else { \ |
565 while (__offs < (cnt)) { \ |
565 while (__offs < (cnt)) { \ |
566 char __buf[IO_BUFFER_SIZE]; \ |
566 char __buf[IO_BUFFER_SIZE]; \ |
567 OBJ rA = __INST(readAhead); \ |
567 OBJ rA = __INST(readAhead); \ |
568 if (rA != nil) { \ |
568 if (rA != nil) { \ |
569 (buf)[__ooffs+__offs] = __intVal(rA);\ |
569 (buf)[__ooffs+__offs] = __intVal(rA);\ |
570 __INST(readAhead) = nil; \ |
570 __INST(readAhead) = nil; \ |
571 (ret) = 1; \ |
571 (ret) = 1; \ |
572 __offs += (ret); \ |
572 __offs += (ret); \ |
573 continue; \ |
573 continue; \ |
574 } \ |
574 } \ |
575 { \ |
575 { \ |
576 int l; \ |
576 int l; \ |
577 int res; \ |
577 int res; \ |
578 CLEAR_ERRNO; \ |
578 CLEAR_ERRNO; \ |
579 l = (cnt)-__offs; \ |
579 l = (cnt)-__offs; \ |
580 if ( l > IO_BUFFER_SIZE) \ |
580 if ( l > IO_BUFFER_SIZE) \ |
581 l = IO_BUFFER_SIZE; \ |
581 l = IO_BUFFER_SIZE; \ |
582 if (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0) { \ |
582 if (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0) { \ |
583 if (res > 0) { \ |
583 if (res > 0) { \ |
584 if (res > l) \ |
584 if (res > l) \ |
585 res = l; \ |
585 res = l; \ |
586 READ(ret,f, __buf, res, handleType); \ |
586 READ(ret,f, __buf, res, handleType); \ |
587 } else { \ |
587 } else { \ |
588 (ret) = 0; \ |
588 (ret) = 0; \ |
589 } \ |
589 } \ |
590 } else if (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)) { \ |
590 } else if (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)) { \ |
591 if (res > 0) { \ |
591 if (res > 0) { \ |
592 if (res > l) \ |
592 if (res > l) \ |
593 res = l; \ |
593 res = l; \ |
594 READ(ret,f, __buf, res, handleType); \ |
594 READ(ret,f, __buf, res, handleType); \ |
595 } else \ |
595 } else \ |
596 (ret) = 0; \ |
596 (ret) = 0; \ |
597 } else { \ |
597 } else { \ |
598 READ(ret,f, __buf, l, handleType); \ |
598 READ(ret,f, __buf, l, handleType); \ |
599 } \ |
599 } \ |
600 if ((ret) < 0 && __threadErrno == EINTR) { \ |
600 if ((ret) < 0 && __threadErrno == EINTR) { \ |
601 continue; \ |
601 continue; \ |
602 } \ |
602 } \ |
603 } \ |
603 } \ |
604 if( (ret) > 0 ) { \ |
604 if( (ret) > 0 ) { \ |
605 /* refetch */ \ |
605 /* refetch */ \ |
606 buf = (volatile char *)(obj); \ |
606 buf = (volatile char *)(obj); \ |
607 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
607 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
608 __offs += (ret); \ |
608 __offs += (ret); \ |
609 } else { \ |
609 } else { \ |
610 (ret) = 0; \ |
610 (ret) = 0; \ |
611 } \ |
611 } \ |
612 break; \ |
612 break; \ |
613 } \ |
613 } \ |
614 if (__offs > 0) \ |
614 if (__offs > 0) \ |
615 (ret) = __offs; \ |
615 (ret) = __offs; \ |
616 } \ |
616 } \ |
617 } |
617 } |
618 |
618 |
619 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
619 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
620 if (isBuffered) { \ |
620 if (isBuffered) { \ |
621 for (;;) { \ |
621 for (;;) { \ |
622 CLEAR_ERRNO; \ |
622 CLEAR_ERRNO; \ |
623 ret = putc(*(buf), f); \ |
623 ret = putc(*(buf), f); \ |
624 if ((ret) >= 0) { \ |
624 if ((ret) >= 0) { \ |
625 (ret) = 1; \ |
625 (ret) = 1; \ |
626 } else if (ferror(f)) { \ |
626 } else if (ferror(f)) { \ |
627 if (__threadErrno == EINTR) { \ |
627 if (__threadErrno == EINTR) { \ |
628 clearerr(f); \ |
628 clearerr(f); \ |
629 continue; \ |
629 continue; \ |
630 } \ |
630 } \ |
631 } else \ |
631 } else \ |
632 (ret) = 0; \ |
632 (ret) = 0; \ |
633 break; \ |
633 break; \ |
634 } \ |
634 } \ |
635 } else { \ |
635 } else { \ |
636 for (;;) { \ |
636 for (;;) { \ |
637 CLEAR_ERRNO; \ |
637 CLEAR_ERRNO; \ |
638 WRITE(ret,f, buf, 1, handleType); \ |
638 WRITE(ret,f, buf, 1, handleType); \ |
639 if ((ret) >= 0 || __threadErrno != EINTR) \ |
639 if ((ret) >= 0 || __threadErrno != EINTR) \ |
640 break; \ |
640 break; \ |
641 } \ |
641 } \ |
642 } |
642 } |
643 |
643 |
644 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
644 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
645 (ret) = 0; \ |
645 (ret) = 0; \ |
646 if (isBuffered) { \ |
646 if (isBuffered) { \ |
647 int __offs = 0; \ |
647 int __offs = 0; \ |
648 while (__offs < (cnt)) { \ |
648 while (__offs < (cnt)) { \ |
649 CLEAR_ERRNO; \ |
649 CLEAR_ERRNO; \ |
650 ret = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
650 ret = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
651 if ((ret) <= 0) { \ |
651 if ((ret) <= 0) { \ |
652 if (ferror(f)) { \ |
652 if (ferror(f)) { \ |
653 if (__threadErrno == EINTR) { \ |
653 if (__threadErrno == EINTR) { \ |
654 clearerr(f); \ |
654 clearerr(f); \ |
655 continue; \ |
655 continue; \ |
656 } \ |
656 } \ |
657 break; \ |
657 break; \ |
658 } else { \ |
658 } else { \ |
659 (ret) = 0; \ |
659 (ret) = 0; \ |
660 } \ |
660 } \ |
661 } \ |
661 } \ |
662 __offs += (ret); \ |
662 __offs += (ret); \ |
663 } \ |
663 } \ |
664 if (__offs > 0) \ |
664 if (__offs > 0) \ |
665 (ret) = __offs; \ |
665 (ret) = __offs; \ |
666 } else { \ |
666 } else { \ |
667 int __offs = 0; \ |
667 int __offs = 0; \ |
668 while (__offs < (cnt)) { \ |
668 while (__offs < (cnt)) { \ |
669 CLEAR_ERRNO; \ |
669 CLEAR_ERRNO; \ |
670 WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
670 WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
671 if (ret <= 0) { \ |
671 if (ret <= 0) { \ |
672 if (ret < 0 && __threadErrno == EINTR) { \ |
672 if (ret < 0 && __threadErrno == EINTR) { \ |
673 continue; \ |
673 continue; \ |
674 } \ |
674 } \ |
675 break; \ |
675 break; \ |
676 } \ |
676 } \ |
677 __offs += (ret); \ |
677 __offs += (ret); \ |
678 } \ |
678 } \ |
679 if (__offs > 0) \ |
679 if (__offs > 0) \ |
680 (ret) = __offs; \ |
680 (ret) = __offs; \ |
681 } |
681 } |
682 |
682 |
683 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
683 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
684 { \ |
684 { \ |
685 int __ooffs = obj_offs; \ |
685 int __ooffs = obj_offs; \ |
686 int __offs = 0; \ |
686 int __offs = 0; \ |
687 char *buf = (char *)(obj); \ |
687 char *buf = (char *)(obj); \ |
688 \ |
688 \ |
689 (ret) = 0; \ |
689 (ret) = 0; \ |
690 if (isBuffered) { \ |
690 if (isBuffered) { \ |
691 while (__offs < (cnt)) { \ |
691 while (__offs < (cnt)) { \ |
692 CLEAR_ERRNO; \ |
692 CLEAR_ERRNO; \ |
693 ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
693 ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
694 if ((ret) <= 0) { \ |
694 if ((ret) <= 0) { \ |
695 if (ferror(f)) { \ |
695 if (ferror(f)) { \ |
696 if (__threadErrno == EINTR) { \ |
696 if (__threadErrno == EINTR) { \ |
697 /* refetch */ \ |
697 /* refetch */ \ |
698 buf = (char *)(obj); \ |
698 buf = (volatile char *)(obj); \ |
699 clearerr(f); \ |
699 clearerr(f); \ |
700 continue; \ |
700 continue; \ |
701 } \ |
701 } \ |
702 break; \ |
702 break; \ |
703 } else { \ |
703 } else { \ |
704 (ret) = 0; \ |
704 (ret) = 0; \ |
705 } \ |
705 } \ |
706 } \ |
706 } \ |
707 __offs += (ret); \ |
707 __offs += (ret); \ |
708 } \ |
708 } \ |
709 if (__offs > 0) \ |
709 if (__offs > 0) \ |
710 (ret) = __offs; \ |
710 (ret) = __offs; \ |
711 } else { \ |
711 } else { \ |
712 while (__offs < (cnt)) { \ |
712 while (__offs < (cnt)) { \ |
713 char __buf[IO_BUFFER_SIZE]; \ |
713 char __buf[IO_BUFFER_SIZE]; \ |
714 int l; \ |
714 int l; \ |
715 CLEAR_ERRNO; \ |
715 CLEAR_ERRNO; \ |
716 l = (cnt)-__offs; \ |
716 l = (cnt)-__offs; \ |
717 if ( l > IO_BUFFER_SIZE) \ |
717 if ( l > IO_BUFFER_SIZE) \ |
718 l = IO_BUFFER_SIZE; \ |
718 l = IO_BUFFER_SIZE; \ |
719 /* refetch */ \ |
719 /* refetch */ \ |
720 buf = (volatile char *)(obj); \ |
720 buf = (volatile char *)(obj); \ |
721 memcpy(__buf,(buf)+__ooffs+__offs,l); \ |
721 memcpy(__buf,(buf)+__ooffs+__offs,l); \ |
722 WRITE(ret,f, __buf, l, handleType); \ |
722 WRITE(ret,f, __buf, l, handleType); \ |
723 if (ret <= 0) { \ |
723 if (ret <= 0) { \ |
724 if (ret < 0 && __threadErrno == EINTR) { \ |
724 if (ret < 0 && __threadErrno == EINTR) { \ |
725 continue; \ |
725 continue; \ |
726 } \ |
726 } \ |
727 break; \ |
727 break; \ |
728 } \ |
728 } \ |
729 __offs += (ret); \ |
729 __offs += (ret); \ |
730 } \ |
730 } \ |
731 if (__offs > 0) \ |
731 if (__offs > 0) \ |
732 (ret) = __offs; \ |
732 (ret) = __offs; \ |
733 } \ |
733 } \ |
734 } |
734 } |
735 |
735 |
736 #else /* no WIN32 */ |
736 #else /* no WIN32 */ |
737 |
737 |
738 # define __READING__(f) \ |
738 # define __READING__(f) \ |
739 if ((__INST(didWrite) != false) \ |
739 if ((__INST(didWrite) != false) \ |
740 && (__INST(mode) == @symbol(readwrite))) { \ |
740 && (__INST(mode) == @symbol(readwrite))) { \ |
741 __INST(didWrite) = false; \ |
741 __INST(didWrite) = false; \ |
742 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
742 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
743 } |
743 } |
744 |
744 |
745 # define __WRITING__(f) \ |
745 # define __WRITING__(f) \ |
746 if ((__INST(didWrite) != true) \ |
746 if ((__INST(didWrite) != true) \ |
747 && (__INST(mode) == @symbol(readwrite))) { \ |
747 && (__INST(mode) == @symbol(readwrite))) { \ |
748 __INST(didWrite) = true; \ |
748 __INST(didWrite) = true; \ |
749 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
749 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
750 } |
750 } |
751 |
751 |
752 |
752 |
753 # ifdef NO_STDIO |
753 # ifdef NO_STDIO |
754 # define __UNGETC__(c, f, isBuffered) \ |
754 # define __UNGETC__(c, f, isBuffered) \ |
755 __INST(readAhead) = __mkSmallInteger((c)); |
755 __INST(readAhead) = __mkSmallInteger((c)); |
756 # else /* use STDIO */ |
756 # else /* use STDIO */ |
757 # define __UNGETC__(c, f, isBuffered) \ |
757 # define __UNGETC__(c, f, isBuffered) \ |
758 if (isBuffered) { \ |
758 if (isBuffered) { \ |
759 ungetc((c), (f)); \ |
759 ungetc((c), (f)); \ |
760 } else { \ |
760 } else { \ |
761 __INST(readAhead) = __mkSmallInteger((c)); \ |
761 __INST(readAhead) = __mkSmallInteger((c)); \ |
762 } |
762 } |
763 # endif /* use STDIO */ |
763 # endif /* use STDIO */ |
764 |
764 |
765 # ifdef NO_STDIO |
765 # ifdef NO_STDIO |
766 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
766 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
767 { \ |
767 { \ |
768 OBJ rA = __INST(readAhead); \ |
768 OBJ rA = __INST(readAhead); \ |
769 if (rA != nil) { \ |
769 if (rA != nil) { \ |
770 *(buf) = __intVal(rA); \ |
770 *(buf) = __intVal(rA); \ |
771 DEBUGBUFFER(buf); \ |
771 DEBUGBUFFER(buf); \ |
772 __INST(readAhead) = nil; \ |
772 __INST(readAhead) = nil; \ |
773 (ret) = 1; \ |
773 (ret) = 1; \ |
774 } else { \ |
774 } else { \ |
775 for (;;) { \ |
775 for (;;) { \ |
776 CLEAR_ERRNO; \ |
776 CLEAR_ERRNO; \ |
777 (ret) = READ(f, buf, 1, handleType); \ |
777 (ret) = READ(f, buf, 1, handleType); \ |
778 DEBUGBUFFER(buf); \ |
778 DEBUGBUFFER(buf); \ |
779 if ((ret) >= 0 || __threadErrno != EINTR) \ |
779 if ((ret) >= 0 || __threadErrno != EINTR) \ |
780 break; \ |
780 break; \ |
781 __HANDLE_INTERRUPTS__; \ |
781 __HANDLE_INTERRUPTS__; \ |
782 } \ |
782 } \ |
783 } \ |
783 } \ |
784 } |
784 } |
785 # else /* use STDIO */ |
785 # else /* use STDIO */ |
786 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
786 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
787 if (isBuffered) { \ |
787 if (isBuffered) { \ |
788 for (;;) { \ |
788 for (;;) { \ |
789 CLEAR_ERRNO; \ |
789 CLEAR_ERRNO; \ |
790 (ret) = getc(f); \ |
790 (ret) = getc(f); \ |
791 if ((ret) >= 0) { \ |
791 if ((ret) >= 0) { \ |
792 DEBUGBUFFER(buf); \ |
792 DEBUGBUFFER(buf); \ |
793 *(buf) = (ret); \ |
793 *(buf) = (ret); \ |
794 (ret) = 1; \ |
794 (ret) = 1; \ |
795 } else if (ferror(f)) { \ |
795 } else if (ferror(f)) { \ |
796 if (__threadErrno == EINTR) { \ |
796 if (__threadErrno == EINTR) { \ |
797 __HANDLE_INTERRUPTS__; \ |
797 __HANDLE_INTERRUPTS__; \ |
798 clearerr(f); \ |
798 clearerr(f); \ |
799 continue; \ |
799 continue; \ |
800 } \ |
800 } \ |
801 } else \ |
801 } else \ |
802 (ret) = 0; \ |
802 (ret) = 0; \ |
803 break; \ |
803 break; \ |
804 } \ |
804 } \ |
805 } else { \ |
805 } else { \ |
806 OBJ rA = __INST(readAhead); \ |
806 OBJ rA = __INST(readAhead); \ |
807 if (rA != nil) { \ |
807 if (rA != nil) { \ |
808 *(buf) = __intVal(rA); \ |
808 *(buf) = __intVal(rA); \ |
809 DEBUGBUFFER(buf); \ |
809 DEBUGBUFFER(buf); \ |
810 __INST(readAhead) = nil; \ |
810 __INST(readAhead) = nil; \ |
811 (ret) = 1; \ |
811 (ret) = 1; \ |
812 } else { \ |
812 } else { \ |
813 for (;;) { \ |
813 for (;;) { \ |
814 CLEAR_ERRNO; \ |
814 CLEAR_ERRNO; \ |
815 (ret) = read(fileno(f), buf, 1); \ |
815 (ret) = read(fileno(f), buf, 1); \ |
816 DEBUGBUFFER(buf); \ |
816 DEBUGBUFFER(buf); \ |
817 if ((ret) >= 0 || __threadErrno != EINTR) \ |
817 if ((ret) >= 0 || __threadErrno != EINTR) \ |
818 break; \ |
818 break; \ |
819 __HANDLE_INTERRUPTS__; \ |
819 __HANDLE_INTERRUPTS__; \ |
820 } \ |
820 } \ |
821 } \ |
821 } \ |
822 } |
822 } |
823 # endif /* use STDIO */ |
823 # endif /* use STDIO */ |
824 |
824 |
825 /* |
825 /* |
826 * read_bytes into a c-buffer |
826 * read_bytes into a c-buffer |
827 * (which may NOT move) |
827 * (which may NOT move) |
828 */ |
828 */ |
829 # ifdef NO_STDIO |
829 # ifdef NO_STDIO |
830 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
830 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
831 { \ |
831 { \ |
832 int __offs = 0, __cnt; \ |
832 int __offs = 0, __cnt; \ |
833 \ |
833 \ |
834 while (__offs < (cnt)) { \ |
834 while (__offs < (cnt)) { \ |
835 OBJ rA = __INST(readAhead); \ |
835 OBJ rA = __INST(readAhead); \ |
836 if (rA != nil) { \ |
836 if (rA != nil) { \ |
837 (buf)[__offs] = __intVal(rA); \ |
837 (buf)[__offs] = __intVal(rA); \ |
838 DEBUGBUFFER(buf); \ |
838 DEBUGBUFFER(buf); \ |
839 __INST(readAhead) = nil; \ |
839 __INST(readAhead) = nil; \ |
840 __offs++; \ |
840 __offs++; \ |
841 } else { \ |
841 } else { \ |
842 CLEAR_ERRNO; \ |
842 CLEAR_ERRNO; \ |
843 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
843 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
844 DEBUGBUFFER(buf); \ |
844 DEBUGBUFFER(buf); \ |
845 if (__cnt <= 0) { \ |
845 if (__cnt <= 0) { \ |
846 if (__cnt < 0 && __threadErrno == EINTR) { \ |
846 if (__cnt < 0 && __threadErrno == EINTR) { \ |
847 __HANDLE_INTERRUPTS__; \ |
847 __HANDLE_INTERRUPTS__; \ |
848 continue; \ |
848 continue; \ |
849 } \ |
849 } \ |
850 break; \ |
850 break; \ |
851 } \ |
851 } \ |
852 __offs += __cnt; \ |
852 __offs += __cnt; \ |
853 } \ |
853 } \ |
854 } \ |
854 } \ |
855 if (__offs > 0) \ |
855 if (__offs > 0) \ |
856 (ret) = __offs; \ |
856 (ret) = __offs; \ |
857 } |
857 } |
858 # else /* use STDIO */ |
858 # else /* use STDIO */ |
859 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
859 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
860 (ret) = 0; \ |
860 (ret) = 0; \ |
861 if (isBuffered) { \ |
861 if (isBuffered) { \ |
862 int __offs = 0; \ |
862 int __offs = 0; \ |
863 while (__offs < (cnt)) { \ |
863 while (__offs < (cnt)) { \ |
864 CLEAR_ERRNO; \ |
864 CLEAR_ERRNO; \ |
865 (ret) = getc(f); \ |
865 (ret) = getc(f); \ |
866 if ((ret) < 0) { \ |
866 if ((ret) < 0) { \ |
867 if (ferror(f)) { \ |
867 if (ferror(f)) { \ |
868 if (__threadErrno == EINTR) { \ |
868 if (__threadErrno == EINTR) { \ |
869 __HANDLE_INTERRUPTS__; \ |
869 __HANDLE_INTERRUPTS__; \ |
870 clearerr(f); \ |
870 clearerr(f); \ |
871 continue; \ |
871 continue; \ |
872 } \ |
872 } \ |
873 } else { \ |
873 } else { \ |
874 (ret) = 0; \ |
874 (ret) = 0; \ |
875 } \ |
875 } \ |
876 break; \ |
876 break; \ |
877 } \ |
877 } \ |
878 DEBUGBUFFER(buf); \ |
878 DEBUGBUFFER(buf); \ |
879 (buf)[__offs++] = (ret); \ |
879 (buf)[__offs++] = (ret); \ |
880 } \ |
880 } \ |
881 if (__offs > 0) \ |
881 if (__offs > 0) \ |
882 (ret) = __offs; \ |
882 (ret) = __offs; \ |
883 } else { \ |
883 } else { \ |
884 int __offs = 0, __cnt; \ |
884 int __offs = 0, __cnt; \ |
885 int fd = fileno(f); \ |
885 int fd = fileno(f); \ |
886 \ |
886 \ |
887 while (__offs < (cnt)) { \ |
887 while (__offs < (cnt)) { \ |
888 OBJ rA = __INST(readAhead); \ |
888 OBJ rA = __INST(readAhead); \ |
889 if (rA != nil) { \ |
889 if (rA != nil) { \ |
890 DEBUGBUFFER(buf); \ |
890 DEBUGBUFFER(buf); \ |
891 (buf)[__offs] = __intVal(rA); \ |
891 (buf)[__offs] = __intVal(rA); \ |
892 __INST(readAhead) = nil; \ |
892 __INST(readAhead) = nil; \ |
893 __offs++; \ |
893 __offs++; \ |
894 } else { \ |
894 } else { \ |
895 CLEAR_ERRNO; \ |
895 CLEAR_ERRNO; \ |
896 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
896 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
897 DEBUGBUFFER(buf); \ |
897 DEBUGBUFFER(buf); \ |
898 if (__cnt <= 0) { \ |
898 if (__cnt <= 0) { \ |
899 if (__cnt < 0 && __threadErrno == EINTR) { \ |
899 if (__cnt < 0 && __threadErrno == EINTR) { \ |
900 __HANDLE_INTERRUPTS__; \ |
900 __HANDLE_INTERRUPTS__; \ |
901 continue; \ |
901 continue; \ |
902 } \ |
902 } \ |
903 break; \ |
903 break; \ |
904 } \ |
904 } \ |
905 __offs += __cnt; \ |
905 __offs += __cnt; \ |
906 } \ |
906 } \ |
907 } \ |
907 } \ |
908 if (__offs > 0) \ |
908 if (__offs > 0) \ |
909 (ret) = __offs; \ |
909 (ret) = __offs; \ |
910 } |
910 } |
911 |
911 |
912 |
912 |
913 /* |
913 /* |
914 * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc... |
914 * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc... |
915 */ |
915 */ |
916 |
916 |
917 # if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY)) |
917 # if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY)) |
918 # define GETFLAGS(fd) \ |
918 # define GETFLAGS(fd) \ |
919 fcntl(fd, F_GETFL, 0); |
919 fcntl(fd, F_GETFL, 0); |
920 |
920 |
921 # define SETFLAGS(fd, flags) \ |
921 # define SETFLAGS(fd, flags) \ |
922 fcntl(fd, F_SETFL, flags) |
922 fcntl(fd, F_SETFL, flags) |
923 |
923 |
924 # if defined(O_NONBLOCK) |
924 # if defined(O_NONBLOCK) |
925 # define __STX_NONBLOCK_FLAG O_NONBLOCK |
925 # define __STX_NONBLOCK_FLAG O_NONBLOCK |
926 # else |
926 # else |
927 # if defined(O_NDELAY) |
927 # if defined(O_NDELAY) |
1050 { \ |
1050 { \ |
1051 int __ooffs = obj_offs; \ |
1051 int __ooffs = obj_offs; \ |
1052 int __offs = 0; \ |
1052 int __offs = 0; \ |
1053 int __cnt; \ |
1053 int __cnt; \ |
1054 char *buf = (char *)(obj); \ |
1054 char *buf = (char *)(obj); \ |
1055 \ |
1055 \ |
1056 (ret) = 0; \ |
1056 (ret) = 0; \ |
1057 if (isBuffered) { \ |
1057 if (isBuffered) { \ |
1058 while (__offs < (cnt)) { \ |
1058 while (__offs < (cnt)) { \ |
1059 CLEAR_ERRNO; \ |
1059 CLEAR_ERRNO; \ |
1060 (ret) = getc(f); \ |
1060 (ret) = getc(f); \ |
1061 if ((ret) < 0) { \ |
1061 if ((ret) < 0) { \ |
1062 if (ferror(f)) { \ |
1062 if (ferror(f)) { \ |
1063 if (__threadErrno == EINTR) { \ |
1063 if (__threadErrno == EINTR) { \ |
1064 __HANDLE_INTERRUPTS__; \ |
1064 __HANDLE_INTERRUPTS__; \ |
1065 clearerr(f); \ |
1065 clearerr(f); \ |
1066 /* refetch */ \ |
1066 /* refetch */ \ |
1067 buf = (char *)(obj); \ |
1067 buf = (volatile char *)(obj); \ |
1068 DEBUGBUFFER(buf); \ |
1068 DEBUGBUFFER(buf); \ |
1069 continue; \ |
1069 continue; \ |
1070 } \ |
1070 } \ |
1071 } else { \ |
1071 } else { \ |
1072 (ret) = 0; \ |
1072 (ret) = 0; \ |
1073 } \ |
1073 } \ |
1074 break; \ |
1074 break; \ |
1075 } \ |
1075 } \ |
1076 (buf)[__ooffs+__offs] = (ret); \ |
1076 (buf)[__ooffs+__offs] = (ret); \ |
1077 DEBUGBUFFER(buf); \ |
1077 DEBUGBUFFER(buf); \ |
1078 __offs++; \ |
1078 __offs++; \ |
1079 } \ |
1079 } \ |
1080 if (__offs > 0) \ |
1080 if (__offs > 0) \ |
1081 (ret) = __offs; \ |
1081 (ret) = __offs; \ |
1082 } else { \ |
1082 } else { \ |
1083 int fd = fileno(f); \ |
1083 int fd = fileno(f); \ |
1084 \ |
1084 \ |
1085 while (__offs < (cnt)) { \ |
1085 while (__offs < (cnt)) { \ |
1086 OBJ rA = __INST(readAhead); \ |
1086 OBJ rA = __INST(readAhead); \ |
1087 if (rA != nil) { \ |
1087 if (rA != nil) { \ |
1088 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1088 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1089 DEBUGBUFFER(buf); \ |
1089 DEBUGBUFFER(buf); \ |
1090 __INST(readAhead) = nil; \ |
1090 __INST(readAhead) = nil; \ |
1091 __offs++; \ |
1091 __offs++; \ |
1092 } else { \ |
1092 } else { \ |
1093 CLEAR_ERRNO; \ |
1093 CLEAR_ERRNO; \ |
1094 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1094 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1095 DEBUGBUFFER(buf); \ |
1095 DEBUGBUFFER(buf); \ |
1096 if (__cnt <= 0) { \ |
1096 if (__cnt <= 0) { \ |
1097 if (__cnt < 0 && __threadErrno == EINTR) { \ |
1097 if (__cnt < 0 && __threadErrno == EINTR) { \ |
1098 __HANDLE_INTERRUPTS__; \ |
1098 __HANDLE_INTERRUPTS__; \ |
1099 /* refetch */ \ |
1099 /* refetch */ \ |
1100 buf = (char *)(obj); \ |
1100 buf = (volatile char *)(obj); \ |
1101 continue; \ |
1101 continue; \ |
1102 } \ |
1102 } \ |
1103 break; \ |
1103 break; \ |
1104 } \ |
1104 } \ |
1105 __offs += __cnt; \ |
1105 __offs += __cnt; \ |
1106 } \ |
1106 } \ |
1107 } \ |
1107 } \ |
1108 if (__offs > 0) \ |
1108 if (__offs > 0) \ |
1109 (ret) = __offs; \ |
1109 (ret) = __offs; \ |
1110 } \ |
1110 } \ |
1111 } |
1111 } |
1112 |
1112 |
1113 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1113 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1114 { \ |
1114 { \ |
1115 int __ooffs = obj_offs; \ |
1115 int __ooffs = obj_offs; \ |
1116 int __offs = 0; \ |
1116 int __offs = 0; \ |
1117 int __cnt; \ |
1117 int __cnt; \ |
1118 char *buf = (char *)(obj); \ |
1118 char *buf = (char *)(obj); \ |
1119 \ |
1119 \ |
1120 (ret) = 0; \ |
1120 (ret) = 0; \ |
1121 if (isBuffered) { \ |
1121 if (isBuffered) { \ |
1122 while (__offs < (cnt)) { \ |
1122 while (__offs < (cnt)) { \ |
1123 CLEAR_ERRNO; \ |
1123 CLEAR_ERRNO; \ |
1124 (ret) = getc(f); \ |
1124 (ret) = getc(f); \ |
1125 if ((ret) < 0) { \ |
1125 if ((ret) < 0) { \ |
1126 if (ferror(f)) { \ |
1126 if (ferror(f)) { \ |
1127 if (__threadErrno == EINTR) { \ |
1127 if (__threadErrno == EINTR) { \ |
1128 clearerr(f); \ |
1128 clearerr(f); \ |
1129 /* refetch */ \ |
1129 /* refetch */ \ |
1130 buf = (char *)(obj); \ |
1130 buf = (volatile char *)(obj); \ |
1131 (ret) = 0; \ |
1131 (ret) = 0; \ |
1132 break; \ |
1132 break; \ |
1133 } \ |
1133 } \ |
1134 } else { \ |
1134 } else { \ |
1135 (ret) = 0; \ |
1135 (ret) = 0; \ |
1136 } \ |
1136 } \ |
1137 break; \ |
1137 break; \ |
1138 } \ |
1138 } \ |
1139 (buf)[__ooffs+__offs] = (ret); \ |
1139 (buf)[__ooffs+__offs] = (ret); \ |
1140 DEBUGBUFFER(buf); \ |
1140 DEBUGBUFFER(buf); \ |
1141 __offs++; \ |
1141 __offs++; \ |
1142 } \ |
1142 } \ |
1143 if (__offs > 0) \ |
1143 if (__offs > 0) \ |
1144 (ret) = __offs; \ |
1144 (ret) = __offs; \ |
1145 } else { \ |
1145 } else { \ |
1146 int fd = fileno(f); \ |
1146 int fd = fileno(f); \ |
1147 \ |
1147 \ |
1148 while (__offs < (cnt)) { \ |
1148 while (__offs < (cnt)) { \ |
1149 OBJ rA = __INST(readAhead); \ |
1149 OBJ rA = __INST(readAhead); \ |
1150 if (rA != nil) { \ |
1150 if (rA != nil) { \ |
1151 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1151 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1152 DEBUGBUFFER(buf); \ |
1152 DEBUGBUFFER(buf); \ |
1153 __INST(readAhead) = nil; \ |
1153 __INST(readAhead) = nil; \ |
1154 __offs++; \ |
1154 __offs++; \ |
1155 continue; \ |
1155 continue; \ |
1156 } \ |
1156 } \ |
1157 CLEAR_ERRNO; \ |
1157 CLEAR_ERRNO; \ |
1158 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1158 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1159 DEBUGBUFFER(buf); \ |
1159 DEBUGBUFFER(buf); \ |
1160 if (__cnt > 0) { \ |
1160 if (__cnt > 0) { \ |
1161 __offs += __cnt; \ |
1161 __offs += __cnt; \ |
1162 } \ |
1162 } \ |
1163 break; \ |
1163 break; \ |
1164 } \ |
1164 } \ |
1165 if (__offs > 0) \ |
1165 if (__offs > 0) \ |
1166 (ret) = __offs; \ |
1166 (ret) = __offs; \ |
1167 } \ |
1167 } \ |
1168 } |
1168 } |
1169 |
1169 |
1170 |
1170 |
1171 # endif /* use STDIO */ |
1171 # endif /* use STDIO */ |
1172 |
1172 |
1173 # ifdef NO_STDIO |
1173 # ifdef NO_STDIO |
1174 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1174 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1175 for (;;) { \ |
1175 for (;;) { \ |
1176 CLEAR_ERRNO; \ |
1176 CLEAR_ERRNO; \ |
1177 (ret) = WRITE(f, buf, 1, handleType); \ |
1177 (ret) = WRITE(f, buf, 1, handleType); \ |
1178 if ((ret) >= 0 || __threadErrno != EINTR) \ |
1178 if ((ret) >= 0 || __threadErrno != EINTR) \ |
1179 break; \ |
1179 break; \ |
1180 __HANDLE_INTERRUPTS__; \ |
1180 __HANDLE_INTERRUPTS__; \ |
1181 } |
1181 } |
1182 # else /* use STDIO */ |
1182 # else /* use STDIO */ |
1183 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1183 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1184 if (isBuffered) { \ |
1184 if (isBuffered) { \ |
1185 for (;;) { \ |
1185 for (;;) { \ |
1186 CLEAR_ERRNO; \ |
1186 CLEAR_ERRNO; \ |
1187 ret = putc(*(buf), f); \ |
1187 ret = putc(*(buf), f); \ |
1188 if ((ret) >= 0) { \ |
1188 if ((ret) >= 0) { \ |
1189 (ret) = 1; \ |
1189 (ret) = 1; \ |
1190 } else if (ferror(f)) { \ |
1190 } else if (ferror(f)) { \ |
1191 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \ |
1191 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \ |
1192 if (__threadErrno == EINTR || __threadErrno == 0) { \ |
1192 if (__threadErrno == EINTR || __threadErrno == 0) { \ |
1193 __HANDLE_INTERRUPTS__; \ |
1193 __HANDLE_INTERRUPTS__; \ |
1194 clearerr(f); \ |
1194 clearerr(f); \ |
1195 continue; \ |
1195 continue; \ |
1196 } \ |
1196 } \ |
1197 } else \ |
1197 } else \ |
1198 (ret) = 0; \ |
1198 (ret) = 0; \ |
1199 break; \ |
1199 break; \ |
1200 } \ |
1200 } \ |
1201 } else { \ |
1201 } else { \ |
1202 for (;;) { \ |
1202 for (;;) { \ |
1203 CLEAR_ERRNO; \ |
1203 CLEAR_ERRNO; \ |
1204 (ret) = write(fileno(f), buf, 1); \ |
1204 (ret) = write(fileno(f), buf, 1); \ |
1205 if ((ret) >= 0 || __threadErrno != EINTR) \ |
1205 if ((ret) >= 0 || __threadErrno != EINTR) \ |
1206 break; \ |
1206 break; \ |
1207 __HANDLE_INTERRUPTS__; \ |
1207 __HANDLE_INTERRUPTS__; \ |
1208 } \ |
1208 } \ |
1209 } |
1209 } |
1210 # endif /* use STDIO */ |
1210 # endif /* use STDIO */ |
1211 |
1211 |
1212 /* |
1212 /* |
1213 * write_bytes from a c-buffer |
1213 * write_bytes from a c-buffer |