changeset 16909 | d02e5b66902a |
parent 16776 | fd62ae0ff6fa |
child 16912 | 2391fcb8b4a4 |
16908:25523cfdfa62 | 16909:d02e5b66902a |
---|---|
198 #ifdef DEBUGGING |
198 #ifdef DEBUGGING |
199 extern char *__survStartPtr, *__survEndPtr; |
199 extern char *__survStartPtr, *__survEndPtr; |
200 # define DEBUGBUFFER(buf) \ |
200 # define DEBUGBUFFER(buf) \ |
201 if (((char *)(buf) >= __survStartPtr) \ |
201 if (((char *)(buf) >= __survStartPtr) \ |
202 && ((char *)(buf) < __survEndPtr)) { \ |
202 && ((char *)(buf) < __survEndPtr)) { \ |
203 __fatal0("read into survivor\n"); \ |
203 __fatal0("read into survivor\n"); \ |
204 } |
204 } |
205 |
205 |
206 #else |
206 #else |
207 # define DEBUGBUFFER(buf) /* nothing */ |
207 # define DEBUGBUFFER(buf) /* nothing */ |
208 #endif |
208 #endif |
219 # define OPT_FSEEK(f, pos, whence) /* nothing */ |
219 # define OPT_FSEEK(f, pos, whence) /* nothing */ |
220 #endif |
220 #endif |
221 |
221 |
222 #ifdef WIN32 |
222 #ifdef WIN32 |
223 # define READ(ret, f, cp, n, handleType) { \ |
223 # define READ(ret, f, cp, n, handleType) { \ |
224 if (handleType == @symbol(socketHandle)) { \ |
224 if (handleType == @symbol(socketHandle)) { \ |
225 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \ |
225 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \ |
226 } else { \ |
226 } else { \ |
227 HANDLE h = _get_osfhandle(fileno(f)); \ |
227 HANDLE h = _get_osfhandle(fileno(f)); \ |
228 if (handleType == @symbol(socketFilePointer)) { \ |
228 if (handleType == @symbol(socketFilePointer)) { \ |
229 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
229 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
230 } else { \ |
230 } else { \ |
231 int __res; \ |
231 int __res; \ |
232 (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\ |
232 (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\ |
233 (ret) = (ret) ? __res : -1; \ |
233 (ret) = (ret) ? __res : (__threadErrno == ERROR_BROKEN_PIPE ? 0 : -1); \ |
234 } \ |
234 } \ |
235 } \ |
235 } \ |
236 } |
236 } |
237 |
237 |
238 # define WRITE(ret, f, cp, n, handleType) { \ |
238 # define WRITE(ret, f, cp, n, handleType) { \ |
239 if (handleType == @symbol(socketHandle)) { \ |
239 if (handleType == @symbol(socketHandle)) { \ |
240 (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \ |
240 (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \ |
241 } else {\ |
241 } else {\ |
242 HANDLE h = _get_osfhandle(fileno(f)); \ |
242 HANDLE h = _get_osfhandle(fileno(f)); \ |
243 if (handleType == @symbol(socketFilePointer)) { \ |
243 if (handleType == @symbol(socketFilePointer)) { \ |
244 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
244 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
245 } else {\ |
245 } else {\ |
246 int __res; \ |
246 int __res; \ |
247 (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\ |
247 (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\ |
248 (ret) = (ret) ? __res : -1; \ |
248 (ret) = (ret) ? __res : -1; \ |
249 } \ |
249 } \ |
250 } \ |
250 } \ |
251 } |
251 } |
252 |
252 |
253 # define FFLUSH(fp) fflush(fp) |
253 # define FFLUSH(fp) fflush(fp) |
254 # undef STDIO_NEEDS_FSEEK |
254 # undef STDIO_NEEDS_FSEEK |
255 # define FILEPOINTER FILE * |
255 # define FILEPOINTER FILE * |
256 # define FILENO(f) fileno(f) |
256 # define FILENO(f) fileno(f) |
257 |
257 |
258 # define __READING__(f) \ |
258 # define __READING__(f) \ |
259 if ((__INST(didWrite) != false) \ |
259 if ((__INST(didWrite) != false) \ |
260 && (__INST(mode) == @symbol(readwrite))) { \ |
260 && (__INST(mode) == @symbol(readwrite))) { \ |
261 __INST(didWrite) = false; \ |
261 __INST(didWrite) = false; \ |
262 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
262 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
263 } |
263 } |
264 |
264 |
265 # define __WRITING__(f) \ |
265 # define __WRITING__(f) \ |
266 if ((__INST(didWrite) != true) \ |
266 if ((__INST(didWrite) != true) \ |
267 && (__INST(mode) == @symbol(readwrite))) { \ |
267 && (__INST(mode) == @symbol(readwrite))) { \ |
268 __INST(didWrite) = true; \ |
268 __INST(didWrite) = true; \ |
269 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
269 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
270 } |
270 } |
271 |
271 |
272 # define __UNGETC__(c, f, isBuffered) \ |
272 # define __UNGETC__(c, f, isBuffered) \ |
273 if (isBuffered) { \ |
273 if (isBuffered) { \ |
274 ungetc((c), (f)); \ |
274 ungetc((c), (f)); \ |
275 } else { \ |
275 } else { \ |
276 __INST(readAhead) = __mkSmallInteger((c)); \ |
276 __INST(readAhead) = __mkSmallInteger((c)); \ |
277 } |
277 } |
278 |
278 |
279 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
279 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
280 if (isBuffered) { \ |
280 if (isBuffered) { \ |
281 for (;;) { \ |
281 for (;;) { \ |
282 CLEAR_ERRNO; \ |
282 CLEAR_ERRNO; \ |
283 (ret) = getc(f); \ |
283 (ret) = getc(f); \ |
284 if ((ret) >= 0) { \ |
284 if ((ret) >= 0) { \ |
285 *(buf) = (ret); \ |
285 *(buf) = (ret); \ |
286 (ret) = 1; \ |
286 (ret) = 1; \ |
287 } else if (ferror(f)) { \ |
287 } else if (ferror(f)) { \ |
288 if (__threadErrno == EINTR) { \ |
288 if (__threadErrno == EINTR) { \ |
289 clearerr(f); \ |
289 clearerr(f); \ |
290 continue; \ |
290 continue; \ |
291 } \ |
291 } \ |
292 } else { \ |
292 } else { \ |
293 (ret) = 0; \ |
293 (ret) = 0; \ |
294 } \ |
294 } \ |
295 break; \ |
295 break; \ |
296 } \ |
296 } \ |
297 } else { \ |
297 } else { \ |
298 OBJ rA = __INST(readAhead); \ |
298 OBJ rA = __INST(readAhead); \ |
299 if (rA != nil) { \ |
299 if (rA != nil) { \ |
300 *(buf) = (char)__intVal(rA); \ |
300 *(buf) = (char)__intVal(rA); \ |
301 __INST(readAhead) = nil; \ |
301 __INST(readAhead) = nil; \ |
302 (ret) = 1; \ |
302 (ret) = 1; \ |
303 } else { \ |
303 } else { \ |
304 for (;;) { \ |
304 for (;;) { \ |
305 CLEAR_ERRNO; \ |
305 CLEAR_ERRNO; \ |
306 READ((ret), f, buf, 1, handleType); \ |
306 READ((ret), f, buf, 1, handleType); \ |
307 if ((ret) >= 0 || __threadErrno != EINTR) \ |
307 if ((ret) >= 0 || __threadErrno != EINTR) \ |
308 break; \ |
308 break; \ |
309 } \ |
309 } \ |
310 } \ |
310 } \ |
311 } |
311 } |
312 |
312 |
313 /* |
313 /* |
314 * read_bytes into a c-buffer |
314 * read_bytes into a c-buffer |
315 * (which may NOT move) |
315 * (which may NOT move) |
316 */ |
316 */ |
317 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
317 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
318 (ret) = 0; \ |
318 (ret) = 0; \ |
319 if (isBuffered) { \ |
319 if (isBuffered) { \ |
320 int __offs = 0; \ |
320 int __offs = 0; \ |
321 while (__offs < (cnt)) { \ |
321 while (__offs < (cnt)) { \ |
322 CLEAR_ERRNO; \ |
322 CLEAR_ERRNO; \ |
323 (ret) = getc(f); \ |
323 (ret) = getc(f); \ |
324 if ((ret) < 0) { \ |
324 if ((ret) < 0) { \ |
325 if (ferror(f)) { \ |
325 if (ferror(f)) { \ |
326 if (__threadErrno == EINTR) { \ |
326 if (__threadErrno == EINTR) { \ |
327 clearerr(f); \ |
327 clearerr(f); \ |
328 continue; \ |
328 continue; \ |
329 } \ |
329 } \ |
330 } else { \ |
330 } else { \ |
331 (ret) = 0; \ |
331 (ret) = 0; \ |
332 } \ |
332 } \ |
333 break; \ |
333 break; \ |
334 } \ |
334 } \ |
335 (buf)[__offs++] = (ret); \ |
335 (buf)[__offs++] = (ret); \ |
336 } \ |
336 } \ |
337 if (__offs > 0) \ |
337 if (__offs > 0) \ |
338 (ret) = __offs; \ |
338 (ret) = __offs; \ |
339 } else { \ |
339 } else { \ |
340 int __offs = 0; \ |
340 int __offs = 0; \ |
341 \ |
341 \ |
342 while (__offs < (cnt)) { \ |
342 while (__offs < (cnt)) { \ |
343 OBJ rA = __INST(readAhead); \ |
343 OBJ rA = __INST(readAhead); \ |
344 if (rA != nil) { \ |
344 if (rA != nil) { \ |
345 (buf)[__offs] = __intVal(rA); \ |
345 (buf)[__offs] = __intVal(rA); \ |
346 __INST(readAhead) = nil; \ |
346 __INST(readAhead) = nil; \ |
347 (ret) = 1; \ |
347 (ret) = 1; \ |
348 } else { \ |
348 } else { \ |
349 CLEAR_ERRNO; \ |
349 CLEAR_ERRNO; \ |
350 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \ |
350 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \ |
351 if ((ret) <= 0) { \ |
351 if ((ret) <= 0) { \ |
352 if ((ret) < 0 && __threadErrno == EINTR) { \ |
352 if ((ret) < 0 && __threadErrno == EINTR) { \ |
353 continue; \ |
353 continue; \ |
354 } \ |
354 } \ |
355 break; \ |
355 break; \ |
356 } \ |
356 } \ |
357 } \ |
357 } \ |
358 __offs += (ret); \ |
358 __offs += (ret); \ |
359 } \ |
359 } \ |
360 if (__offs > 0) \ |
360 if (__offs > 0) \ |
361 (ret) = __offs; \ |
361 (ret) = __offs; \ |
362 } |
362 } |
363 |
363 |
364 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
364 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
365 { \ |
365 { \ |
366 int __offs = 0; \ |
366 int __offs = 0; \ |
367 int oldFlags; \ |
367 int oldFlags; \ |
368 \ |
368 \ |
369 (ret) = 0; \ |
369 (ret) = 0; \ |
370 if (isBuffered) { \ |
370 if (isBuffered) { \ |
371 while (__offs < (cnt)) { \ |
371 while (__offs < (cnt)) { \ |
372 CLEAR_ERRNO; \ |
372 CLEAR_ERRNO; \ |
373 (ret) = getc(f); \ |
373 (ret) = getc(f); \ |
374 if ((ret) < 0) { \ |
374 if ((ret) < 0) { \ |
375 if (ferror(f)) { \ |
375 if (ferror(f)) { \ |
376 if (__threadErrno == EINTR) { \ |
376 if (__threadErrno == EINTR) { \ |
377 clearerr(f); \ |
377 clearerr(f); \ |
378 continue; \ |
378 continue; \ |
379 } \ |
379 } \ |
380 } else { \ |
380 } else { \ |
381 (ret) = 0; \ |
381 (ret) = 0; \ |
382 } \ |
382 } \ |
383 break; \ |
383 break; \ |
384 } \ |
384 } \ |
385 (buf)[__offs++] = (ret); \ |
385 (buf)[__offs++] = (ret); \ |
386 } \ |
386 } \ |
387 (ret) = __offs; \ |
387 (ret) = __offs; \ |
388 } else { \ |
388 } else { \ |
389 while (__offs < (cnt)) { \ |
389 while (__offs < (cnt)) { \ |
390 OBJ rA = __INST(readAhead); \ |
390 OBJ rA = __INST(readAhead); \ |
391 if (rA != nil) { \ |
391 if (rA != nil) { \ |
392 (buf)[__offs] = __intVal(rA); \ |
392 (buf)[__offs] = __intVal(rA); \ |
393 __INST(readAhead) = nil; \ |
393 __INST(readAhead) = nil; \ |
394 (ret) = 1; \ |
394 (ret) = 1; \ |
395 __offs ++; \ |
395 __offs ++; \ |
396 continue; \ |
396 continue; \ |
397 } \ |
397 } \ |
398 CLEAR_ERRNO; \ |
398 CLEAR_ERRNO; \ |
399 { \ |
399 { \ |
400 int res = 0; \ |
400 int res = 0; \ |
401 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res), 1)) \ |
401 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res), 1)) \ |
402 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
402 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
403 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0), 1))) { \ |
403 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0), 1))) { \ |
404 if (res > 0) { \ |
404 if (res > 0) { \ |
405 if (res > ((cnt)-__offs)) \ |
405 if (res > ((cnt)-__offs)) \ |
406 res = (cnt)-__offs; \ |
406 res = (cnt)-__offs; \ |
407 READ((ret), f, (buf)+__offs, res, handleType); \ |
407 READ((ret), f, (buf)+__offs, res, handleType); \ |
408 } else { \ |
408 } else { \ |
409 (ret) = 0; \ |
409 (ret) = 0; \ |
410 break; \ |
410 break; \ |
411 } \ |
411 } \ |
412 } else { \ |
412 } else { \ |
413 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \ |
413 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \ |
414 } \ |
414 } \ |
415 } \ |
415 } \ |
416 if ((ret) <= 0) { \ |
416 if ((ret) <= 0) { \ |
417 if (ret < 0 && __threadErrno == EINTR) \ |
417 if (ret < 0 && __threadErrno == EINTR) \ |
418 continue; \ |
418 continue; \ |
419 break; \ |
419 break; \ |
420 } \ |
420 } \ |
421 __offs += (ret); \ |
421 __offs += (ret); \ |
422 } \ |
422 } \ |
423 (ret) = __offs; \ |
423 (ret) = __offs; \ |
424 } \ |
424 } \ |
425 } |
425 } |
426 |
426 |
427 # define IO_BUFFER_SIZE (8*1024) |
427 # define IO_BUFFER_SIZE (8*1024) |
428 |
428 |
429 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
429 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
430 { \ |
430 { \ |
431 int __ooffs = obj_offs; \ |
431 int __ooffs = obj_offs; \ |
432 int __offs = 0; \ |
432 int __offs = 0; \ |
433 char *buf = (char *)(obj); \ |
433 char *buf = (char *)(obj); \ |
434 \ |
434 \ |
435 (ret) = 0; \ |
435 (ret) = 0; \ |
436 if (isBuffered) { \ |
436 if (isBuffered) { \ |
437 while (__offs < (cnt)) { \ |
437 while (__offs < (cnt)) { \ |
438 CLEAR_ERRNO; \ |
438 CLEAR_ERRNO; \ |
439 (ret) = getc(f); \ |
439 (ret) = getc(f); \ |
440 if ((ret) < 0) { \ |
440 if ((ret) < 0) { \ |
441 if (ferror(f)) { \ |
441 if (ferror(f)) { \ |
442 if (__threadErrno == EINTR) { \ |
442 if (__threadErrno == EINTR) { \ |
443 clearerr(f); \ |
443 clearerr(f); \ |
444 /* refetch */ \ |
444 /* refetch */ \ |
445 buf = (char *)(obj); \ |
445 buf = (char *)(obj); \ |
446 continue; \ |
446 continue; \ |
447 } \ |
447 } \ |
448 } else { \ |
448 } else { \ |
449 (ret) = 0; \ |
449 (ret) = 0; \ |
450 } \ |
450 } \ |
451 break; \ |
451 break; \ |
452 } \ |
452 } \ |
453 (buf)[__ooffs+__offs] = (ret); \ |
453 (buf)[__ooffs+__offs] = (ret); \ |
454 __offs++; \ |
454 __offs++; \ |
455 } \ |
455 } \ |
456 if (__offs > 0) \ |
456 if (__offs > 0) \ |
457 (ret) = __offs; \ |
457 (ret) = __offs; \ |
458 } else { \ |
458 } else { \ |
459 while (__offs < (cnt)) { \ |
459 while (__offs < (cnt)) { \ |
460 char __buf[IO_BUFFER_SIZE]; \ |
460 char __buf[IO_BUFFER_SIZE]; \ |
461 OBJ rA = __INST(readAhead); \ |
461 OBJ rA = __INST(readAhead); \ |
462 if (rA != nil) { \ |
462 if (rA != nil) { \ |
463 (buf)[__ooffs+__offs] = __intVal(rA); \ |
463 (buf)[__ooffs+__offs] = __intVal(rA); \ |
464 __INST(readAhead) = nil; \ |
464 __INST(readAhead) = nil; \ |
465 (ret) = 1; \ |
465 (ret) = 1; \ |
466 } else { \ |
466 } else { \ |
467 int l; \ |
467 int l; \ |
468 CLEAR_ERRNO; \ |
468 CLEAR_ERRNO; \ |
469 l = (cnt)-__offs; \ |
469 l = (cnt)-__offs; \ |
470 if ( l > IO_BUFFER_SIZE) \ |
470 if ( l > IO_BUFFER_SIZE) \ |
471 l = IO_BUFFER_SIZE; \ |
471 l = IO_BUFFER_SIZE; \ |
472 READ((ret),f, __buf, l, handleType); \ |
472 READ((ret),f, __buf, l, handleType); \ |
473 if ((ret) <= 0) { \ |
473 if ((ret) <= 0) { \ |
474 if ((ret) < 0 && __threadErrno == EINTR) { \ |
474 if ((ret) < 0 && __threadErrno == EINTR) { \ |
475 continue; \ |
475 continue; \ |
476 } \ |
476 } \ |
477 break; \ |
477 break; \ |
478 } \ |
478 } \ |
479 } \ |
479 } \ |
480 if ((ret) > 0 ) { \ |
480 if ((ret) > 0 ) { \ |
481 /* refetch */ \ |
481 /* refetch */ \ |
482 buf = (char *)(obj); \ |
482 buf = (char *)(obj); \ |
483 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
483 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
484 __offs += (ret); \ |
484 __offs += (ret); \ |
485 } else { \ |
485 } else { \ |
486 (ret) = 0; \ |
486 (ret) = 0; \ |
487 } \ |
487 } \ |
488 } \ |
488 } \ |
489 if (__offs > 0) \ |
489 if (__offs > 0) \ |
490 (ret) = __offs; \ |
490 (ret) = __offs; \ |
491 } \ |
491 } \ |
492 } |
492 } |
493 |
493 |
494 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
494 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
495 { \ |
495 { \ |
496 int __ooffs = obj_offs; \ |
496 int __ooffs = obj_offs; \ |
497 int __offs = 0; \ |
497 int __offs = 0; \ |
498 char *buf = (char *)(obj); \ |
498 char *buf = (char *)(obj); \ |
499 \ |
499 \ |
500 (ret) = 0; \ |
500 (ret) = 0; \ |
501 if (isBuffered) { \ |
501 if (isBuffered) { \ |
502 while (__offs < (cnt)) { \ |
502 while (__offs < (cnt)) { \ |
503 CLEAR_ERRNO; \ |
503 CLEAR_ERRNO; \ |
504 (ret) = getc(f); \ |
504 (ret) = getc(f); \ |
505 if ((ret) < 0) { \ |
505 if ((ret) < 0) { \ |
506 if (ferror(f)) { \ |
506 if (ferror(f)) { \ |
507 if (__threadErrno == EINTR) { \ |
507 if (__threadErrno == EINTR) { \ |
508 clearerr(f); \ |
508 clearerr(f); \ |
509 /* refetch */ \ |
509 /* refetch */ \ |
510 buf = (char *)(obj);\ |
510 buf = (char *)(obj);\ |
511 continue; \ |
511 continue; \ |
512 } \ |
512 } \ |
513 } else { \ |
513 } else { \ |
514 (ret) = 0; \ |
514 (ret) = 0; \ |
515 } \ |
515 } \ |
516 break; \ |
516 break; \ |
517 } \ |
517 } \ |
518 (buf)[__ooffs+__offs] = (ret); \ |
518 (buf)[__ooffs+__offs] = (ret); \ |
519 __offs++; \ |
519 __offs++; \ |
520 } \ |
520 } \ |
521 if (__offs > 0) \ |
521 if (__offs > 0) \ |
522 (ret) = __offs; \ |
522 (ret) = __offs; \ |
523 } else { \ |
523 } else { \ |
524 while (__offs < (cnt)) { \ |
524 while (__offs < (cnt)) { \ |
525 char __buf[IO_BUFFER_SIZE]; \ |
525 char __buf[IO_BUFFER_SIZE]; \ |
526 OBJ rA = __INST(readAhead); \ |
526 OBJ rA = __INST(readAhead); \ |
527 if (rA != nil) { \ |
527 if (rA != nil) { \ |
528 (buf)[__ooffs+__offs] = __intVal(rA);\ |
528 (buf)[__ooffs+__offs] = __intVal(rA);\ |
529 __INST(readAhead) = nil; \ |
529 __INST(readAhead) = nil; \ |
530 (ret) = 1; \ |
530 (ret) = 1; \ |
531 __offs++; \ |
531 __offs++; \ |
532 continue; \ |
532 continue; \ |
533 } \ |
533 } \ |
534 { \ |
534 { \ |
535 int res = 0; \ |
535 int res = 0; \ |
536 int l = (cnt)-__offs; \ |
536 int l = (cnt)-__offs; \ |
537 CLEAR_ERRNO; \ |
537 CLEAR_ERRNO; \ |
538 if (l > IO_BUFFER_SIZE) \ |
538 if (l > IO_BUFFER_SIZE) \ |
539 l = IO_BUFFER_SIZE; \ |
539 l = IO_BUFFER_SIZE; \ |
540 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)), FIONREAD, &res), 1)) \ |
540 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)), FIONREAD, &res), 1)) \ |
541 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
541 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
542 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0,0,0,&res,0), 1))) { \ |
542 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0,0,0,&res,0), 1))) { \ |
543 if (res > 0) { \ |
543 if (res > 0) { \ |
544 if (res > l) res = l; \ |
544 if (res > l) res = l; \ |
545 READ((ret), f, __buf, res, handleType); \ |
545 READ((ret), f, __buf, res, handleType); \ |
546 } else { \ |
546 } else { \ |
547 (ret) = 0; \ |
547 (ret) = 0; \ |
548 break; \ |
548 break; \ |
549 } \ |
549 } \ |
550 } else { \ |
550 } else { \ |
551 READ((ret), f, __buf, l, handleType); \ |
551 READ((ret), f, __buf, l, handleType); \ |
552 } \ |
552 } \ |
553 if ((ret) <= 0) { \ |
553 if ((ret) <= 0) { \ |
554 if (ret < 0 && __threadErrno == EINTR) \ |
554 if (ret < 0 && __threadErrno == EINTR) \ |
555 continue; \ |
555 continue; \ |
556 break; \ |
556 break; \ |
557 } \ |
557 } \ |
558 } \ |
558 } \ |
559 if ((ret) > 0) { \ |
559 if ((ret) > 0) { \ |
560 buf = (char *)(obj); \ |
560 buf = (char *)(obj); \ |
561 memcpy((buf)+__ooffs+__offs, __buf, (ret)); \ |
561 memcpy((buf)+__ooffs+__offs, __buf, (ret)); \ |
562 __offs += (ret); \ |
562 __offs += (ret); \ |
563 } else { \ |
563 } else { \ |
564 (ret) = 0; \ |
564 (ret) = 0; \ |
565 } \ |
565 } \ |
566 } \ |
566 } \ |
567 if (__offs > 0) \ |
567 if (__offs > 0) \ |
568 (ret) = __offs; \ |
568 (ret) = __offs; \ |
569 } \ |
569 } \ |
570 } |
570 } |
571 |
571 |
572 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
572 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
573 if (isBuffered) { \ |
573 if (isBuffered) { \ |
574 for (;;) { \ |
574 for (;;) { \ |
575 CLEAR_ERRNO; \ |
575 CLEAR_ERRNO; \ |
576 ret = putc(*(buf), f); \ |
576 ret = putc(*(buf), f); \ |
577 if ((ret) >= 0) { \ |
577 if ((ret) >= 0) { \ |
578 (ret) = 1; \ |
578 (ret) = 1; \ |
579 } else if (ferror(f)) { \ |
579 } else if (ferror(f)) { \ |
580 if (__threadErrno == EINTR) { \ |
580 if (__threadErrno == EINTR) { \ |
581 clearerr(f); \ |
581 clearerr(f); \ |
582 continue; \ |
582 continue; \ |
583 } \ |
583 } \ |
584 } else \ |
584 } else \ |
585 (ret) = 0; \ |
585 (ret) = 0; \ |
586 break; \ |
586 break; \ |
587 } \ |
587 } \ |
588 } else { \ |
588 } else { \ |
589 for (;;) { \ |
589 for (;;) { \ |
590 CLEAR_ERRNO; \ |
590 CLEAR_ERRNO; \ |
591 WRITE(ret,f, buf, 1, handleType); \ |
591 WRITE(ret,f, buf, 1, handleType); \ |
592 if ((ret) >= 0 || __threadErrno != EINTR) \ |
592 if ((ret) >= 0 || __threadErrno != EINTR) \ |
593 break; \ |
593 break; \ |
594 } \ |
594 } \ |
595 } |
595 } |
596 |
596 |
597 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
597 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
598 (ret) = 0; \ |
598 (ret) = 0; \ |
599 if (isBuffered) { \ |
599 if (isBuffered) { \ |
600 int __offs = 0; \ |
600 int __offs = 0; \ |
601 while (__offs < (cnt)) { \ |
601 while (__offs < (cnt)) { \ |
602 CLEAR_ERRNO; \ |
602 CLEAR_ERRNO; \ |
603 (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
603 (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
604 if ((ret) <= 0) { \ |
604 if ((ret) <= 0) { \ |
605 if (ferror(f)) { \ |
605 if (ferror(f)) { \ |
606 if (__threadErrno == EINTR) { \ |
606 if (__threadErrno == EINTR) { \ |
607 clearerr(f); \ |
607 clearerr(f); \ |
608 continue; \ |
608 continue; \ |
609 } \ |
609 } \ |
610 break; \ |
610 break; \ |
611 } else { \ |
611 } else { \ |
612 (ret) = 0; \ |
612 (ret) = 0; \ |
613 } \ |
613 } \ |
614 } \ |
614 } \ |
615 __offs += (ret); \ |
615 __offs += (ret); \ |
616 } \ |
616 } \ |
617 if (__offs > 0) \ |
617 if (__offs > 0) \ |
618 (ret) = __offs; \ |
618 (ret) = __offs; \ |
619 } else { \ |
619 } else { \ |
620 int __offs = 0; \ |
620 int __offs = 0; \ |
621 while (__offs < (cnt)) { \ |
621 while (__offs < (cnt)) { \ |
622 CLEAR_ERRNO; \ |
622 CLEAR_ERRNO; \ |
623 WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
623 WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
624 if (ret <= 0) { \ |
624 if (ret <= 0) { \ |
625 if (ret < 0 && __threadErrno == EINTR) { \ |
625 if (ret < 0 && __threadErrno == EINTR) { \ |
626 continue; \ |
626 continue; \ |
627 } \ |
627 } \ |
628 break; \ |
628 break; \ |
629 } \ |
629 } \ |
630 __offs += (ret); \ |
630 __offs += (ret); \ |
631 } \ |
631 } \ |
632 if (__offs > 0) \ |
632 if (__offs > 0) \ |
633 (ret) = __offs; \ |
633 (ret) = __offs; \ |
634 } |
634 } |
635 |
635 |
636 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
636 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
637 { \ |
637 { \ |
638 int __ooffs = obj_offs; \ |
638 int __ooffs = obj_offs; \ |
639 int __offs = 0; \ |
639 int __offs = 0; \ |
640 char *buf = (char *)(obj); \ |
640 char *buf = (char *)(obj); \ |
641 \ |
641 \ |
642 (ret) = 0; \ |
642 (ret) = 0; \ |
643 if (isBuffered) { \ |
643 if (isBuffered) { \ |
644 while (__offs < (cnt)) { \ |
644 while (__offs < (cnt)) { \ |
645 CLEAR_ERRNO; \ |
645 CLEAR_ERRNO; \ |
646 ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
646 ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
647 if ((ret) <= 0) { \ |
647 if ((ret) <= 0) { \ |
648 if (ferror(f)) { \ |
648 if (ferror(f)) { \ |
649 if (__threadErrno == EINTR) { \ |
649 if (__threadErrno == EINTR) { \ |
650 /* refetch */ \ |
650 /* refetch */ \ |
651 buf = (char *)(obj); \ |
651 buf = (char *)(obj); \ |
652 clearerr(f); \ |
652 clearerr(f); \ |
653 continue; \ |
653 continue; \ |
654 } \ |
654 } \ |
655 break; \ |
655 break; \ |
656 } else { \ |
656 } else { \ |
657 (ret) = 0; \ |
657 (ret) = 0; \ |
658 } \ |
658 } \ |
659 } \ |
659 } \ |
660 __offs += (ret); \ |
660 __offs += (ret); \ |
661 } \ |
661 } \ |
662 if (__offs > 0) \ |
662 if (__offs > 0) \ |
663 (ret) = __offs; \ |
663 (ret) = __offs; \ |
664 } else { \ |
664 } else { \ |
665 while (__offs < (cnt)) { \ |
665 while (__offs < (cnt)) { \ |
666 char __buf[IO_BUFFER_SIZE]; \ |
666 char __buf[IO_BUFFER_SIZE]; \ |
667 int l; \ |
667 int l; \ |
668 CLEAR_ERRNO; \ |
668 CLEAR_ERRNO; \ |
669 l = (cnt)-__offs; \ |
669 l = (cnt)-__offs; \ |
670 if ( l > IO_BUFFER_SIZE) \ |
670 if ( l > IO_BUFFER_SIZE) \ |
671 l = IO_BUFFER_SIZE; \ |
671 l = IO_BUFFER_SIZE; \ |
672 /* refetch */ \ |
672 /* refetch */ \ |
673 buf = (char *)(obj); \ |
673 buf = (char *)(obj); \ |
674 memcpy(__buf,(buf)+__ooffs+__offs,l); \ |
674 memcpy(__buf,(buf)+__ooffs+__offs,l); \ |
675 WRITE(ret,f, __buf, l, handleType); \ |
675 WRITE(ret,f, __buf, l, handleType); \ |
676 if (ret <= 0) { \ |
676 if (ret <= 0) { \ |
677 if (ret < 0 && __threadErrno == EINTR) { \ |
677 if (ret < 0 && __threadErrno == EINTR) { \ |
678 continue; \ |
678 continue; \ |
679 } \ |
679 } \ |
680 break; \ |
680 break; \ |
681 } \ |
681 } \ |
682 __offs += (ret); \ |
682 __offs += (ret); \ |
683 } \ |
683 } \ |
684 if (__offs > 0) \ |
684 if (__offs > 0) \ |
685 (ret) = __offs; \ |
685 (ret) = __offs; \ |
686 } \ |
686 } \ |
687 } |
687 } |
688 |
688 |
689 #else /* ! WIN32 */ |
689 #else /* ! WIN32 */ |
690 /* ======================== UNIX / LINUX ====================================================== */ |
690 /* ======================== UNIX / LINUX ====================================================== */ |
691 typedef int SOCKET; |
691 typedef int SOCKET; |
692 |
692 |
693 # define __READING__(f) \ |
693 # define __READING__(f) \ |
694 if ((__INST(didWrite) != false) \ |
694 if ((__INST(didWrite) != false) \ |
695 && (__INST(mode) == @symbol(readwrite))) { \ |
695 && (__INST(mode) == @symbol(readwrite))) { \ |
696 __INST(didWrite) = false; \ |
696 __INST(didWrite) = false; \ |
697 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
697 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
698 } |
698 } |
699 |
699 |
700 # define __WRITING__(f) \ |
700 # define __WRITING__(f) \ |
701 if ((__INST(didWrite) != true) \ |
701 if ((__INST(didWrite) != true) \ |
702 && (__INST(mode) == @symbol(readwrite))) { \ |
702 && (__INST(mode) == @symbol(readwrite))) { \ |
703 __INST(didWrite) = true; \ |
703 __INST(didWrite) = true; \ |
704 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
704 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
705 } |
705 } |
706 |
706 |
707 |
707 |
708 # ifdef NO_STDIO |
708 # ifdef NO_STDIO |
709 # define __UNGETC__(c, f, isBuffered) \ |
709 # define __UNGETC__(c, f, isBuffered) \ |
710 __INST(readAhead) = __mkSmallInteger((c)); |
710 __INST(readAhead) = __mkSmallInteger((c)); |
711 # else /* use STDIO */ |
711 # else /* use STDIO */ |
712 # define __UNGETC__(c, f, isBuffered) \ |
712 # define __UNGETC__(c, f, isBuffered) \ |
713 if (isBuffered) { \ |
713 if (isBuffered) { \ |
714 ungetc((c), (f)); \ |
714 ungetc((c), (f)); \ |
715 } else { \ |
715 } else { \ |
716 __INST(readAhead) = __mkSmallInteger((c)); \ |
716 __INST(readAhead) = __mkSmallInteger((c)); \ |
717 } |
717 } |
718 # endif /* use STDIO */ |
718 # endif /* use STDIO */ |
719 |
719 |
720 # ifdef NO_STDIO |
720 # ifdef NO_STDIO |
721 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
721 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
722 { \ |
722 { \ |
723 OBJ rA = __INST(readAhead); \ |
723 OBJ rA = __INST(readAhead); \ |
724 if (rA != nil) { \ |
724 if (rA != nil) { \ |
725 *(buf) = __intVal(rA); \ |
725 *(buf) = __intVal(rA); \ |
726 DEBUGBUFFER(buf); \ |
726 DEBUGBUFFER(buf); \ |
727 __INST(readAhead) = nil; \ |
727 __INST(readAhead) = nil; \ |
728 (ret) = 1; \ |
728 (ret) = 1; \ |
729 } else { \ |
729 } else { \ |
730 for (;;) { \ |
730 for (;;) { \ |
731 CLEAR_ERRNO; \ |
731 CLEAR_ERRNO; \ |
732 (ret) = READ(f, buf, 1, handleType); \ |
732 (ret) = READ(f, buf, 1, handleType); \ |
733 DEBUGBUFFER(buf); \ |
733 DEBUGBUFFER(buf); \ |
734 if ((ret) >= 0) break; \ |
734 if ((ret) >= 0) break; \ |
735 if (errno != EINTR) { \ |
735 if (errno != EINTR) { \ |
736 break; \ |
736 break; \ |
737 } \ |
737 } \ |
738 __HANDLE_INTERRUPTS__; \ |
738 __HANDLE_INTERRUPTS__; \ |
739 } \ |
739 } \ |
740 } \ |
740 } \ |
741 } |
741 } |
742 # else /* use STDIO */ |
742 # else /* use STDIO */ |
743 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
743 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
744 if (isBuffered) { \ |
744 if (isBuffered) { \ |
745 for (;;) { \ |
745 for (;;) { \ |
746 CLEAR_ERRNO; \ |
746 CLEAR_ERRNO; \ |
747 (ret) = getc(f); \ |
747 (ret) = getc(f); \ |
748 if ((ret) >= 0) { \ |
748 if ((ret) >= 0) { \ |
749 DEBUGBUFFER(buf); \ |
749 DEBUGBUFFER(buf); \ |
750 *(buf) = (ret); \ |
750 *(buf) = (ret); \ |
751 (ret) = 1; \ |
751 (ret) = 1; \ |
752 } else if (ferror(f)) { \ |
752 } else if (ferror(f)) { \ |
753 if (errno == EINTR) { \ |
753 if (errno == EINTR) { \ |
754 __HANDLE_INTERRUPTS__; \ |
754 __HANDLE_INTERRUPTS__; \ |
755 clearerr(f); \ |
755 clearerr(f); \ |
756 continue; \ |
756 continue; \ |
757 } \ |
757 } \ |
758 } else \ |
758 } else \ |
759 (ret) = 0; \ |
759 (ret) = 0; \ |
760 break; \ |
760 break; \ |
761 } \ |
761 } \ |
762 } else { \ |
762 } else { \ |
763 OBJ rA = __INST(readAhead); \ |
763 OBJ rA = __INST(readAhead); \ |
764 if (rA != nil) { \ |
764 if (rA != nil) { \ |
765 *(buf) = __intVal(rA); \ |
765 *(buf) = __intVal(rA); \ |
766 DEBUGBUFFER(buf); \ |
766 DEBUGBUFFER(buf); \ |
767 __INST(readAhead) = nil; \ |
767 __INST(readAhead) = nil; \ |
768 (ret) = 1; \ |
768 (ret) = 1; \ |
769 } else { \ |
769 } else { \ |
770 for (;;) { \ |
770 for (;;) { \ |
771 CLEAR_ERRNO; \ |
771 CLEAR_ERRNO; \ |
772 (ret) = read(fileno(f), buf, 1); \ |
772 (ret) = read(fileno(f), buf, 1); \ |
773 DEBUGBUFFER(buf); \ |
773 DEBUGBUFFER(buf); \ |
774 if ((ret) >= 0) break; \ |
774 if ((ret) >= 0) break; \ |
775 if (errno != EINTR) { \ |
775 if (errno != EINTR) { \ |
776 break; \ |
776 break; \ |
777 } \ |
777 } \ |
778 __HANDLE_INTERRUPTS__; \ |
778 __HANDLE_INTERRUPTS__; \ |
779 } \ |
779 } \ |
780 } \ |
780 } \ |
781 } |
781 } |
782 # endif /* use STDIO */ |
782 # endif /* use STDIO */ |
783 |
783 |
784 /* |
784 /* |
785 * read_bytes into a c-buffer |
785 * read_bytes into a c-buffer |
786 * (which may NOT move) |
786 * (which may NOT move) |
787 */ |
787 */ |
788 # ifdef NO_STDIO |
788 # ifdef NO_STDIO |
789 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
789 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
790 { \ |
790 { \ |
791 int __offs = 0, __cnt; \ |
791 int __offs = 0, __cnt; \ |
792 \ |
792 \ |
793 while (__offs < (cnt)) { \ |
793 while (__offs < (cnt)) { \ |
794 OBJ rA = __INST(readAhead); \ |
794 OBJ rA = __INST(readAhead); \ |
795 if (rA != nil) { \ |
795 if (rA != nil) { \ |
796 (buf)[__offs] = __intVal(rA); \ |
796 (buf)[__offs] = __intVal(rA); \ |
797 DEBUGBUFFER(buf); \ |
797 DEBUGBUFFER(buf); \ |
798 __INST(readAhead) = nil; \ |
798 __INST(readAhead) = nil; \ |
799 __offs++; \ |
799 __offs++; \ |
800 } else { \ |
800 } else { \ |
801 CLEAR_ERRNO; \ |
801 CLEAR_ERRNO; \ |
802 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
802 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
803 DEBUGBUFFER(buf); \ |
803 DEBUGBUFFER(buf); \ |
804 if (__cnt <= 0) { \ |
804 if (__cnt <= 0) { \ |
805 if (__cnt < 0 && errno == EINTR) { \ |
805 if (__cnt < 0 && errno == EINTR) { \ |
806 __HANDLE_INTERRUPTS__; \ |
806 __HANDLE_INTERRUPTS__; \ |
807 continue; \ |
807 continue; \ |
808 } \ |
808 } \ |
809 break; \ |
809 break; \ |
810 } \ |
810 } \ |
811 __offs += __cnt; \ |
811 __offs += __cnt; \ |
812 } \ |
812 } \ |
813 } \ |
813 } \ |
814 if (__offs > 0) \ |
814 if (__offs > 0) \ |
815 (ret) = __offs; \ |
815 (ret) = __offs; \ |
816 } |
816 } |
817 # else /* use STDIO */ |
817 # else /* use STDIO */ |
818 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
818 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
819 (ret) = 0; \ |
819 (ret) = 0; \ |
820 if (isBuffered) { \ |
820 if (isBuffered) { \ |
821 int __offs = 0; \ |
821 int __offs = 0; \ |
822 while (__offs < (cnt)) { \ |
822 while (__offs < (cnt)) { \ |
823 CLEAR_ERRNO; \ |
823 CLEAR_ERRNO; \ |
824 (ret) = getc(f); \ |
824 (ret) = getc(f); \ |
825 if ((ret) < 0) { \ |
825 if ((ret) < 0) { \ |
826 if (ferror(f)) { \ |
826 if (ferror(f)) { \ |
827 if (errno == EINTR) { \ |
827 if (errno == EINTR) { \ |
828 __HANDLE_INTERRUPTS__; \ |
828 __HANDLE_INTERRUPTS__; \ |
829 clearerr(f); \ |
829 clearerr(f); \ |
830 continue; \ |
830 continue; \ |
831 } \ |
831 } \ |
832 } else { \ |
832 } else { \ |
833 (ret) = 0; \ |
833 (ret) = 0; \ |
834 } \ |
834 } \ |
835 break; \ |
835 break; \ |
836 } \ |
836 } \ |
837 DEBUGBUFFER(buf); \ |
837 DEBUGBUFFER(buf); \ |
838 (buf)[__offs++] = (ret); \ |
838 (buf)[__offs++] = (ret); \ |
839 } \ |
839 } \ |
840 if (__offs > 0) \ |
840 if (__offs > 0) \ |
841 (ret) = __offs; \ |
841 (ret) = __offs; \ |
842 } else { \ |
842 } else { \ |
843 int __offs = 0, __cnt; \ |
843 int __offs = 0, __cnt; \ |
844 int fd = fileno(f); \ |
844 int fd = fileno(f); \ |
845 \ |
845 \ |
846 while (__offs < (cnt)) { \ |
846 while (__offs < (cnt)) { \ |
847 OBJ rA = __INST(readAhead); \ |
847 OBJ rA = __INST(readAhead); \ |
848 if (rA != nil) { \ |
848 if (rA != nil) { \ |
849 DEBUGBUFFER(buf); \ |
849 DEBUGBUFFER(buf); \ |
850 (buf)[__offs] = __intVal(rA); \ |
850 (buf)[__offs] = __intVal(rA); \ |
851 __INST(readAhead) = nil; \ |
851 __INST(readAhead) = nil; \ |
852 __offs++; \ |
852 __offs++; \ |
853 } else { \ |
853 } else { \ |
854 CLEAR_ERRNO; \ |
854 CLEAR_ERRNO; \ |
855 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
855 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
856 DEBUGBUFFER(buf); \ |
856 DEBUGBUFFER(buf); \ |
857 if (__cnt <= 0) { \ |
857 if (__cnt <= 0) { \ |
858 if (__cnt < 0 && errno == EINTR) { \ |
858 if (__cnt < 0 && errno == EINTR) { \ |
859 __HANDLE_INTERRUPTS__; \ |
859 __HANDLE_INTERRUPTS__; \ |
860 continue; \ |
860 continue; \ |
861 } \ |
861 } \ |
862 break; \ |
862 break; \ |
863 } \ |
863 } \ |
864 __offs += __cnt; \ |
864 __offs += __cnt; \ |
865 } \ |
865 } \ |
866 } \ |
866 } \ |
867 if (__offs > 0) \ |
867 if (__offs > 0) \ |
868 (ret) = __offs; \ |
868 (ret) = __offs; \ |
869 } |
869 } |
870 |
870 |
871 |
871 |
872 /* |
872 /* |
873 * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc... |
873 * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc... |
874 */ |
874 */ |
875 |
875 |
876 # if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY)) |
876 # if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY)) |
877 # define SETFLAGS(fd, flags) \ |
877 # define SETFLAGS(fd, flags) \ |
878 fcntl(fd, F_SETFL, flags) |
878 fcntl(fd, F_SETFL, flags) |
879 |
879 |
880 # if defined(O_NONBLOCK) |
880 # if defined(O_NONBLOCK) |
881 # define __STX_NONBLOCK_FLAG O_NONBLOCK |
881 # define __STX_NONBLOCK_FLAG O_NONBLOCK |
882 # else |
882 # else |
883 # if defined(O_NDELAY) |
883 # if defined(O_NDELAY) |
886 # define __STX_NONBLOCK_FLAG FNDELAY |
886 # define __STX_NONBLOCK_FLAG FNDELAY |
887 # endif |
887 # endif |
888 # endif |
888 # endif |
889 |
889 |
890 # define SETNONBLOCKING(fd, oldFlags) \ |
890 # define SETNONBLOCKING(fd, oldFlags) \ |
891 { \ |
891 { \ |
892 int flags = fcntl(fd, F_GETFL, 0); \ |
892 int flags = fcntl(fd, F_GETFL, 0); \ |
893 if (flags >= 0) { \ |
893 if (flags >= 0) { \ |
894 fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \ |
894 fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \ |
895 } \ |
895 } \ |
896 oldFlags = flags; \ |
896 oldFlags = flags; \ |
897 } |
897 } |
898 # else |
898 # else |
899 # define SETFLAGS(fd, flags) /* nothing */ |
899 # define SETFLAGS(fd, flags) /* nothing */ |
900 # define SETNONBLOCKING(fd, oldFlags) /* nothing */ |
900 # define SETNONBLOCKING(fd, oldFlags) /* nothing */ |
901 # endif |
901 # endif |
902 |
902 |
903 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
903 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
904 { \ |
904 { \ |
905 int __offs = 0, __cnt; \ |
905 int __offs = 0, __cnt; \ |
906 int oldFlags; \ |
906 int oldFlags; \ |
907 \ |
907 \ |
908 (ret) = 0; \ |
908 (ret) = 0; \ |
909 SETNONBLOCKING(fileno(f), oldFlags); \ |
909 SETNONBLOCKING(fileno(f), oldFlags); \ |
910 if (isBuffered) { \ |
910 if (isBuffered) { \ |
911 while (__offs < (cnt)) { \ |
911 while (__offs < (cnt)) { \ |
912 CLEAR_ERRNO; \ |
912 CLEAR_ERRNO; \ |
913 (ret) = getc(f); \ |
913 (ret) = getc(f); \ |
914 if ((ret) < 0) { \ |
914 if ((ret) < 0) { \ |
915 if (ferror(f)) { \ |
915 if (ferror(f)) { \ |
916 if (errno == EINTR) { \ |
916 if (errno == EINTR) { \ |
917 (ret) = 0; \ |
917 (ret) = 0; \ |
918 clearerr(f); \ |
918 clearerr(f); \ |
919 break; \ |
919 break; \ |
920 } \ |
920 } \ |
921 } else { \ |
921 } else { \ |
922 (ret) = 0; \ |
922 (ret) = 0; \ |
923 } \ |
923 } \ |
924 break; \ |
924 break; \ |
925 } \ |
925 } \ |
926 (buf)[__offs++] = (ret); \ |
926 (buf)[__offs++] = (ret); \ |
927 DEBUGBUFFER(buf); \ |
927 DEBUGBUFFER(buf); \ |
928 } \ |
928 } \ |
929 if (__offs > 0) \ |
929 if (__offs > 0) \ |
930 (ret) = __offs; \ |
930 (ret) = __offs; \ |
931 } else { \ |
931 } else { \ |
932 int fd = fileno(f); \ |
932 int fd = fileno(f); \ |
933 \ |
933 \ |
934 while (__offs < (cnt)) { \ |
934 while (__offs < (cnt)) { \ |
935 OBJ rA = __INST(readAhead); \ |
935 OBJ rA = __INST(readAhead); \ |
936 if (rA != nil) { \ |
936 if (rA != nil) { \ |
937 (buf)[__offs] = __intVal(rA); \ |
937 (buf)[__offs] = __intVal(rA); \ |
938 DEBUGBUFFER(buf); \ |
938 DEBUGBUFFER(buf); \ |
939 __INST(readAhead) = nil; \ |
939 __INST(readAhead) = nil; \ |
940 __offs++; \ |
940 __offs++; \ |
941 continue; \ |
941 continue; \ |
942 } \ |
942 } \ |
943 CLEAR_ERRNO; \ |
943 CLEAR_ERRNO; \ |
944 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
944 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
945 DEBUGBUFFER(buf); \ |
945 DEBUGBUFFER(buf); \ |
946 if (__cnt > 0) { \ |
946 if (__cnt > 0) { \ |
947 __offs += __cnt; \ |
947 __offs += __cnt; \ |
948 } \ |
948 } \ |
949 break; \ |
949 break; \ |
950 } \ |
950 } \ |
951 if (__offs > 0) \ |
951 if (__offs > 0) \ |
952 (ret) = __offs; \ |
952 (ret) = __offs; \ |
953 } \ |
953 } \ |
954 SETFLAGS(fileno(f), oldFlags); \ |
954 SETFLAGS(fileno(f), oldFlags); \ |
955 } |
955 } |
956 |
956 |
957 # endif /* use STDIO */ |
957 # endif /* use STDIO */ |
965 { \ |
965 { \ |
966 int __ooffs = obj_offs; \ |
966 int __ooffs = obj_offs; \ |
967 int __offs = 0; \ |
967 int __offs = 0; \ |
968 int __cnt; \ |
968 int __cnt; \ |
969 char *buf = (char *)(obj); \ |
969 char *buf = (char *)(obj); \ |
970 \ |
970 \ |
971 (ret) = 0; \ |
971 (ret) = 0; \ |
972 { \ |
972 { \ |
973 while (__offs < (cnt)) { \ |
973 while (__offs < (cnt)) { \ |
974 OBJ rA = __INST(readAhead); \ |
974 OBJ rA = __INST(readAhead); \ |
975 if (rA != nil) { \ |
975 if (rA != nil) { \ |
976 (buf)[__ooffs+__offs] = __intVal(rA); \ |
976 (buf)[__ooffs+__offs] = __intVal(rA); \ |
977 DEBUGBUFFER(buf); \ |
977 DEBUGBUFFER(buf); \ |
978 __INST(readAhead) = nil; \ |
978 __INST(readAhead) = nil; \ |
979 __offs++; \ |
979 __offs++; \ |
980 } else { \ |
980 } else { \ |
981 CLEAR_ERRNO; \ |
981 CLEAR_ERRNO; \ |
982 __cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \ |
982 __cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \ |
983 DEBUGBUFFER(buf); \ |
983 DEBUGBUFFER(buf); \ |
984 if (__cnt <= 0) { \ |
984 if (__cnt <= 0) { \ |
985 if (__cnt < 0 && errno == EINTR) { \ |
985 if (__cnt < 0 && errno == EINTR) { \ |
986 __HANDLE_INTERRUPTS__; \ |
986 __HANDLE_INTERRUPTS__; \ |
987 /* refetch */ \ |
987 /* refetch */ \ |
988 buf = (char *)(obj); \ |
988 buf = (char *)(obj); \ |
989 continue; \ |
989 continue; \ |
990 } \ |
990 } \ |
991 break; \ |
991 break; \ |
992 } \ |
992 } \ |
993 __offs += __cnt; \ |
993 __offs += __cnt; \ |
994 } \ |
994 } \ |
995 } \ |
995 } \ |
996 if (__offs > 0) \ |
996 if (__offs > 0) \ |
997 (ret) = __offs; \ |
997 (ret) = __offs; \ |
998 } \ |
998 } \ |
999 } |
999 } |
1000 |
1000 |
1001 # else /* use STDIO */ |
1001 # else /* use STDIO */ |
1002 |
1002 |
1004 { \ |
1004 { \ |
1005 int __ooffs = obj_offs; \ |
1005 int __ooffs = obj_offs; \ |
1006 int __offs = 0; \ |
1006 int __offs = 0; \ |
1007 int __cnt; \ |
1007 int __cnt; \ |
1008 char *buf = (char *)(obj); \ |
1008 char *buf = (char *)(obj); \ |
1009 \ |
1009 \ |
1010 (ret) = 0; \ |
1010 (ret) = 0; \ |
1011 if (isBuffered) { \ |
1011 if (isBuffered) { \ |
1012 while (__offs < (cnt)) { \ |
1012 while (__offs < (cnt)) { \ |
1013 CLEAR_ERRNO; \ |
1013 CLEAR_ERRNO; \ |
1014 (ret) = getc(f); \ |
1014 (ret) = getc(f); \ |
1015 if ((ret) < 0) { \ |
1015 if ((ret) < 0) { \ |
1016 if (ferror(f)) { \ |
1016 if (ferror(f)) { \ |
1017 if (errno == EINTR) { \ |
1017 if (errno == EINTR) { \ |
1018 __HANDLE_INTERRUPTS__; \ |
1018 __HANDLE_INTERRUPTS__; \ |
1019 clearerr(f); \ |
1019 clearerr(f); \ |
1020 /* refetch */ \ |
1020 /* refetch */ \ |
1021 buf = (char *)(obj); \ |
1021 buf = (char *)(obj); \ |
1022 DEBUGBUFFER(buf); \ |
1022 DEBUGBUFFER(buf); \ |
1023 continue; \ |
1023 continue; \ |
1024 } \ |
1024 } \ |
1025 } else { \ |
1025 } else { \ |
1026 (ret) = 0; \ |
1026 (ret) = 0; \ |
1027 } \ |
1027 } \ |
1028 break; \ |
1028 break; \ |
1029 } \ |
1029 } \ |
1030 (buf)[__ooffs+__offs] = (ret); \ |
1030 (buf)[__ooffs+__offs] = (ret); \ |
1031 DEBUGBUFFER(buf); \ |
1031 DEBUGBUFFER(buf); \ |
1032 __offs++; \ |
1032 __offs++; \ |
1033 } \ |
1033 } \ |
1034 if (__offs > 0) \ |
1034 if (__offs > 0) \ |
1035 (ret) = __offs; \ |
1035 (ret) = __offs; \ |
1036 } else { \ |
1036 } else { \ |
1037 int fd = fileno(f); \ |
1037 int fd = fileno(f); \ |
1038 \ |
1038 \ |
1039 while (__offs < (cnt)) { \ |
1039 while (__offs < (cnt)) { \ |
1040 OBJ rA = __INST(readAhead); \ |
1040 OBJ rA = __INST(readAhead); \ |
1041 if (rA != nil) { \ |
1041 if (rA != nil) { \ |
1042 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1042 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1043 DEBUGBUFFER(buf); \ |
1043 DEBUGBUFFER(buf); \ |
1044 __INST(readAhead) = nil; \ |
1044 __INST(readAhead) = nil; \ |
1045 __offs++; \ |
1045 __offs++; \ |
1046 } else { \ |
1046 } else { \ |
1047 CLEAR_ERRNO; \ |
1047 CLEAR_ERRNO; \ |
1048 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1048 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1049 DEBUGBUFFER(buf); \ |
1049 DEBUGBUFFER(buf); \ |
1050 if (__cnt <= 0) { \ |
1050 if (__cnt <= 0) { \ |
1051 if (__cnt < 0 && errno == EINTR) { \ |
1051 if (__cnt < 0 && errno == EINTR) { \ |
1052 __HANDLE_INTERRUPTS__; \ |
1052 __HANDLE_INTERRUPTS__; \ |
1053 /* refetch */ \ |
1053 /* refetch */ \ |
1054 buf = (char *)(obj); \ |
1054 buf = (char *)(obj); \ |
1055 continue; \ |
1055 continue; \ |
1056 } \ |
1056 } \ |
1057 break; \ |
1057 break; \ |
1058 } \ |
1058 } \ |
1059 __offs += __cnt; \ |
1059 __offs += __cnt; \ |
1060 } \ |
1060 } \ |
1061 } \ |
1061 } \ |
1062 if (__offs > 0) \ |
1062 if (__offs > 0) \ |
1063 (ret) = __offs; \ |
1063 (ret) = __offs; \ |
1064 } \ |
1064 } \ |
1065 } |
1065 } |
1066 |
1066 |
1067 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1067 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1068 { \ |
1068 { \ |
1069 int __ooffs = obj_offs; \ |
1069 int __ooffs = obj_offs; \ |
1070 int __offs = 0; \ |
1070 int __offs = 0; \ |
1071 int __cnt; \ |
1071 int __cnt; \ |
1072 char *buf = (char *)(obj); \ |
1072 char *buf = (char *)(obj); \ |
1073 int oldFlags; \ |
1073 int oldFlags; \ |
1074 \ |
1074 \ |
1075 (ret) = 0; \ |
1075 (ret) = 0; \ |
1076 SETNONBLOCKING(fileno(f), oldFlags); \ |
1076 SETNONBLOCKING(fileno(f), oldFlags); \ |
1077 \ |
1077 \ |
1078 if (isBuffered) { \ |
1078 if (isBuffered) { \ |
1079 while (__offs < (cnt)) { \ |
1079 while (__offs < (cnt)) { \ |
1080 CLEAR_ERRNO; \ |
1080 CLEAR_ERRNO; \ |
1081 (ret) = getc(f); \ |
1081 (ret) = getc(f); \ |
1082 if ((ret) < 0) { \ |
1082 if ((ret) < 0) { \ |
1083 if (ferror(f)) { \ |
1083 if (ferror(f)) { \ |
1084 if (errno == EINTR) { \ |
1084 if (errno == EINTR) { \ |
1085 clearerr(f); \ |
1085 clearerr(f); \ |
1086 /* refetch */ \ |
1086 /* refetch */ \ |
1087 buf = (char *)(obj); \ |
1087 buf = (char *)(obj); \ |
1088 (ret) = 0; \ |
1088 (ret) = 0; \ |
1089 break; \ |
1089 break; \ |
1090 } \ |
1090 } \ |
1091 } else { \ |
1091 } else { \ |
1092 (ret) = 0; \ |
1092 (ret) = 0; \ |
1093 } \ |
1093 } \ |
1094 break; \ |
1094 break; \ |
1095 } \ |
1095 } \ |
1096 (buf)[__ooffs+__offs] = (ret); \ |
1096 (buf)[__ooffs+__offs] = (ret); \ |
1097 DEBUGBUFFER(buf); \ |
1097 DEBUGBUFFER(buf); \ |
1098 __offs++; \ |
1098 __offs++; \ |
1099 } \ |
1099 } \ |
1100 if (__offs > 0) \ |
1100 if (__offs > 0) \ |
1101 (ret) = __offs; \ |
1101 (ret) = __offs; \ |
1102 } else { \ |
1102 } else { \ |
1103 int fd = fileno(f); \ |
1103 int fd = fileno(f); \ |
1104 \ |
1104 \ |
1105 while (__offs < (cnt)) { \ |
1105 while (__offs < (cnt)) { \ |
1106 OBJ rA = __INST(readAhead); \ |
1106 OBJ rA = __INST(readAhead); \ |
1107 if (rA != nil) { \ |
1107 if (rA != nil) { \ |
1108 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1108 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1109 DEBUGBUFFER(buf); \ |
1109 DEBUGBUFFER(buf); \ |
1110 __INST(readAhead) = nil; \ |
1110 __INST(readAhead) = nil; \ |
1111 __offs++; \ |
1111 __offs++; \ |
1112 continue; \ |
1112 continue; \ |
1113 } \ |
1113 } \ |
1114 CLEAR_ERRNO; \ |
1114 CLEAR_ERRNO; \ |
1115 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1115 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1116 DEBUGBUFFER(buf); \ |
1116 DEBUGBUFFER(buf); \ |
1117 if (__cnt > 0) { \ |
1117 if (__cnt > 0) { \ |
1118 __offs += __cnt; \ |
1118 __offs += __cnt; \ |
1119 } \ |
1119 } \ |
1120 break; \ |
1120 break; \ |
1121 } \ |
1121 } \ |
1122 if (__offs > 0) \ |
1122 if (__offs > 0) \ |
1123 (ret) = __offs; \ |
1123 (ret) = __offs; \ |
1124 } \ |
1124 } \ |
1125 SETFLAGS(fileno(f), oldFlags); \ |
1125 SETFLAGS(fileno(f), oldFlags); \ |
1126 } |
1126 } |
1127 |
1127 |
1128 |
1128 |
1129 # endif /* use STDIO */ |
1129 # endif /* use STDIO */ |
1130 |
1130 |
1131 # ifdef NO_STDIO |
1131 # ifdef NO_STDIO |
1132 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1132 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1133 for (;;) { \ |
1133 for (;;) { \ |
1134 CLEAR_ERRNO; \ |
1134 CLEAR_ERRNO; \ |
1135 (ret) = WRITE(f, buf, 1, handleType); \ |
1135 (ret) = WRITE(f, buf, 1, handleType); \ |
1136 if ((ret) >= 0) break; \ |
1136 if ((ret) >= 0) break; \ |
1137 if (errno != EINTR) { \ |
1137 if (errno != EINTR) { \ |
1138 break; \ |
1138 break; \ |
1139 } \ |
1139 } \ |
1140 __HANDLE_INTERRUPTS__; \ |
1140 __HANDLE_INTERRUPTS__; \ |
1141 } |
1141 } |
1142 # else /* use STDIO */ |
1142 # else /* use STDIO */ |
1143 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1143 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1144 if (isBuffered) { \ |
1144 if (isBuffered) { \ |
1145 for (;;) { \ |
1145 for (;;) { \ |
1146 CLEAR_ERRNO; \ |
1146 CLEAR_ERRNO; \ |
1147 ret = putc(*(buf), f); \ |
1147 ret = putc(*(buf), f); \ |
1148 if ((ret) >= 0) { \ |
1148 if ((ret) >= 0) { \ |
1149 (ret) = 1; \ |
1149 (ret) = 1; \ |
1150 } else if (ferror(f)) { \ |
1150 } else if (ferror(f)) { \ |
1151 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \ |
1151 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \ |
1152 if (errno == EINTR || errno == 0) { \ |
1152 if (errno == EINTR || errno == 0) { \ |
1153 __HANDLE_INTERRUPTS__; \ |
1153 __HANDLE_INTERRUPTS__; \ |
1154 clearerr(f); \ |
1154 clearerr(f); \ |
1155 continue; \ |
1155 continue; \ |
1156 } \ |
1156 } \ |
1157 } else \ |
1157 } else \ |
1158 (ret) = 0; \ |
1158 (ret) = 0; \ |
1159 break; \ |
1159 break; \ |
1160 } \ |
1160 } \ |
1161 } else { \ |
1161 } else { \ |
1162 for (;;) { \ |
1162 for (;;) { \ |
1163 CLEAR_ERRNO; \ |
1163 CLEAR_ERRNO; \ |
1164 (ret) = write(fileno(f), buf, 1); \ |
1164 (ret) = write(fileno(f), buf, 1); \ |
1165 if ((ret) >= 0) break; \ |
1165 if ((ret) >= 0) break; \ |
1166 if (errno != EINTR) { \ |
1166 if (errno != EINTR) { \ |
1167 break; \ |
1167 break; \ |
1168 } \ |
1168 } \ |
1169 __HANDLE_INTERRUPTS__; \ |
1169 __HANDLE_INTERRUPTS__; \ |
1170 } \ |
1170 } \ |
1171 } |
1171 } |
1172 # endif /* use STDIO */ |
1172 # endif /* use STDIO */ |
1173 |
1173 |
1174 /* |
1174 /* |
1175 * write_bytes from a c-buffer |
1175 * write_bytes from a c-buffer |
1177 */ |
1177 */ |
1178 # ifdef NO_STDIO |
1178 # ifdef NO_STDIO |
1179 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
1179 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
1180 (ret) = 0; \ |
1180 (ret) = 0; \ |
1181 { \ |
1181 { \ |
1182 int __offs = 0; \ |
1182 int __offs = 0; \ |
1183 while (__offs < (cnt)) { \ |
1183 while (__offs < (cnt)) { \ |
1184 CLEAR_ERRNO; \ |
1184 CLEAR_ERRNO; \ |
1185 ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
1185 ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
1186 if (ret <= 0) { \ |
1186 if (ret <= 0) { \ |
1187 if (ret < 0 && errno == EINTR) { \ |
1187 if (ret < 0 && errno == EINTR) { \ |
1188 __HANDLE_INTERRUPTS__; \ |
1188 __HANDLE_INTERRUPTS__; \ |
1189 continue; \ |
1189 continue; \ |
1190 } \ |
1190 } \ |
1191 break; \ |
1191 break; \ |
1192 } \ |
1192 } \ |
1193 __offs += (ret); \ |
1193 __offs += (ret); \ |
1194 } \ |
1194 } \ |
1195 if (__offs > 0) \ |
1195 if (__offs > 0) \ |
1196 (ret) = __offs; \ |
1196 (ret) = __offs; \ |
1197 } |
1197 } |
1198 # else /* use STDIO */ |
1198 # else /* use STDIO */ |
1199 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
1199 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
1200 (ret) = 0; \ |
1200 (ret) = 0; \ |
1201 if (isBuffered) { \ |
1201 if (isBuffered) { \ |
1202 int __offs = 0; \ |
1202 int __offs = 0; \ |
1203 while (__offs < (cnt)) { \ |
1203 while (__offs < (cnt)) { \ |
1204 CLEAR_ERRNO; \ |
1204 CLEAR_ERRNO; \ |
1205 (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
1205 (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
1206 if ((ret) <= 0) { \ |
1206 if ((ret) <= 0) { \ |
1207 if (ferror(f)) { \ |
1207 if (ferror(f)) { \ |
1208 if (errno == EINTR) { \ |
1208 if (errno == EINTR) { \ |
1209 __HANDLE_INTERRUPTS__; \ |
1209 __HANDLE_INTERRUPTS__; \ |
1210 clearerr(f); \ |
1210 clearerr(f); \ |
1211 continue; \ |
1211 continue; \ |
1212 } \ |
1212 } \ |
1213 } else { \ |
1213 } else { \ |
1214 (ret) = 0; \ |
1214 (ret) = 0; \ |
1215 } \ |
1215 } \ |
1216 break; \ |
1216 break; \ |
1217 } \ |
1217 } \ |
1218 __offs += (ret); \ |
1218 __offs += (ret); \ |
1219 } \ |
1219 } \ |
1220 if (__offs > 0) \ |
1220 if (__offs > 0) \ |
1221 (ret) = __offs; \ |
1221 (ret) = __offs; \ |
1222 } else { \ |
1222 } else { \ |
1223 int __offs = 0; \ |
1223 int __offs = 0; \ |
1224 while (__offs < (cnt)) { \ |
1224 while (__offs < (cnt)) { \ |
1225 CLEAR_ERRNO; \ |
1225 CLEAR_ERRNO; \ |
1226 (ret) = write(fileno(f), (buf)+__offs, (cnt)-__offs);\ |
1226 (ret) = write(fileno(f), (buf)+__offs, (cnt)-__offs);\ |
1227 if ((ret) <= 0) { \ |
1227 if ((ret) <= 0) { \ |
1228 if ((ret) < 0) { \ |
1228 if ((ret) < 0) { \ |
1229 if (errno == EINTR) { \ |
1229 if (errno == EINTR) { \ |
1230 __HANDLE_INTERRUPTS__; \ |
1230 __HANDLE_INTERRUPTS__; \ |
1231 continue; \ |
1231 continue; \ |
1232 } \ |
1232 } \ |
1233 } \ |
1233 } \ |
1234 break; \ |
1234 break; \ |
1235 } \ |
1235 } \ |
1236 __offs += (ret); \ |
1236 __offs += (ret); \ |
1237 } \ |
1237 } \ |
1238 if (__offs > 0) \ |
1238 if (__offs > 0) \ |
1239 (ret) = __offs; \ |
1239 (ret) = __offs; \ |
1240 } |
1240 } |
1241 # endif /* use STDIO */ |
1241 # endif /* use STDIO */ |
1242 |
1242 |
1243 /* |
1243 /* |
1244 * write_bytes from an object |
1244 * write_bytes from an object |
1248 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1248 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1249 { \ |
1249 { \ |
1250 int __ooffs = obj_offs; \ |
1250 int __ooffs = obj_offs; \ |
1251 int __offs = 0; \ |
1251 int __offs = 0; \ |
1252 char *buf = (char *)(obj); \ |
1252 char *buf = (char *)(obj); \ |
1253 \ |
1253 \ |
1254 (ret) = 0; \ |
1254 (ret) = 0; \ |
1255 { \ |
1255 { \ |
1256 while (__offs < (cnt)) { \ |
1256 while (__offs < (cnt)) { \ |
1257 CLEAR_ERRNO; \ |
1257 CLEAR_ERRNO; \ |
1258 ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \ |
1258 ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \ |
1259 if (ret <= 0) { \ |
1259 if (ret <= 0) { \ |
1260 if (ret < 0 && errno == EINTR) { \ |
1260 if (ret < 0 && errno == EINTR) { \ |
1261 __HANDLE_INTERRUPTS__; \ |
1261 __HANDLE_INTERRUPTS__; \ |
1262 /* refetch */ \ |
1262 /* refetch */ \ |
1263 buf = (char *)(obj); \ |
1263 buf = (char *)(obj); \ |
1264 continue; \ |
1264 continue; \ |
1265 } \ |
1265 } \ |
1266 break; \ |
1266 break; \ |
1267 } \ |
1267 } \ |
1268 __offs += (ret); \ |
1268 __offs += (ret); \ |
1269 } \ |
1269 } \ |
1270 if (__offs > 0) \ |
1270 if (__offs > 0) \ |
1271 (ret) = __offs; \ |
1271 (ret) = __offs; \ |
1272 } \ |
1272 } \ |
1273 } |
1273 } |
1274 # else /* use STDIO */ |
1274 # else /* use STDIO */ |
1275 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1275 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1276 { \ |
1276 { \ |
1277 int __ooffs = obj_offs; \ |
1277 int __ooffs = obj_offs; \ |
1278 int __offs = 0; \ |
1278 int __offs = 0; \ |
1279 char *buf = (char *)(obj); \ |
1279 char *buf = (char *)(obj); \ |
1280 \ |
1280 \ |
1281 (ret) = 0; \ |
1281 (ret) = 0; \ |
1282 if (isBuffered) { \ |
1282 if (isBuffered) { \ |
1283 while (__offs < (cnt)) { \ |
1283 while (__offs < (cnt)) { \ |
1284 CLEAR_ERRNO; \ |
1284 CLEAR_ERRNO; \ |
1285 (ret) = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
1285 (ret) = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
1286 if ((ret) <= 0) { \ |
1286 if ((ret) <= 0) { \ |
1287 if (ferror(f)) { \ |
1287 if (ferror(f)) { \ |
1288 if (errno == EINTR) { \ |
1288 if (errno == EINTR) { \ |
1289 __HANDLE_INTERRUPTS__; \ |
1289 __HANDLE_INTERRUPTS__; \ |
1290 /* refetch */ \ |
1290 /* refetch */ \ |
1291 buf = (char *)(obj); \ |
1291 buf = (char *)(obj); \ |
1292 clearerr(f); \ |
1292 clearerr(f); \ |
1293 continue; \ |
1293 continue; \ |
1294 } \ |
1294 } \ |
1295 break; \ |
1295 break; \ |
1296 } else { \ |
1296 } else { \ |
1297 (ret) = 0; \ |
1297 (ret) = 0; \ |
1298 } \ |
1298 } \ |
1299 } \ |
1299 } \ |
1300 __offs += (ret); \ |
1300 __offs += (ret); \ |
1301 } \ |
1301 } \ |
1302 } else { \ |
1302 } else { \ |
1303 while (__offs < (cnt)) { \ |
1303 while (__offs < (cnt)) { \ |
1304 CLEAR_ERRNO; \ |
1304 CLEAR_ERRNO; \ |
1305 (ret) = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1305 (ret) = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1306 if ((ret) <= 0) { \ |
1306 if ((ret) <= 0) { \ |
1307 if ((ret) < 0) { \ |
1307 if ((ret) < 0) { \ |
1308 if (errno == EINTR){ \ |
1308 if (errno == EINTR){ \ |
1309 __HANDLE_INTERRUPTS__; \ |
1309 __HANDLE_INTERRUPTS__; \ |
1310 /* refetch */ \ |
1310 /* refetch */ \ |
1311 buf = (char *)(obj); \ |
1311 buf = (char *)(obj); \ |
1312 continue; \ |
1312 continue; \ |
1313 } \ |
1313 } \ |
1314 } \ |
1314 } \ |
1315 break; \ |
1315 break; \ |
1316 } \ |
1316 } \ |
1317 __offs += (ret); \ |
1317 __offs += (ret); \ |
1318 } \ |
1318 } \ |
1319 } \ |
1319 } \ |
1320 if (__offs > 0) \ |
1320 if (__offs > 0) \ |
1321 (ret) = __offs; \ |
1321 (ret) = __offs; \ |
1322 } |
1322 } |
1323 # endif /* use STDIO */ |
1323 # endif /* use STDIO */ |
1324 #endif /* unix */ |
1324 #endif /* unix */ |
1325 %} |
1325 %} |
1326 ! ! |
1326 ! ! |
4986 if ((__INST(handleType) == nil) |
4986 if ((__INST(handleType) == nil) |
4987 || (__INST(handleType) == @symbol(filePointer)) |
4987 || (__INST(handleType) == @symbol(filePointer)) |
4988 || (__INST(handleType) == @symbol(socketFilePointer)) |
4988 || (__INST(handleType) == @symbol(socketFilePointer)) |
4989 || (__INST(handleType) == @symbol(socketHandle)) |
4989 || (__INST(handleType) == @symbol(socketHandle)) |
4990 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4990 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4991 if (((fp = __INST(handle)) != nil) |
4991 if (((fp = __INST(handle)) != nil) |
4992 && (__INST(mode) != @symbol(writeonly)) |
4992 && (__INST(mode) != @symbol(writeonly)) |
4993 ) { |
4993 ) { |
4994 f = __FILEVal(fp); |
4994 f = __FILEVal(fp); |
4995 |
4995 |
4996 _buffered = (__INST(buffered) == true); |
4996 _buffered = (__INST(buffered) == true); |
4997 if (_buffered) { |
4997 if (_buffered) { |
4998 __READING__(f) |
4998 __READING__(f) |
4999 } |
4999 } |
5000 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
5000 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
5001 |
5001 |
5002 if (ret > 0) { |
5002 if (ret > 0) { |
5003 pos = __INST(position); |
5003 pos = __INST(position); |
5004 if (__isSmallInteger(pos)) { |
5004 if (__isSmallInteger(pos)) { |
5005 OBJ t; |
5005 OBJ t; |
5006 |
5006 |
5007 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
5007 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
5008 } else { |
5008 } else { |
5009 __INST(position) = nil; /* i.e. do not know */ |
5009 __INST(position) = nil; /* i.e. do not know */ |
5010 } |
5010 } |
5011 if (__INST(binary) == true) { |
5011 if (__INST(binary) == true) { |
5012 RETURN ( __mkSmallInteger(ch) ); |
5012 RETURN ( __mkSmallInteger(ch) ); |
5013 } |
5013 } |
5014 RETURN ( __MKCHARACTER(ch) ); |
5014 RETURN ( __MKCHARACTER(ch) ); |
5015 } |
5015 } |
5016 |
5016 |
5017 __INST(position) = nil; |
5017 __INST(position) = nil; |
5018 if (ret < 0) { |
5018 if (ret < 0) { |
5019 error = __mkSmallInteger(__threadErrno); |
5019 error = __mkSmallInteger(__threadErrno); |
5020 } else /* ret == 0 */ { |
5020 } else /* ret == 0 */ { |
5021 __INST(hitEOF) = true; |
5021 __INST(hitEOF) = true; |
5022 } |
5022 } |
5023 } |
5023 } |
5024 } |
5024 } |
5025 %}. |
5025 %}. |
5026 hitEOF == true ifTrue:[^ self pastEndRead]. |
5026 hitEOF == true ifTrue:[^ self pastEndRead]. |
5027 error notNil ifTrue:[ |
5027 error notNil ifTrue:[ |
5028 lastErrorNumber := error. |
5028 lastErrorNumber := error. |
5029 ^ self readError:error |
5029 ^ self readError:error |
5030 ]. |
5030 ]. |
5031 handle isNil ifTrue:[^ self errorNotOpen]. |
5031 handle isNil ifTrue:[^ self errorNotOpen]. |
5032 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5032 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5033 |
5033 |
5034 readAhead notNil ifTrue:[ |
5034 readAhead notNil ifTrue:[ |
5035 c := readAhead. |
5035 c := readAhead. |
5036 readAhead := nil. |
5036 readAhead := nil. |
5037 ^ c. |
5037 ^ c. |
5038 ]. |
5038 ]. |
5039 c := self nextByteFromFile:handle. |
5039 c := self nextByteFromFile:handle. |
5040 c isNil ifTrue:[ |
5040 c isNil ifTrue:[ |
5041 ^ self pastEndRead. |
5041 ^ self pastEndRead. |
5042 ]. |
5042 ]. |
5043 binary == true ifTrue:[ |
5043 binary == true ifTrue:[ |
5044 ^ c |
5044 ^ c |
5045 ]. |
5045 ]. |
5046 ^ Character value:c |
5046 ^ Character value:c |
5047 ! |
5047 ! |
5048 |
5048 |
5049 next:count |
5049 next:count |
5160 int ret, _buffered; |
5160 int ret, _buffered; |
5161 OBJ fp; |
5161 OBJ fp; |
5162 OBJ ra; |
5162 OBJ ra; |
5163 |
5163 |
5164 if ((ra = __INST(readAhead)) != nil) { |
5164 if ((ra = __INST(readAhead)) != nil) { |
5165 if (__INST(binary) == true) { |
5165 if (__INST(binary) == true) { |
5166 RETURN ( ra ); |
5166 RETURN ( ra ); |
5167 } |
5167 } |
5168 c = __intVal(ra); |
5168 c = __intVal(ra); |
5169 RETURN ( __MKCHARACTER(c) ); |
5169 RETURN ( __MKCHARACTER(c) ); |
5170 } |
5170 } |
5171 |
5171 |
5172 __INST(lastErrorNumber) = nil; |
5172 __INST(lastErrorNumber) = nil; |
5173 |
5173 |
5174 if ((__INST(handleType) == nil) |
5174 if ((__INST(handleType) == nil) |
5175 || (__INST(handleType) == @symbol(filePointer)) |
5175 || (__INST(handleType) == @symbol(filePointer)) |
5176 || (__INST(handleType) == @symbol(socketFilePointer)) |
5176 || (__INST(handleType) == @symbol(socketFilePointer)) |
5177 || (__INST(handleType) == @symbol(socketHandle)) |
5177 || (__INST(handleType) == @symbol(socketHandle)) |
5178 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5178 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5179 if (((fp = __INST(handle)) != nil) |
5179 if (((fp = __INST(handle)) != nil) |
5180 && (__INST(mode) != @symbol(writeonly)) |
5180 && (__INST(mode) != @symbol(writeonly)) |
5181 ) { |
5181 ) { |
5182 f = __FILEVal(fp); |
5182 f = __FILEVal(fp); |
5183 _buffered = (__INST(buffered) == true); |
5183 _buffered = (__INST(buffered) == true); |
5184 if (_buffered) { |
5184 if (_buffered) { |
5185 __READING__(f) |
5185 __READING__(f) |
5186 } |
5186 } |
5187 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5187 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5188 |
5188 |
5189 if (ret > 0) { |
5189 if (ret > 0) { |
5190 __UNGETC__(c, f, _buffered); |
5190 __UNGETC__(c, f, _buffered); |
5191 |
5191 |
5192 if (__INST(binary) == true) { |
5192 if (__INST(binary) == true) { |
5193 RETURN ( __mkSmallInteger(c) ); |
5193 RETURN ( __mkSmallInteger(c) ); |
5194 } |
5194 } |
5195 RETURN ( __MKCHARACTER(c) ); |
5195 RETURN ( __MKCHARACTER(c) ); |
5196 } |
5196 } |
5197 if (ret < 0) { |
5197 if (ret < 0) { |
5198 error = __mkSmallInteger(__threadErrno); |
5198 error = __mkSmallInteger(__threadErrno); |
5199 } else /* ret == 0 */ { |
5199 } else /* ret == 0 */ { |
5200 __INST(hitEOF) = true; |
5200 __INST(hitEOF) = true; |
5201 } |
5201 } |
5202 } |
5202 } |
5203 } |
5203 } |
5204 %}. |
5204 %}. |
5205 hitEOF == true ifTrue:[^ self pastEndRead]. |
5205 hitEOF == true ifTrue:[^ self pastEndRead]. |
5206 error notNil ifTrue:[ |
5206 error notNil ifTrue:[ |
5207 lastErrorNumber := error. |
5207 lastErrorNumber := error. |
5208 ^ self readError:error. |
5208 ^ self readError:error. |
5209 ]. |
5209 ]. |
5210 handle isNil ifTrue:[^ self errorNotOpen]. |
5210 handle isNil ifTrue:[^ self errorNotOpen]. |
5211 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5211 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5212 |
5212 |
5213 readAhead isNil ifTrue:[ |
5213 readAhead isNil ifTrue:[ |
5214 readAhead := self nextOrNil. |
5214 readAhead := self nextOrNil. |
5215 readAhead isNil ifTrue:[ |
5215 readAhead isNil ifTrue:[ |
5216 ^ self pastEndRead. |
5216 ^ self pastEndRead. |
5217 ]. |
5217 ]. |
5218 ]. |
5218 ]. |
5219 ^ readAhead |
5219 ^ readAhead |
5220 ! |
5220 ! |
5221 |
5221 |
5222 peekOrNil |
5222 peekOrNil |
6101 ! ! |
6101 ! ! |
6102 |
6102 |
6103 !ExternalStream class methodsFor:'documentation'! |
6103 !ExternalStream class methodsFor:'documentation'! |
6104 |
6104 |
6105 version |
6105 version |
6106 ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.394 2014-07-15 09:37:25 cg Exp $' |
6106 ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.395 2014-10-26 22:19:04 stefan Exp $' |
6107 ! |
6107 ! |
6108 |
6108 |
6109 version_CVS |
6109 version_CVS |
6110 ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.394 2014-07-15 09:37:25 cg Exp $' |
6110 ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.395 2014-10-26 22:19:04 stefan Exp $' |
6111 ! ! |
6111 ! ! |
6112 |
6112 |
6113 |
6113 |
6114 ExternalStream initialize! |
6114 ExternalStream initialize! |