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