changeset 17115 | 2ef08a902c34 |
parent 17078 | f3ded8a6f9d9 |
child 17332 | f223abac93ca |
17114:592d806673a8 | 17115:2ef08a902c34 |
---|---|
200 #ifdef DEBUGGING |
200 #ifdef DEBUGGING |
201 extern char *__survStartPtr, *__survEndPtr; |
201 extern char *__survStartPtr, *__survEndPtr; |
202 # define DEBUGBUFFER(buf) \ |
202 # define DEBUGBUFFER(buf) \ |
203 if (((char *)(buf) >= __survStartPtr) \ |
203 if (((char *)(buf) >= __survStartPtr) \ |
204 && ((char *)(buf) < __survEndPtr)) { \ |
204 && ((char *)(buf) < __survEndPtr)) { \ |
205 __fatal0("read into survivor\n"); \ |
205 __fatal0("read into survivor\n"); \ |
206 } |
206 } |
207 |
207 |
208 #else |
208 #else |
209 # define DEBUGBUFFER(buf) /* nothing */ |
209 # define DEBUGBUFFER(buf) /* nothing */ |
210 #endif |
210 #endif |
223 |
223 |
224 #ifdef WIN32 |
224 #ifdef WIN32 |
225 // Win returns from ReadFile() with false and _threadErrno == 0 on end of pipe. |
225 // Win returns from ReadFile() with false and _threadErrno == 0 on end of pipe. |
226 // We don't know why |
226 // We don't know why |
227 # define READ(ret, f, cp, n, handleType) { \ |
227 # define READ(ret, f, cp, n, handleType) { \ |
228 if (handleType == @symbol(socketHandle)) { \ |
228 if (handleType == @symbol(socketHandle)) { \ |
229 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \ |
229 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \ |
230 } else { \ |
230 } else { \ |
231 HANDLE h = _get_osfhandle(fileno(f)); \ |
231 HANDLE h = _get_osfhandle(fileno(f)); \ |
232 if (handleType == @symbol(socketFilePointer)) { \ |
232 if (handleType == @symbol(socketFilePointer)) { \ |
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 int __res; \ |
235 int __res; \ |
236 (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\ |
236 (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\ |
237 (ret) = (ret) ? __res : ((__threadErrno == EPIPE || __threadErrno == 0) ? 0 : -1); \ |
237 (ret) = (ret) ? __res : ((__threadErrno == EPIPE || __threadErrno == 0) ? 0 : -1); \ |
238 } \ |
238 } \ |
239 } \ |
239 } \ |
240 } |
240 } |
241 |
241 |
242 # define WRITE(ret, f, cp, n, handleType) { \ |
242 # define WRITE(ret, f, cp, n, handleType) { \ |
243 if (handleType == @symbol(socketHandle)) { \ |
243 if (handleType == @symbol(socketHandle)) { \ |
244 (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \ |
244 (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \ |
245 } else {\ |
245 } else {\ |
246 HANDLE h = _get_osfhandle(fileno(f)); \ |
246 HANDLE h = _get_osfhandle(fileno(f)); \ |
247 if (handleType == @symbol(socketFilePointer)) { \ |
247 if (handleType == @symbol(socketFilePointer)) { \ |
248 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
248 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
249 } else {\ |
249 } else {\ |
250 int __res; \ |
250 int __res; \ |
251 (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\ |
251 (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\ |
252 (ret) = (ret) ? __res : -1; \ |
252 (ret) = (ret) ? __res : -1; \ |
253 } \ |
253 } \ |
254 } \ |
254 } \ |
255 } |
255 } |
256 |
256 |
257 # define FFLUSH(fp) fflush(fp) |
257 # define FFLUSH(fp) fflush(fp) |
258 # undef STDIO_NEEDS_FSEEK |
258 # undef STDIO_NEEDS_FSEEK |
259 # define FILEPOINTER FILE * |
259 # define FILEPOINTER FILE * |
260 # define FILENO(f) fileno(f) |
260 # define FILENO(f) fileno(f) |
261 |
261 |
262 # define __READING__(f) \ |
262 # define __READING__(f) \ |
263 if ((__INST(didWrite) != false) \ |
263 if ((__INST(didWrite) != false) \ |
264 && (__INST(mode) == @symbol(readwrite))) { \ |
264 && (__INST(mode) == @symbol(readwrite))) { \ |
265 __INST(didWrite) = false; \ |
265 __INST(didWrite) = false; \ |
266 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
266 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
267 } |
267 } |
268 |
268 |
269 # define __WRITING__(f) \ |
269 # define __WRITING__(f) \ |
270 if ((__INST(didWrite) != true) \ |
270 if ((__INST(didWrite) != true) \ |
271 && (__INST(mode) == @symbol(readwrite))) { \ |
271 && (__INST(mode) == @symbol(readwrite))) { \ |
272 __INST(didWrite) = true; \ |
272 __INST(didWrite) = true; \ |
273 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
273 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
274 } |
274 } |
275 |
275 |
276 # define __UNGETC__(c, f, isBuffered) \ |
276 # define __UNGETC__(c, f, isBuffered) \ |
277 if (isBuffered) { \ |
277 if (isBuffered) { \ |
278 ungetc((c), (f)); \ |
278 ungetc((c), (f)); \ |
279 } else { \ |
279 } else { \ |
280 __INST(readAhead) = __mkSmallInteger((c)); \ |
280 __INST(readAhead) = __mkSmallInteger((c)); \ |
281 } |
281 } |
282 |
282 |
283 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
283 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
284 if (isBuffered) { \ |
284 if (isBuffered) { \ |
285 for (;;) { \ |
285 for (;;) { \ |
286 CLEAR_ERRNO; \ |
286 CLEAR_ERRNO; \ |
287 (ret) = getc(f); \ |
287 (ret) = getc(f); \ |
288 if ((ret) >= 0) { \ |
288 if ((ret) >= 0) { \ |
289 *(buf) = (ret); \ |
289 *(buf) = (ret); \ |
290 (ret) = 1; \ |
290 (ret) = 1; \ |
291 } else if (ferror(f)) { \ |
291 } else if (ferror(f)) { \ |
292 if (__threadErrno == EINTR) { \ |
292 if (__threadErrno == EINTR) { \ |
293 clearerr(f); \ |
293 clearerr(f); \ |
294 continue; \ |
294 continue; \ |
295 } \ |
295 } \ |
296 } else { \ |
296 } else { \ |
297 (ret) = 0; \ |
297 (ret) = 0; \ |
298 } \ |
298 } \ |
299 break; \ |
299 break; \ |
300 } \ |
300 } \ |
301 } else { \ |
301 } else { \ |
302 OBJ rA = __INST(readAhead); \ |
302 OBJ rA = __INST(readAhead); \ |
303 if (rA != nil) { \ |
303 if (rA != nil) { \ |
304 *(buf) = (char)__intVal(rA); \ |
304 *(buf) = (char)__intVal(rA); \ |
305 __INST(readAhead) = nil; \ |
305 __INST(readAhead) = nil; \ |
306 (ret) = 1; \ |
306 (ret) = 1; \ |
307 } else { \ |
307 } else { \ |
308 for (;;) { \ |
308 for (;;) { \ |
309 CLEAR_ERRNO; \ |
309 CLEAR_ERRNO; \ |
310 READ((ret), f, buf, 1, handleType); \ |
310 READ((ret), f, buf, 1, handleType); \ |
311 if ((ret) >= 0 || __threadErrno != EINTR) \ |
311 if ((ret) >= 0 || __threadErrno != EINTR) \ |
312 break; \ |
312 break; \ |
313 } \ |
313 } \ |
314 } \ |
314 } \ |
315 } |
315 } |
316 |
316 |
317 /* |
317 /* |
318 * read_bytes into a c-buffer |
318 * read_bytes into a c-buffer |
319 * (which may NOT move) |
319 * (which may NOT move) |
320 */ |
320 */ |
321 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
321 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
322 (ret) = 0; \ |
322 (ret) = 0; \ |
323 if (isBuffered) { \ |
323 if (isBuffered) { \ |
324 int __offs = 0; \ |
324 int __offs = 0; \ |
325 while (__offs < (cnt)) { \ |
325 while (__offs < (cnt)) { \ |
326 CLEAR_ERRNO; \ |
326 CLEAR_ERRNO; \ |
327 (ret) = getc(f); \ |
327 (ret) = getc(f); \ |
328 if ((ret) < 0) { \ |
328 if ((ret) < 0) { \ |
329 if (ferror(f)) { \ |
329 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 (buf)[__offs++] = (ret); \ |
339 (buf)[__offs++] = (ret); \ |
340 } \ |
340 } \ |
341 if (__offs > 0) \ |
341 if (__offs > 0) \ |
342 (ret) = __offs; \ |
342 (ret) = __offs; \ |
343 } else { \ |
343 } else { \ |
344 int __offs = 0; \ |
344 int __offs = 0; \ |
345 \ |
345 \ |
346 while (__offs < (cnt)) { \ |
346 while (__offs < (cnt)) { \ |
347 OBJ rA = __INST(readAhead); \ |
347 OBJ rA = __INST(readAhead); \ |
348 if (rA != nil) { \ |
348 if (rA != nil) { \ |
349 (buf)[__offs] = __intVal(rA); \ |
349 (buf)[__offs] = __intVal(rA); \ |
350 __INST(readAhead) = nil; \ |
350 __INST(readAhead) = nil; \ |
351 (ret) = 1; \ |
351 (ret) = 1; \ |
352 } else { \ |
352 } else { \ |
353 CLEAR_ERRNO; \ |
353 CLEAR_ERRNO; \ |
354 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \ |
354 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \ |
355 if ((ret) <= 0) { \ |
355 if ((ret) <= 0) { \ |
356 if ((ret) < 0 && __threadErrno == EINTR) { \ |
356 if ((ret) < 0 && __threadErrno == EINTR) { \ |
357 continue; \ |
357 continue; \ |
358 } \ |
358 } \ |
359 break; \ |
359 break; \ |
360 } \ |
360 } \ |
361 } \ |
361 } \ |
362 __offs += (ret); \ |
362 __offs += (ret); \ |
363 } \ |
363 } \ |
364 if (__offs > 0) \ |
364 if (__offs > 0) \ |
365 (ret) = __offs; \ |
365 (ret) = __offs; \ |
366 } |
366 } |
367 |
367 |
368 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
368 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
369 { \ |
369 { \ |
370 int __offs = 0; \ |
370 int __offs = 0; \ |
371 int oldFlags; \ |
371 int oldFlags; \ |
372 \ |
372 \ |
373 (ret) = 0; \ |
373 (ret) = 0; \ |
374 if (isBuffered) { \ |
374 if (isBuffered) { \ |
375 while (__offs < (cnt)) { \ |
375 while (__offs < (cnt)) { \ |
376 CLEAR_ERRNO; \ |
376 CLEAR_ERRNO; \ |
377 (ret) = getc(f); \ |
377 (ret) = getc(f); \ |
378 if ((ret) < 0) { \ |
378 if ((ret) < 0) { \ |
379 if (ferror(f)) { \ |
379 if (ferror(f)) { \ |
380 if (__threadErrno == EINTR) { \ |
380 if (__threadErrno == EINTR) { \ |
381 clearerr(f); \ |
381 clearerr(f); \ |
382 continue; \ |
382 continue; \ |
383 } \ |
383 } \ |
384 } else { \ |
384 } else { \ |
385 (ret) = 0; \ |
385 (ret) = 0; \ |
386 } \ |
386 } \ |
387 break; \ |
387 break; \ |
388 } \ |
388 } \ |
389 (buf)[__offs++] = (ret); \ |
389 (buf)[__offs++] = (ret); \ |
390 } \ |
390 } \ |
391 (ret) = __offs; \ |
391 (ret) = __offs; \ |
392 } else { \ |
392 } else { \ |
393 while (__offs < (cnt)) { \ |
393 while (__offs < (cnt)) { \ |
394 OBJ rA = __INST(readAhead); \ |
394 OBJ rA = __INST(readAhead); \ |
395 if (rA != nil) { \ |
395 if (rA != nil) { \ |
396 (buf)[__offs] = __intVal(rA); \ |
396 (buf)[__offs] = __intVal(rA); \ |
397 __INST(readAhead) = nil; \ |
397 __INST(readAhead) = nil; \ |
398 (ret) = 1; \ |
398 (ret) = 1; \ |
399 __offs ++; \ |
399 __offs ++; \ |
400 continue; \ |
400 continue; \ |
401 } \ |
401 } \ |
402 CLEAR_ERRNO; \ |
402 CLEAR_ERRNO; \ |
403 { \ |
403 { \ |
404 int res = 0; \ |
404 int res = 0; \ |
405 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res), 1)) \ |
405 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res), 1)) \ |
406 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
406 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
407 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0), 1))) { \ |
407 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0), 1))) { \ |
408 if (res > 0) { \ |
408 if (res > 0) { \ |
409 if (res > ((cnt)-__offs)) \ |
409 if (res > ((cnt)-__offs)) \ |
410 res = (cnt)-__offs; \ |
410 res = (cnt)-__offs; \ |
411 READ((ret), f, (buf)+__offs, res, handleType); \ |
411 READ((ret), f, (buf)+__offs, res, handleType); \ |
412 } else { \ |
412 } else { \ |
413 (ret) = 0; \ |
413 (ret) = 0; \ |
414 break; \ |
414 break; \ |
415 } \ |
415 } \ |
416 } else { \ |
416 } else { \ |
417 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \ |
417 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \ |
418 } \ |
418 } \ |
419 } \ |
419 } \ |
420 if ((ret) <= 0) { \ |
420 if ((ret) <= 0) { \ |
421 if (ret < 0 && __threadErrno == EINTR) \ |
421 if (ret < 0 && __threadErrno == EINTR) \ |
422 continue; \ |
422 continue; \ |
423 break; \ |
423 break; \ |
424 } \ |
424 } \ |
425 __offs += (ret); \ |
425 __offs += (ret); \ |
426 } \ |
426 } \ |
427 (ret) = __offs; \ |
427 (ret) = __offs; \ |
428 } \ |
428 } \ |
429 } |
429 } |
430 |
430 |
431 # define IO_BUFFER_SIZE (8*1024) |
431 # define IO_BUFFER_SIZE (8*1024) |
432 |
432 |
433 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
433 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
434 { \ |
434 { \ |
435 int __ooffs = obj_offs; \ |
435 int __ooffs = obj_offs; \ |
436 int __offs = 0; \ |
436 int __offs = 0; \ |
437 char *buf = (char *)(obj); \ |
437 char *buf = (char *)(obj); \ |
438 \ |
438 \ |
439 (ret) = 0; \ |
439 (ret) = 0; \ |
440 if (isBuffered) { \ |
440 if (isBuffered) { \ |
441 while (__offs < (cnt)) { \ |
441 while (__offs < (cnt)) { \ |
442 CLEAR_ERRNO; \ |
442 CLEAR_ERRNO; \ |
443 (ret) = getc(f); \ |
443 (ret) = getc(f); \ |
444 if ((ret) < 0) { \ |
444 if ((ret) < 0) { \ |
445 if (ferror(f)) { \ |
445 if (ferror(f)) { \ |
446 if (__threadErrno == EINTR) { \ |
446 if (__threadErrno == EINTR) { \ |
447 clearerr(f); \ |
447 clearerr(f); \ |
448 /* refetch */ \ |
448 /* refetch */ \ |
449 buf = (char *)(obj); \ |
449 buf = (char *)(obj); \ |
450 continue; \ |
450 continue; \ |
451 } \ |
451 } \ |
452 } else { \ |
452 } else { \ |
453 (ret) = 0; \ |
453 (ret) = 0; \ |
454 } \ |
454 } \ |
455 break; \ |
455 break; \ |
456 } \ |
456 } \ |
457 (buf)[__ooffs+__offs] = (ret); \ |
457 (buf)[__ooffs+__offs] = (ret); \ |
458 __offs++; \ |
458 __offs++; \ |
459 } \ |
459 } \ |
460 if (__offs > 0) \ |
460 if (__offs > 0) \ |
461 (ret) = __offs; \ |
461 (ret) = __offs; \ |
462 } else { \ |
462 } else { \ |
463 while (__offs < (cnt)) { \ |
463 while (__offs < (cnt)) { \ |
464 char __buf[IO_BUFFER_SIZE]; \ |
464 char __buf[IO_BUFFER_SIZE]; \ |
465 OBJ rA = __INST(readAhead); \ |
465 OBJ rA = __INST(readAhead); \ |
466 if (rA != nil) { \ |
466 if (rA != nil) { \ |
467 (buf)[__ooffs+__offs] = __intVal(rA); \ |
467 (buf)[__ooffs+__offs] = __intVal(rA); \ |
468 __INST(readAhead) = nil; \ |
468 __INST(readAhead) = nil; \ |
469 (ret) = 1; \ |
469 (ret) = 1; \ |
470 } else { \ |
470 } else { \ |
471 int l; \ |
471 int l; \ |
472 CLEAR_ERRNO; \ |
472 CLEAR_ERRNO; \ |
473 l = (cnt)-__offs; \ |
473 l = (cnt)-__offs; \ |
474 if ( l > IO_BUFFER_SIZE) \ |
474 if ( l > IO_BUFFER_SIZE) \ |
475 l = IO_BUFFER_SIZE; \ |
475 l = IO_BUFFER_SIZE; \ |
476 READ((ret),f, __buf, l, handleType); \ |
476 READ((ret),f, __buf, l, handleType); \ |
477 if ((ret) <= 0) { \ |
477 if ((ret) <= 0) { \ |
478 if ((ret) < 0 && __threadErrno == EINTR) { \ |
478 if ((ret) < 0 && __threadErrno == EINTR) { \ |
479 continue; \ |
479 continue; \ |
480 } \ |
480 } \ |
481 break; \ |
481 break; \ |
482 } \ |
482 } \ |
483 } \ |
483 } \ |
484 if ((ret) > 0 ) { \ |
484 if ((ret) > 0 ) { \ |
485 /* refetch */ \ |
485 /* refetch */ \ |
486 buf = (char *)(obj); \ |
486 buf = (char *)(obj); \ |
487 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
487 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
488 __offs += (ret); \ |
488 __offs += (ret); \ |
489 } else { \ |
489 } else { \ |
490 (ret) = 0; \ |
490 (ret) = 0; \ |
491 } \ |
491 } \ |
492 } \ |
492 } \ |
493 if (__offs > 0) \ |
493 if (__offs > 0) \ |
494 (ret) = __offs; \ |
494 (ret) = __offs; \ |
495 } \ |
495 } \ |
496 } |
496 } |
497 |
497 |
498 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
498 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
499 { \ |
499 { \ |
500 int __ooffs = obj_offs; \ |
500 int __ooffs = obj_offs; \ |
501 int __offs = 0; \ |
501 int __offs = 0; \ |
502 char *buf = (char *)(obj); \ |
502 char *buf = (char *)(obj); \ |
503 \ |
503 \ |
504 (ret) = 0; \ |
504 (ret) = 0; \ |
505 if (isBuffered) { \ |
505 if (isBuffered) { \ |
506 while (__offs < (cnt)) { \ |
506 while (__offs < (cnt)) { \ |
507 CLEAR_ERRNO; \ |
507 CLEAR_ERRNO; \ |
508 (ret) = getc(f); \ |
508 (ret) = getc(f); \ |
509 if ((ret) < 0) { \ |
509 if ((ret) < 0) { \ |
510 if (ferror(f)) { \ |
510 if (ferror(f)) { \ |
511 if (__threadErrno == EINTR) { \ |
511 if (__threadErrno == EINTR) { \ |
512 clearerr(f); \ |
512 clearerr(f); \ |
513 /* refetch */ \ |
513 /* refetch */ \ |
514 buf = (char *)(obj);\ |
514 buf = (char *)(obj);\ |
515 continue; \ |
515 continue; \ |
516 } \ |
516 } \ |
517 } else { \ |
517 } else { \ |
518 (ret) = 0; \ |
518 (ret) = 0; \ |
519 } \ |
519 } \ |
520 break; \ |
520 break; \ |
521 } \ |
521 } \ |
522 (buf)[__ooffs+__offs] = (ret); \ |
522 (buf)[__ooffs+__offs] = (ret); \ |
523 __offs++; \ |
523 __offs++; \ |
524 } \ |
524 } \ |
525 if (__offs > 0) \ |
525 if (__offs > 0) \ |
526 (ret) = __offs; \ |
526 (ret) = __offs; \ |
527 } else { \ |
527 } else { \ |
528 while (__offs < (cnt)) { \ |
528 while (__offs < (cnt)) { \ |
529 char __buf[IO_BUFFER_SIZE]; \ |
529 char __buf[IO_BUFFER_SIZE]; \ |
530 OBJ rA = __INST(readAhead); \ |
530 OBJ rA = __INST(readAhead); \ |
531 if (rA != nil) { \ |
531 if (rA != nil) { \ |
532 (buf)[__ooffs+__offs] = __intVal(rA);\ |
532 (buf)[__ooffs+__offs] = __intVal(rA);\ |
533 __INST(readAhead) = nil; \ |
533 __INST(readAhead) = nil; \ |
534 (ret) = 1; \ |
534 (ret) = 1; \ |
535 __offs++; \ |
535 __offs++; \ |
536 continue; \ |
536 continue; \ |
537 } \ |
537 } \ |
538 { \ |
538 { \ |
539 int res = 0; \ |
539 int res = 0; \ |
540 int l = (cnt)-__offs; \ |
540 int l = (cnt)-__offs; \ |
541 CLEAR_ERRNO; \ |
541 CLEAR_ERRNO; \ |
542 if (l > IO_BUFFER_SIZE) \ |
542 if (l > IO_BUFFER_SIZE) \ |
543 l = IO_BUFFER_SIZE; \ |
543 l = IO_BUFFER_SIZE; \ |
544 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)), FIONREAD, &res), 1)) \ |
544 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)), FIONREAD, &res), 1)) \ |
545 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
545 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
546 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0,0,0,&res,0), 1))) { \ |
546 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0,0,0,&res,0), 1))) { \ |
547 if (res > 0) { \ |
547 if (res > 0) { \ |
548 if (res > l) res = l; \ |
548 if (res > l) res = l; \ |
549 READ((ret), f, __buf, res, handleType); \ |
549 READ((ret), f, __buf, res, handleType); \ |
550 } else { \ |
550 } else { \ |
551 (ret) = 0; \ |
551 (ret) = 0; \ |
552 break; \ |
552 break; \ |
553 } \ |
553 } \ |
554 } else { \ |
554 } else { \ |
555 READ((ret), f, __buf, l, handleType); \ |
555 READ((ret), f, __buf, l, handleType); \ |
556 } \ |
556 } \ |
557 if ((ret) <= 0) { \ |
557 if ((ret) <= 0) { \ |
558 if (ret < 0 && __threadErrno == EINTR) \ |
558 if (ret < 0 && __threadErrno == EINTR) \ |
559 continue; \ |
559 continue; \ |
560 break; \ |
560 break; \ |
561 } \ |
561 } \ |
562 } \ |
562 } \ |
563 if ((ret) > 0) { \ |
563 if ((ret) > 0) { \ |
564 buf = (char *)(obj); \ |
564 buf = (char *)(obj); \ |
565 memcpy((buf)+__ooffs+__offs, __buf, (ret)); \ |
565 memcpy((buf)+__ooffs+__offs, __buf, (ret)); \ |
566 __offs += (ret); \ |
566 __offs += (ret); \ |
567 } else { \ |
567 } else { \ |
568 (ret) = 0; \ |
568 (ret) = 0; \ |
569 } \ |
569 } \ |
570 } \ |
570 } \ |
571 if (__offs > 0) \ |
571 if (__offs > 0) \ |
572 (ret) = __offs; \ |
572 (ret) = __offs; \ |
573 } \ |
573 } \ |
574 } |
574 } |
575 |
575 |
576 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
576 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
577 if (isBuffered) { \ |
577 if (isBuffered) { \ |
578 for (;;) { \ |
578 for (;;) { \ |
579 CLEAR_ERRNO; \ |
579 CLEAR_ERRNO; \ |
580 ret = putc(*(buf), f); \ |
580 ret = putc(*(buf), f); \ |
581 if ((ret) >= 0) { \ |
581 if ((ret) >= 0) { \ |
582 (ret) = 1; \ |
582 (ret) = 1; \ |
583 } else if (ferror(f)) { \ |
583 } else if (ferror(f)) { \ |
584 if (__threadErrno == EINTR) { \ |
584 if (__threadErrno == EINTR) { \ |
585 clearerr(f); \ |
585 clearerr(f); \ |
586 continue; \ |
586 continue; \ |
587 } \ |
587 } \ |
588 } else \ |
588 } else \ |
589 (ret) = 0; \ |
589 (ret) = 0; \ |
590 break; \ |
590 break; \ |
591 } \ |
591 } \ |
592 } else { \ |
592 } else { \ |
593 for (;;) { \ |
593 for (;;) { \ |
594 CLEAR_ERRNO; \ |
594 CLEAR_ERRNO; \ |
595 WRITE(ret,f, buf, 1, handleType); \ |
595 WRITE(ret,f, buf, 1, handleType); \ |
596 if ((ret) >= 0 || __threadErrno != EINTR) \ |
596 if ((ret) >= 0 || __threadErrno != EINTR) \ |
597 break; \ |
597 break; \ |
598 } \ |
598 } \ |
599 } |
599 } |
600 |
600 |
601 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
601 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
602 (ret) = 0; \ |
602 (ret) = 0; \ |
603 if (isBuffered) { \ |
603 if (isBuffered) { \ |
604 int __offs = 0; \ |
604 int __offs = 0; \ |
605 while (__offs < (cnt)) { \ |
605 while (__offs < (cnt)) { \ |
606 CLEAR_ERRNO; \ |
606 CLEAR_ERRNO; \ |
607 (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
607 (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
608 if ((ret) <= 0) { \ |
608 if ((ret) <= 0) { \ |
609 if (ferror(f)) { \ |
609 if (ferror(f)) { \ |
610 if (__threadErrno == EINTR) { \ |
610 if (__threadErrno == EINTR) { \ |
611 clearerr(f); \ |
611 clearerr(f); \ |
612 continue; \ |
612 continue; \ |
613 } \ |
613 } \ |
614 break; \ |
614 break; \ |
615 } else { \ |
615 } else { \ |
616 (ret) = 0; \ |
616 (ret) = 0; \ |
617 } \ |
617 } \ |
618 } \ |
618 } \ |
619 __offs += (ret); \ |
619 __offs += (ret); \ |
620 } \ |
620 } \ |
621 if (__offs > 0) \ |
621 if (__offs > 0) \ |
622 (ret) = __offs; \ |
622 (ret) = __offs; \ |
623 } else { \ |
623 } else { \ |
624 int __offs = 0; \ |
624 int __offs = 0; \ |
625 while (__offs < (cnt)) { \ |
625 while (__offs < (cnt)) { \ |
626 CLEAR_ERRNO; \ |
626 CLEAR_ERRNO; \ |
627 WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
627 WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
628 if (ret <= 0) { \ |
628 if (ret <= 0) { \ |
629 if (ret < 0 && __threadErrno == EINTR) { \ |
629 if (ret < 0 && __threadErrno == EINTR) { \ |
630 continue; \ |
630 continue; \ |
631 } \ |
631 } \ |
632 break; \ |
632 break; \ |
633 } \ |
633 } \ |
634 __offs += (ret); \ |
634 __offs += (ret); \ |
635 } \ |
635 } \ |
636 if (__offs > 0) \ |
636 if (__offs > 0) \ |
637 (ret) = __offs; \ |
637 (ret) = __offs; \ |
638 } |
638 } |
639 |
639 |
640 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
640 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
641 { \ |
641 { \ |
642 int __ooffs = obj_offs; \ |
642 int __ooffs = obj_offs; \ |
643 int __offs = 0; \ |
643 int __offs = 0; \ |
644 char *buf = (char *)(obj); \ |
644 char *buf = (char *)(obj); \ |
645 \ |
645 \ |
646 (ret) = 0; \ |
646 (ret) = 0; \ |
647 if (isBuffered) { \ |
647 if (isBuffered) { \ |
648 while (__offs < (cnt)) { \ |
648 while (__offs < (cnt)) { \ |
649 CLEAR_ERRNO; \ |
649 CLEAR_ERRNO; \ |
650 ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
650 ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
651 if ((ret) <= 0) { \ |
651 if ((ret) <= 0) { \ |
652 if (ferror(f)) { \ |
652 if (ferror(f)) { \ |
653 if (__threadErrno == EINTR) { \ |
653 if (__threadErrno == EINTR) { \ |
654 /* refetch */ \ |
654 /* refetch */ \ |
655 buf = (char *)(obj); \ |
655 buf = (char *)(obj); \ |
656 clearerr(f); \ |
656 clearerr(f); \ |
657 continue; \ |
657 continue; \ |
658 } \ |
658 } \ |
659 break; \ |
659 break; \ |
660 } else { \ |
660 } else { \ |
661 (ret) = 0; \ |
661 (ret) = 0; \ |
662 } \ |
662 } \ |
663 } \ |
663 } \ |
664 __offs += (ret); \ |
664 __offs += (ret); \ |
665 } \ |
665 } \ |
666 if (__offs > 0) \ |
666 if (__offs > 0) \ |
667 (ret) = __offs; \ |
667 (ret) = __offs; \ |
668 } else { \ |
668 } else { \ |
669 while (__offs < (cnt)) { \ |
669 while (__offs < (cnt)) { \ |
670 char __buf[IO_BUFFER_SIZE]; \ |
670 char __buf[IO_BUFFER_SIZE]; \ |
671 int l; \ |
671 int l; \ |
672 CLEAR_ERRNO; \ |
672 CLEAR_ERRNO; \ |
673 l = (cnt)-__offs; \ |
673 l = (cnt)-__offs; \ |
674 if ( l > IO_BUFFER_SIZE) \ |
674 if ( l > IO_BUFFER_SIZE) \ |
675 l = IO_BUFFER_SIZE; \ |
675 l = IO_BUFFER_SIZE; \ |
676 /* refetch */ \ |
676 /* refetch */ \ |
677 buf = (char *)(obj); \ |
677 buf = (char *)(obj); \ |
678 memcpy(__buf,(buf)+__ooffs+__offs,l); \ |
678 memcpy(__buf,(buf)+__ooffs+__offs,l); \ |
679 WRITE(ret,f, __buf, l, handleType); \ |
679 WRITE(ret,f, __buf, l, handleType); \ |
680 if (ret <= 0) { \ |
680 if (ret <= 0) { \ |
681 if (ret < 0 && __threadErrno == EINTR) { \ |
681 if (ret < 0 && __threadErrno == EINTR) { \ |
682 continue; \ |
682 continue; \ |
683 } \ |
683 } \ |
684 break; \ |
684 break; \ |
685 } \ |
685 } \ |
686 __offs += (ret); \ |
686 __offs += (ret); \ |
687 } \ |
687 } \ |
688 if (__offs > 0) \ |
688 if (__offs > 0) \ |
689 (ret) = __offs; \ |
689 (ret) = __offs; \ |
690 } \ |
690 } \ |
691 } |
691 } |
692 |
692 |
693 #else /* ! WIN32 */ |
693 #else /* ! WIN32 */ |
694 /* ======================== UNIX / LINUX ====================================================== */ |
694 /* ======================== UNIX / LINUX ====================================================== */ |
695 typedef int SOCKET; |
695 typedef int SOCKET; |
696 |
696 |
697 # define __READING__(f) \ |
697 # define __READING__(f) \ |
698 if ((__INST(didWrite) != false) \ |
698 if ((__INST(didWrite) != false) \ |
699 && (__INST(mode) == @symbol(readwrite))) { \ |
699 && (__INST(mode) == @symbol(readwrite))) { \ |
700 __INST(didWrite) = false; \ |
700 __INST(didWrite) = false; \ |
701 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
701 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
702 } |
702 } |
703 |
703 |
704 # define __WRITING__(f) \ |
704 # define __WRITING__(f) \ |
705 if ((__INST(didWrite) != true) \ |
705 if ((__INST(didWrite) != true) \ |
706 && (__INST(mode) == @symbol(readwrite))) { \ |
706 && (__INST(mode) == @symbol(readwrite))) { \ |
707 __INST(didWrite) = true; \ |
707 __INST(didWrite) = true; \ |
708 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
708 OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */ \ |
709 } |
709 } |
710 |
710 |
711 |
711 |
712 # ifdef NO_STDIO |
712 # ifdef NO_STDIO |
713 # define __UNGETC__(c, f, isBuffered) \ |
713 # define __UNGETC__(c, f, isBuffered) \ |
714 __INST(readAhead) = __mkSmallInteger((c)); |
714 __INST(readAhead) = __mkSmallInteger((c)); |
715 # else /* use STDIO */ |
715 # else /* use STDIO */ |
716 # define __UNGETC__(c, f, isBuffered) \ |
716 # define __UNGETC__(c, f, isBuffered) \ |
717 if (isBuffered) { \ |
717 if (isBuffered) { \ |
718 ungetc((c), (f)); \ |
718 ungetc((c), (f)); \ |
719 } else { \ |
719 } else { \ |
720 __INST(readAhead) = __mkSmallInteger((c)); \ |
720 __INST(readAhead) = __mkSmallInteger((c)); \ |
721 } |
721 } |
722 # endif /* use STDIO */ |
722 # endif /* use STDIO */ |
723 |
723 |
724 # ifdef NO_STDIO |
724 # ifdef NO_STDIO |
725 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
725 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
726 { \ |
726 { \ |
727 OBJ rA = __INST(readAhead); \ |
727 OBJ rA = __INST(readAhead); \ |
728 if (rA != nil) { \ |
728 if (rA != nil) { \ |
729 *(buf) = __intVal(rA); \ |
729 *(buf) = __intVal(rA); \ |
730 DEBUGBUFFER(buf); \ |
730 DEBUGBUFFER(buf); \ |
731 __INST(readAhead) = nil; \ |
731 __INST(readAhead) = nil; \ |
732 (ret) = 1; \ |
732 (ret) = 1; \ |
733 } else { \ |
733 } else { \ |
734 for (;;) { \ |
734 for (;;) { \ |
735 CLEAR_ERRNO; \ |
735 CLEAR_ERRNO; \ |
736 (ret) = READ(f, buf, 1, handleType); \ |
736 (ret) = READ(f, buf, 1, handleType); \ |
737 DEBUGBUFFER(buf); \ |
737 DEBUGBUFFER(buf); \ |
738 if ((ret) >= 0) break; \ |
738 if ((ret) >= 0) break; \ |
739 if (errno != EINTR) { \ |
739 if (errno != EINTR) { \ |
740 break; \ |
740 break; \ |
741 } \ |
741 } \ |
742 __HANDLE_INTERRUPTS__; \ |
742 __HANDLE_INTERRUPTS__; \ |
743 } \ |
743 } \ |
744 } \ |
744 } \ |
745 } |
745 } |
746 # else /* use STDIO */ |
746 # else /* use STDIO */ |
747 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
747 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \ |
748 if (isBuffered) { \ |
748 if (isBuffered) { \ |
749 for (;;) { \ |
749 for (;;) { \ |
750 CLEAR_ERRNO; \ |
750 CLEAR_ERRNO; \ |
751 (ret) = getc(f); \ |
751 (ret) = getc(f); \ |
752 if ((ret) >= 0) { \ |
752 if ((ret) >= 0) { \ |
753 DEBUGBUFFER(buf); \ |
753 DEBUGBUFFER(buf); \ |
754 *(buf) = (ret); \ |
754 *(buf) = (ret); \ |
755 (ret) = 1; \ |
755 (ret) = 1; \ |
756 } else if (ferror(f)) { \ |
756 } else if (ferror(f)) { \ |
757 if (errno == EINTR) { \ |
757 if (errno == EINTR) { \ |
758 __HANDLE_INTERRUPTS__; \ |
758 __HANDLE_INTERRUPTS__; \ |
759 clearerr(f); \ |
759 clearerr(f); \ |
760 continue; \ |
760 continue; \ |
761 } \ |
761 } \ |
762 } else \ |
762 } else \ |
763 (ret) = 0; \ |
763 (ret) = 0; \ |
764 break; \ |
764 break; \ |
765 } \ |
765 } \ |
766 } else { \ |
766 } else { \ |
767 OBJ rA = __INST(readAhead); \ |
767 OBJ rA = __INST(readAhead); \ |
768 if (rA != nil) { \ |
768 if (rA != nil) { \ |
769 *(buf) = __intVal(rA); \ |
769 *(buf) = __intVal(rA); \ |
770 DEBUGBUFFER(buf); \ |
770 DEBUGBUFFER(buf); \ |
771 __INST(readAhead) = nil; \ |
771 __INST(readAhead) = nil; \ |
772 (ret) = 1; \ |
772 (ret) = 1; \ |
773 } else { \ |
773 } else { \ |
774 for (;;) { \ |
774 for (;;) { \ |
775 CLEAR_ERRNO; \ |
775 CLEAR_ERRNO; \ |
776 (ret) = read(fileno(f), buf, 1); \ |
776 (ret) = read(fileno(f), buf, 1); \ |
777 DEBUGBUFFER(buf); \ |
777 DEBUGBUFFER(buf); \ |
778 if ((ret) >= 0) break; \ |
778 if ((ret) >= 0) break; \ |
779 if (errno != EINTR) { \ |
779 if (errno != EINTR) { \ |
780 break; \ |
780 break; \ |
781 } \ |
781 } \ |
782 __HANDLE_INTERRUPTS__; \ |
782 __HANDLE_INTERRUPTS__; \ |
783 } \ |
783 } \ |
784 } \ |
784 } \ |
785 } |
785 } |
786 # endif /* use STDIO */ |
786 # endif /* use STDIO */ |
787 |
787 |
788 /* |
788 /* |
789 * read_bytes into a c-buffer |
789 * read_bytes into a c-buffer |
790 * (which may NOT move) |
790 * (which may NOT move) |
791 */ |
791 */ |
792 # ifdef NO_STDIO |
792 # ifdef NO_STDIO |
793 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
793 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
794 { \ |
794 { \ |
795 int __offs = 0, __cnt; \ |
795 int __offs = 0, __cnt; \ |
796 \ |
796 \ |
797 while (__offs < (cnt)) { \ |
797 while (__offs < (cnt)) { \ |
798 OBJ rA = __INST(readAhead); \ |
798 OBJ rA = __INST(readAhead); \ |
799 if (rA != nil) { \ |
799 if (rA != nil) { \ |
800 (buf)[__offs] = __intVal(rA); \ |
800 (buf)[__offs] = __intVal(rA); \ |
801 DEBUGBUFFER(buf); \ |
801 DEBUGBUFFER(buf); \ |
802 __INST(readAhead) = nil; \ |
802 __INST(readAhead) = nil; \ |
803 __offs++; \ |
803 __offs++; \ |
804 } else { \ |
804 } else { \ |
805 CLEAR_ERRNO; \ |
805 CLEAR_ERRNO; \ |
806 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
806 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
807 DEBUGBUFFER(buf); \ |
807 DEBUGBUFFER(buf); \ |
808 if (__cnt <= 0) { \ |
808 if (__cnt <= 0) { \ |
809 if (__cnt < 0 && errno == EINTR) { \ |
809 if (__cnt < 0 && errno == EINTR) { \ |
810 __HANDLE_INTERRUPTS__; \ |
810 __HANDLE_INTERRUPTS__; \ |
811 continue; \ |
811 continue; \ |
812 } \ |
812 } \ |
813 break; \ |
813 break; \ |
814 } \ |
814 } \ |
815 __offs += __cnt; \ |
815 __offs += __cnt; \ |
816 } \ |
816 } \ |
817 } \ |
817 } \ |
818 if (__offs > 0) \ |
818 if (__offs > 0) \ |
819 (ret) = __offs; \ |
819 (ret) = __offs; \ |
820 } |
820 } |
821 # else /* use STDIO */ |
821 # else /* use STDIO */ |
822 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
822 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
823 (ret) = 0; \ |
823 (ret) = 0; \ |
824 if (isBuffered) { \ |
824 if (isBuffered) { \ |
825 int __offs = 0; \ |
825 int __offs = 0; \ |
826 while (__offs < (cnt)) { \ |
826 while (__offs < (cnt)) { \ |
827 CLEAR_ERRNO; \ |
827 CLEAR_ERRNO; \ |
828 (ret) = getc(f); \ |
828 (ret) = getc(f); \ |
829 if ((ret) < 0) { \ |
829 if ((ret) < 0) { \ |
830 if (ferror(f)) { \ |
830 if (ferror(f)) { \ |
831 if (errno == EINTR) { \ |
831 if (errno == EINTR) { \ |
832 __HANDLE_INTERRUPTS__; \ |
832 __HANDLE_INTERRUPTS__; \ |
833 clearerr(f); \ |
833 clearerr(f); \ |
834 continue; \ |
834 continue; \ |
835 } \ |
835 } \ |
836 } else { \ |
836 } else { \ |
837 (ret) = 0; \ |
837 (ret) = 0; \ |
838 } \ |
838 } \ |
839 break; \ |
839 break; \ |
840 } \ |
840 } \ |
841 DEBUGBUFFER(buf); \ |
841 DEBUGBUFFER(buf); \ |
842 (buf)[__offs++] = (ret); \ |
842 (buf)[__offs++] = (ret); \ |
843 } \ |
843 } \ |
844 if (__offs > 0) \ |
844 if (__offs > 0) \ |
845 (ret) = __offs; \ |
845 (ret) = __offs; \ |
846 } else { \ |
846 } else { \ |
847 int __offs = 0, __cnt; \ |
847 int __offs = 0, __cnt; \ |
848 int fd = fileno(f); \ |
848 int fd = fileno(f); \ |
849 \ |
849 \ |
850 while (__offs < (cnt)) { \ |
850 while (__offs < (cnt)) { \ |
851 OBJ rA = __INST(readAhead); \ |
851 OBJ rA = __INST(readAhead); \ |
852 if (rA != nil) { \ |
852 if (rA != nil) { \ |
853 DEBUGBUFFER(buf); \ |
853 DEBUGBUFFER(buf); \ |
854 (buf)[__offs] = __intVal(rA); \ |
854 (buf)[__offs] = __intVal(rA); \ |
855 __INST(readAhead) = nil; \ |
855 __INST(readAhead) = nil; \ |
856 __offs++; \ |
856 __offs++; \ |
857 } else { \ |
857 } else { \ |
858 CLEAR_ERRNO; \ |
858 CLEAR_ERRNO; \ |
859 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
859 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
860 DEBUGBUFFER(buf); \ |
860 DEBUGBUFFER(buf); \ |
861 if (__cnt <= 0) { \ |
861 if (__cnt <= 0) { \ |
862 if (__cnt < 0 && errno == EINTR) { \ |
862 if (__cnt < 0 && errno == EINTR) { \ |
863 __HANDLE_INTERRUPTS__; \ |
863 __HANDLE_INTERRUPTS__; \ |
864 continue; \ |
864 continue; \ |
865 } \ |
865 } \ |
866 break; \ |
866 break; \ |
867 } \ |
867 } \ |
868 __offs += __cnt; \ |
868 __offs += __cnt; \ |
869 } \ |
869 } \ |
870 } \ |
870 } \ |
871 if (__offs > 0) \ |
871 if (__offs > 0) \ |
872 (ret) = __offs; \ |
872 (ret) = __offs; \ |
873 } |
873 } |
874 |
874 |
875 |
875 |
876 /* |
876 /* |
877 * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc... |
877 * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc... |
878 */ |
878 */ |
879 |
879 |
880 # if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY)) |
880 # if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY)) |
881 # define SETFLAGS(fd, flags) \ |
881 # define SETFLAGS(fd, flags) \ |
882 fcntl(fd, F_SETFL, flags) |
882 fcntl(fd, F_SETFL, flags) |
883 |
883 |
884 # if defined(O_NONBLOCK) |
884 # if defined(O_NONBLOCK) |
885 # define __STX_NONBLOCK_FLAG O_NONBLOCK |
885 # define __STX_NONBLOCK_FLAG O_NONBLOCK |
886 # else |
886 # else |
887 # if defined(O_NDELAY) |
887 # if defined(O_NDELAY) |
890 # define __STX_NONBLOCK_FLAG FNDELAY |
890 # define __STX_NONBLOCK_FLAG FNDELAY |
891 # endif |
891 # endif |
892 # endif |
892 # endif |
893 |
893 |
894 # define SETNONBLOCKING(fd, oldFlags) \ |
894 # define SETNONBLOCKING(fd, oldFlags) \ |
895 { \ |
895 { \ |
896 int flags = fcntl(fd, F_GETFL, 0); \ |
896 int flags = fcntl(fd, F_GETFL, 0); \ |
897 if (flags >= 0) { \ |
897 if (flags >= 0) { \ |
898 fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \ |
898 fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \ |
899 } \ |
899 } \ |
900 oldFlags = flags; \ |
900 oldFlags = flags; \ |
901 } |
901 } |
902 # else |
902 # else |
903 # define SETFLAGS(fd, flags) /* nothing */ |
903 # define SETFLAGS(fd, flags) /* nothing */ |
904 # define SETNONBLOCKING(fd, oldFlags) /* nothing */ |
904 # define SETNONBLOCKING(fd, oldFlags) /* nothing */ |
905 # endif |
905 # endif |
906 |
906 |
907 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
907 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
908 { \ |
908 { \ |
909 int __offs = 0, __cnt; \ |
909 int __offs = 0, __cnt; \ |
910 int oldFlags; \ |
910 int oldFlags; \ |
911 \ |
911 \ |
912 (ret) = 0; \ |
912 (ret) = 0; \ |
913 SETNONBLOCKING(fileno(f), oldFlags); \ |
913 SETNONBLOCKING(fileno(f), oldFlags); \ |
914 if (isBuffered) { \ |
914 if (isBuffered) { \ |
915 while (__offs < (cnt)) { \ |
915 while (__offs < (cnt)) { \ |
916 CLEAR_ERRNO; \ |
916 CLEAR_ERRNO; \ |
917 (ret) = getc(f); \ |
917 (ret) = getc(f); \ |
918 if ((ret) < 0) { \ |
918 if ((ret) < 0) { \ |
919 if (ferror(f)) { \ |
919 if (ferror(f)) { \ |
920 if (errno == EINTR) { \ |
920 if (errno == EINTR) { \ |
921 (ret) = 0; \ |
921 (ret) = 0; \ |
922 clearerr(f); \ |
922 clearerr(f); \ |
923 break; \ |
923 break; \ |
924 } \ |
924 } \ |
925 } else { \ |
925 } else { \ |
926 (ret) = 0; \ |
926 (ret) = 0; \ |
927 } \ |
927 } \ |
928 break; \ |
928 break; \ |
929 } \ |
929 } \ |
930 (buf)[__offs++] = (ret); \ |
930 (buf)[__offs++] = (ret); \ |
931 DEBUGBUFFER(buf); \ |
931 DEBUGBUFFER(buf); \ |
932 } \ |
932 } \ |
933 if (__offs > 0) \ |
933 if (__offs > 0) \ |
934 (ret) = __offs; \ |
934 (ret) = __offs; \ |
935 } else { \ |
935 } else { \ |
936 int fd = fileno(f); \ |
936 int fd = fileno(f); \ |
937 \ |
937 \ |
938 while (__offs < (cnt)) { \ |
938 while (__offs < (cnt)) { \ |
939 OBJ rA = __INST(readAhead); \ |
939 OBJ rA = __INST(readAhead); \ |
940 if (rA != nil) { \ |
940 if (rA != nil) { \ |
941 (buf)[__offs] = __intVal(rA); \ |
941 (buf)[__offs] = __intVal(rA); \ |
942 DEBUGBUFFER(buf); \ |
942 DEBUGBUFFER(buf); \ |
943 __INST(readAhead) = nil; \ |
943 __INST(readAhead) = nil; \ |
944 __offs++; \ |
944 __offs++; \ |
945 continue; \ |
945 continue; \ |
946 } \ |
946 } \ |
947 CLEAR_ERRNO; \ |
947 CLEAR_ERRNO; \ |
948 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
948 __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \ |
949 DEBUGBUFFER(buf); \ |
949 DEBUGBUFFER(buf); \ |
950 if (__cnt > 0) { \ |
950 if (__cnt > 0) { \ |
951 __offs += __cnt; \ |
951 __offs += __cnt; \ |
952 } \ |
952 } \ |
953 break; \ |
953 break; \ |
954 } \ |
954 } \ |
955 if (__offs > 0) \ |
955 if (__offs > 0) \ |
956 (ret) = __offs; \ |
956 (ret) = __offs; \ |
957 } \ |
957 } \ |
958 SETFLAGS(fileno(f), oldFlags); \ |
958 SETFLAGS(fileno(f), oldFlags); \ |
959 } |
959 } |
960 |
960 |
961 # endif /* use STDIO */ |
961 # endif /* use STDIO */ |
969 { \ |
969 { \ |
970 int __ooffs = obj_offs; \ |
970 int __ooffs = obj_offs; \ |
971 int __offs = 0; \ |
971 int __offs = 0; \ |
972 int __cnt; \ |
972 int __cnt; \ |
973 char *buf = (char *)(obj); \ |
973 char *buf = (char *)(obj); \ |
974 \ |
974 \ |
975 (ret) = 0; \ |
975 (ret) = 0; \ |
976 { \ |
976 { \ |
977 while (__offs < (cnt)) { \ |
977 while (__offs < (cnt)) { \ |
978 OBJ rA = __INST(readAhead); \ |
978 OBJ rA = __INST(readAhead); \ |
979 if (rA != nil) { \ |
979 if (rA != nil) { \ |
980 (buf)[__ooffs+__offs] = __intVal(rA); \ |
980 (buf)[__ooffs+__offs] = __intVal(rA); \ |
981 DEBUGBUFFER(buf); \ |
981 DEBUGBUFFER(buf); \ |
982 __INST(readAhead) = nil; \ |
982 __INST(readAhead) = nil; \ |
983 __offs++; \ |
983 __offs++; \ |
984 } else { \ |
984 } else { \ |
985 CLEAR_ERRNO; \ |
985 CLEAR_ERRNO; \ |
986 __cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \ |
986 __cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \ |
987 DEBUGBUFFER(buf); \ |
987 DEBUGBUFFER(buf); \ |
988 if (__cnt <= 0) { \ |
988 if (__cnt <= 0) { \ |
989 if (__cnt < 0 && errno == EINTR) { \ |
989 if (__cnt < 0 && errno == EINTR) { \ |
990 __HANDLE_INTERRUPTS__; \ |
990 __HANDLE_INTERRUPTS__; \ |
991 /* refetch */ \ |
991 /* refetch */ \ |
992 buf = (char *)(obj); \ |
992 buf = (char *)(obj); \ |
993 continue; \ |
993 continue; \ |
994 } \ |
994 } \ |
995 break; \ |
995 break; \ |
996 } \ |
996 } \ |
997 __offs += __cnt; \ |
997 __offs += __cnt; \ |
998 } \ |
998 } \ |
999 } \ |
999 } \ |
1000 if (__offs > 0) \ |
1000 if (__offs > 0) \ |
1001 (ret) = __offs; \ |
1001 (ret) = __offs; \ |
1002 } \ |
1002 } \ |
1003 } |
1003 } |
1004 |
1004 |
1005 # else /* use STDIO */ |
1005 # else /* use STDIO */ |
1006 |
1006 |
1008 { \ |
1008 { \ |
1009 int __ooffs = obj_offs; \ |
1009 int __ooffs = obj_offs; \ |
1010 int __offs = 0; \ |
1010 int __offs = 0; \ |
1011 int __cnt; \ |
1011 int __cnt; \ |
1012 char *buf = (char *)(obj); \ |
1012 char *buf = (char *)(obj); \ |
1013 \ |
1013 \ |
1014 (ret) = 0; \ |
1014 (ret) = 0; \ |
1015 if (isBuffered) { \ |
1015 if (isBuffered) { \ |
1016 while (__offs < (cnt)) { \ |
1016 while (__offs < (cnt)) { \ |
1017 CLEAR_ERRNO; \ |
1017 CLEAR_ERRNO; \ |
1018 (ret) = getc(f); \ |
1018 (ret) = getc(f); \ |
1019 if ((ret) < 0) { \ |
1019 if ((ret) < 0) { \ |
1020 if (ferror(f)) { \ |
1020 if (ferror(f)) { \ |
1021 if (errno == EINTR) { \ |
1021 if (errno == EINTR) { \ |
1022 __HANDLE_INTERRUPTS__; \ |
1022 __HANDLE_INTERRUPTS__; \ |
1023 clearerr(f); \ |
1023 clearerr(f); \ |
1024 /* refetch */ \ |
1024 /* refetch */ \ |
1025 buf = (char *)(obj); \ |
1025 buf = (char *)(obj); \ |
1026 DEBUGBUFFER(buf); \ |
1026 DEBUGBUFFER(buf); \ |
1027 continue; \ |
1027 continue; \ |
1028 } \ |
1028 } \ |
1029 } else { \ |
1029 } else { \ |
1030 (ret) = 0; \ |
1030 (ret) = 0; \ |
1031 } \ |
1031 } \ |
1032 break; \ |
1032 break; \ |
1033 } \ |
1033 } \ |
1034 (buf)[__ooffs+__offs] = (ret); \ |
1034 (buf)[__ooffs+__offs] = (ret); \ |
1035 DEBUGBUFFER(buf); \ |
1035 DEBUGBUFFER(buf); \ |
1036 __offs++; \ |
1036 __offs++; \ |
1037 } \ |
1037 } \ |
1038 if (__offs > 0) \ |
1038 if (__offs > 0) \ |
1039 (ret) = __offs; \ |
1039 (ret) = __offs; \ |
1040 } else { \ |
1040 } else { \ |
1041 int fd = fileno(f); \ |
1041 int fd = fileno(f); \ |
1042 \ |
1042 \ |
1043 while (__offs < (cnt)) { \ |
1043 while (__offs < (cnt)) { \ |
1044 OBJ rA = __INST(readAhead); \ |
1044 OBJ rA = __INST(readAhead); \ |
1045 if (rA != nil) { \ |
1045 if (rA != nil) { \ |
1046 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1046 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1047 DEBUGBUFFER(buf); \ |
1047 DEBUGBUFFER(buf); \ |
1048 __INST(readAhead) = nil; \ |
1048 __INST(readAhead) = nil; \ |
1049 __offs++; \ |
1049 __offs++; \ |
1050 } else { \ |
1050 } else { \ |
1051 CLEAR_ERRNO; \ |
1051 CLEAR_ERRNO; \ |
1052 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1052 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1053 DEBUGBUFFER(buf); \ |
1053 DEBUGBUFFER(buf); \ |
1054 if (__cnt <= 0) { \ |
1054 if (__cnt <= 0) { \ |
1055 if (__cnt < 0 && errno == EINTR) { \ |
1055 if (__cnt < 0 && errno == EINTR) { \ |
1056 __HANDLE_INTERRUPTS__; \ |
1056 __HANDLE_INTERRUPTS__; \ |
1057 /* refetch */ \ |
1057 /* refetch */ \ |
1058 buf = (char *)(obj); \ |
1058 buf = (char *)(obj); \ |
1059 continue; \ |
1059 continue; \ |
1060 } \ |
1060 } \ |
1061 break; \ |
1061 break; \ |
1062 } \ |
1062 } \ |
1063 __offs += __cnt; \ |
1063 __offs += __cnt; \ |
1064 } \ |
1064 } \ |
1065 } \ |
1065 } \ |
1066 if (__offs > 0) \ |
1066 if (__offs > 0) \ |
1067 (ret) = __offs; \ |
1067 (ret) = __offs; \ |
1068 } \ |
1068 } \ |
1069 } |
1069 } |
1070 |
1070 |
1071 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1071 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1072 { \ |
1072 { \ |
1073 int __ooffs = obj_offs; \ |
1073 int __ooffs = obj_offs; \ |
1074 int __offs = 0; \ |
1074 int __offs = 0; \ |
1075 int __cnt; \ |
1075 int __cnt; \ |
1076 char *buf = (char *)(obj); \ |
1076 char *buf = (char *)(obj); \ |
1077 int oldFlags; \ |
1077 int oldFlags; \ |
1078 \ |
1078 \ |
1079 (ret) = 0; \ |
1079 (ret) = 0; \ |
1080 SETNONBLOCKING(fileno(f), oldFlags); \ |
1080 SETNONBLOCKING(fileno(f), oldFlags); \ |
1081 \ |
1081 \ |
1082 if (isBuffered) { \ |
1082 if (isBuffered) { \ |
1083 while (__offs < (cnt)) { \ |
1083 while (__offs < (cnt)) { \ |
1084 CLEAR_ERRNO; \ |
1084 CLEAR_ERRNO; \ |
1085 (ret) = getc(f); \ |
1085 (ret) = getc(f); \ |
1086 if ((ret) < 0) { \ |
1086 if ((ret) < 0) { \ |
1087 if (ferror(f)) { \ |
1087 if (ferror(f)) { \ |
1088 if (errno == EINTR) { \ |
1088 if (errno == EINTR) { \ |
1089 clearerr(f); \ |
1089 clearerr(f); \ |
1090 /* refetch */ \ |
1090 /* refetch */ \ |
1091 buf = (char *)(obj); \ |
1091 buf = (char *)(obj); \ |
1092 (ret) = 0; \ |
1092 (ret) = 0; \ |
1093 break; \ |
1093 break; \ |
1094 } \ |
1094 } \ |
1095 } else { \ |
1095 } else { \ |
1096 (ret) = 0; \ |
1096 (ret) = 0; \ |
1097 } \ |
1097 } \ |
1098 break; \ |
1098 break; \ |
1099 } \ |
1099 } \ |
1100 (buf)[__ooffs+__offs] = (ret); \ |
1100 (buf)[__ooffs+__offs] = (ret); \ |
1101 DEBUGBUFFER(buf); \ |
1101 DEBUGBUFFER(buf); \ |
1102 __offs++; \ |
1102 __offs++; \ |
1103 } \ |
1103 } \ |
1104 if (__offs > 0) \ |
1104 if (__offs > 0) \ |
1105 (ret) = __offs; \ |
1105 (ret) = __offs; \ |
1106 } else { \ |
1106 } else { \ |
1107 int fd = fileno(f); \ |
1107 int fd = fileno(f); \ |
1108 \ |
1108 \ |
1109 while (__offs < (cnt)) { \ |
1109 while (__offs < (cnt)) { \ |
1110 OBJ rA = __INST(readAhead); \ |
1110 OBJ rA = __INST(readAhead); \ |
1111 if (rA != nil) { \ |
1111 if (rA != nil) { \ |
1112 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1112 (buf)[__ooffs+__offs] = __intVal(rA); \ |
1113 DEBUGBUFFER(buf); \ |
1113 DEBUGBUFFER(buf); \ |
1114 __INST(readAhead) = nil; \ |
1114 __INST(readAhead) = nil; \ |
1115 __offs++; \ |
1115 __offs++; \ |
1116 continue; \ |
1116 continue; \ |
1117 } \ |
1117 } \ |
1118 CLEAR_ERRNO; \ |
1118 CLEAR_ERRNO; \ |
1119 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1119 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1120 DEBUGBUFFER(buf); \ |
1120 DEBUGBUFFER(buf); \ |
1121 if (__cnt > 0) { \ |
1121 if (__cnt > 0) { \ |
1122 __offs += __cnt; \ |
1122 __offs += __cnt; \ |
1123 } \ |
1123 } \ |
1124 break; \ |
1124 break; \ |
1125 } \ |
1125 } \ |
1126 if (__offs > 0) \ |
1126 if (__offs > 0) \ |
1127 (ret) = __offs; \ |
1127 (ret) = __offs; \ |
1128 } \ |
1128 } \ |
1129 SETFLAGS(fileno(f), oldFlags); \ |
1129 SETFLAGS(fileno(f), oldFlags); \ |
1130 } |
1130 } |
1131 |
1131 |
1132 |
1132 |
1133 # endif /* use STDIO */ |
1133 # endif /* use STDIO */ |
1134 |
1134 |
1135 # ifdef NO_STDIO |
1135 # ifdef NO_STDIO |
1136 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1136 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1137 for (;;) { \ |
1137 for (;;) { \ |
1138 CLEAR_ERRNO; \ |
1138 CLEAR_ERRNO; \ |
1139 (ret) = WRITE(f, buf, 1, handleType); \ |
1139 (ret) = WRITE(f, buf, 1, handleType); \ |
1140 if ((ret) >= 0) break; \ |
1140 if ((ret) >= 0) break; \ |
1141 if (errno != EINTR) { \ |
1141 if (errno != EINTR) { \ |
1142 break; \ |
1142 break; \ |
1143 } \ |
1143 } \ |
1144 __HANDLE_INTERRUPTS__; \ |
1144 __HANDLE_INTERRUPTS__; \ |
1145 } |
1145 } |
1146 # else /* use STDIO */ |
1146 # else /* use STDIO */ |
1147 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1147 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType) \ |
1148 if (isBuffered) { \ |
1148 if (isBuffered) { \ |
1149 for (;;) { \ |
1149 for (;;) { \ |
1150 CLEAR_ERRNO; \ |
1150 CLEAR_ERRNO; \ |
1151 ret = putc(*(buf), f); \ |
1151 ret = putc(*(buf), f); \ |
1152 if ((ret) >= 0) { \ |
1152 if ((ret) >= 0) { \ |
1153 (ret) = 1; \ |
1153 (ret) = 1; \ |
1154 } else if (ferror(f)) { \ |
1154 } else if (ferror(f)) { \ |
1155 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \ |
1155 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \ |
1156 if (errno == EINTR || errno == 0) { \ |
1156 if (errno == EINTR || errno == 0) { \ |
1157 __HANDLE_INTERRUPTS__; \ |
1157 __HANDLE_INTERRUPTS__; \ |
1158 clearerr(f); \ |
1158 clearerr(f); \ |
1159 continue; \ |
1159 continue; \ |
1160 } \ |
1160 } \ |
1161 } else \ |
1161 } else \ |
1162 (ret) = 0; \ |
1162 (ret) = 0; \ |
1163 break; \ |
1163 break; \ |
1164 } \ |
1164 } \ |
1165 } else { \ |
1165 } else { \ |
1166 for (;;) { \ |
1166 for (;;) { \ |
1167 CLEAR_ERRNO; \ |
1167 CLEAR_ERRNO; \ |
1168 (ret) = write(fileno(f), buf, 1); \ |
1168 (ret) = write(fileno(f), buf, 1); \ |
1169 if ((ret) >= 0) break; \ |
1169 if ((ret) >= 0) break; \ |
1170 if (errno != EINTR) { \ |
1170 if (errno != EINTR) { \ |
1171 break; \ |
1171 break; \ |
1172 } \ |
1172 } \ |
1173 __HANDLE_INTERRUPTS__; \ |
1173 __HANDLE_INTERRUPTS__; \ |
1174 } \ |
1174 } \ |
1175 } |
1175 } |
1176 # endif /* use STDIO */ |
1176 # endif /* use STDIO */ |
1177 |
1177 |
1178 /* |
1178 /* |
1179 * write_bytes from a c-buffer |
1179 * write_bytes from a c-buffer |
1181 */ |
1181 */ |
1182 # ifdef NO_STDIO |
1182 # ifdef NO_STDIO |
1183 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
1183 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
1184 (ret) = 0; \ |
1184 (ret) = 0; \ |
1185 { \ |
1185 { \ |
1186 int __offs = 0; \ |
1186 int __offs = 0; \ |
1187 while (__offs < (cnt)) { \ |
1187 while (__offs < (cnt)) { \ |
1188 CLEAR_ERRNO; \ |
1188 CLEAR_ERRNO; \ |
1189 ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
1189 ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \ |
1190 if (ret <= 0) { \ |
1190 if (ret <= 0) { \ |
1191 if (ret < 0 && errno == EINTR) { \ |
1191 if (ret < 0 && errno == EINTR) { \ |
1192 __HANDLE_INTERRUPTS__; \ |
1192 __HANDLE_INTERRUPTS__; \ |
1193 continue; \ |
1193 continue; \ |
1194 } \ |
1194 } \ |
1195 break; \ |
1195 break; \ |
1196 } \ |
1196 } \ |
1197 __offs += (ret); \ |
1197 __offs += (ret); \ |
1198 } \ |
1198 } \ |
1199 if (__offs > 0) \ |
1199 if (__offs > 0) \ |
1200 (ret) = __offs; \ |
1200 (ret) = __offs; \ |
1201 } |
1201 } |
1202 # else /* use STDIO */ |
1202 # else /* use STDIO */ |
1203 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
1203 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType) \ |
1204 (ret) = 0; \ |
1204 (ret) = 0; \ |
1205 if (isBuffered) { \ |
1205 if (isBuffered) { \ |
1206 int __offs = 0; \ |
1206 int __offs = 0; \ |
1207 while (__offs < (cnt)) { \ |
1207 while (__offs < (cnt)) { \ |
1208 CLEAR_ERRNO; \ |
1208 CLEAR_ERRNO; \ |
1209 (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
1209 (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\ |
1210 if ((ret) <= 0) { \ |
1210 if ((ret) <= 0) { \ |
1211 if (ferror(f)) { \ |
1211 if (ferror(f)) { \ |
1212 if (errno == EINTR) { \ |
1212 if (errno == EINTR) { \ |
1213 __HANDLE_INTERRUPTS__; \ |
1213 __HANDLE_INTERRUPTS__; \ |
1214 clearerr(f); \ |
1214 clearerr(f); \ |
1215 continue; \ |
1215 continue; \ |
1216 } \ |
1216 } \ |
1217 } else { \ |
1217 } else { \ |
1218 (ret) = 0; \ |
1218 (ret) = 0; \ |
1219 } \ |
1219 } \ |
1220 break; \ |
1220 break; \ |
1221 } \ |
1221 } \ |
1222 __offs += (ret); \ |
1222 __offs += (ret); \ |
1223 } \ |
1223 } \ |
1224 if (__offs > 0) \ |
1224 if (__offs > 0) \ |
1225 (ret) = __offs; \ |
1225 (ret) = __offs; \ |
1226 } else { \ |
1226 } else { \ |
1227 int __offs = 0; \ |
1227 int __offs = 0; \ |
1228 while (__offs < (cnt)) { \ |
1228 while (__offs < (cnt)) { \ |
1229 CLEAR_ERRNO; \ |
1229 CLEAR_ERRNO; \ |
1230 (ret) = write(fileno(f), (buf)+__offs, (cnt)-__offs);\ |
1230 (ret) = write(fileno(f), (buf)+__offs, (cnt)-__offs);\ |
1231 if ((ret) <= 0) { \ |
1231 if ((ret) <= 0) { \ |
1232 if ((ret) < 0) { \ |
1232 if ((ret) < 0) { \ |
1233 if (errno == EINTR) { \ |
1233 if (errno == EINTR) { \ |
1234 __HANDLE_INTERRUPTS__; \ |
1234 __HANDLE_INTERRUPTS__; \ |
1235 continue; \ |
1235 continue; \ |
1236 } \ |
1236 } \ |
1237 } \ |
1237 } \ |
1238 break; \ |
1238 break; \ |
1239 } \ |
1239 } \ |
1240 __offs += (ret); \ |
1240 __offs += (ret); \ |
1241 } \ |
1241 } \ |
1242 if (__offs > 0) \ |
1242 if (__offs > 0) \ |
1243 (ret) = __offs; \ |
1243 (ret) = __offs; \ |
1244 } |
1244 } |
1245 # endif /* use STDIO */ |
1245 # endif /* use STDIO */ |
1246 |
1246 |
1247 /* |
1247 /* |
1248 * write_bytes from an object |
1248 * write_bytes from an object |
1252 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1252 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1253 { \ |
1253 { \ |
1254 int __ooffs = obj_offs; \ |
1254 int __ooffs = obj_offs; \ |
1255 int __offs = 0; \ |
1255 int __offs = 0; \ |
1256 char *buf = (char *)(obj); \ |
1256 char *buf = (char *)(obj); \ |
1257 \ |
1257 \ |
1258 (ret) = 0; \ |
1258 (ret) = 0; \ |
1259 { \ |
1259 { \ |
1260 while (__offs < (cnt)) { \ |
1260 while (__offs < (cnt)) { \ |
1261 CLEAR_ERRNO; \ |
1261 CLEAR_ERRNO; \ |
1262 ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \ |
1262 ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \ |
1263 if (ret <= 0) { \ |
1263 if (ret <= 0) { \ |
1264 if (ret < 0 && errno == EINTR) { \ |
1264 if (ret < 0 && errno == EINTR) { \ |
1265 __HANDLE_INTERRUPTS__; \ |
1265 __HANDLE_INTERRUPTS__; \ |
1266 /* refetch */ \ |
1266 /* refetch */ \ |
1267 buf = (char *)(obj); \ |
1267 buf = (char *)(obj); \ |
1268 continue; \ |
1268 continue; \ |
1269 } \ |
1269 } \ |
1270 break; \ |
1270 break; \ |
1271 } \ |
1271 } \ |
1272 __offs += (ret); \ |
1272 __offs += (ret); \ |
1273 } \ |
1273 } \ |
1274 if (__offs > 0) \ |
1274 if (__offs > 0) \ |
1275 (ret) = __offs; \ |
1275 (ret) = __offs; \ |
1276 } \ |
1276 } \ |
1277 } |
1277 } |
1278 # else /* use STDIO */ |
1278 # else /* use STDIO */ |
1279 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1279 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \ |
1280 { \ |
1280 { \ |
1281 int __ooffs = obj_offs; \ |
1281 int __ooffs = obj_offs; \ |
1282 int __offs = 0; \ |
1282 int __offs = 0; \ |
1283 char *buf = (char *)(obj); \ |
1283 char *buf = (char *)(obj); \ |
1284 \ |
1284 \ |
1285 (ret) = 0; \ |
1285 (ret) = 0; \ |
1286 if (isBuffered) { \ |
1286 if (isBuffered) { \ |
1287 while (__offs < (cnt)) { \ |
1287 while (__offs < (cnt)) { \ |
1288 CLEAR_ERRNO; \ |
1288 CLEAR_ERRNO; \ |
1289 (ret) = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
1289 (ret) = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \ |
1290 if ((ret) <= 0) { \ |
1290 if ((ret) <= 0) { \ |
1291 if (ferror(f)) { \ |
1291 if (ferror(f)) { \ |
1292 if (errno == EINTR) { \ |
1292 if (errno == EINTR) { \ |
1293 __HANDLE_INTERRUPTS__; \ |
1293 __HANDLE_INTERRUPTS__; \ |
1294 /* refetch */ \ |
1294 /* refetch */ \ |
1295 buf = (char *)(obj); \ |
1295 buf = (char *)(obj); \ |
1296 clearerr(f); \ |
1296 clearerr(f); \ |
1297 continue; \ |
1297 continue; \ |
1298 } \ |
1298 } \ |
1299 break; \ |
1299 break; \ |
1300 } else { \ |
1300 } else { \ |
1301 (ret) = 0; \ |
1301 (ret) = 0; \ |
1302 } \ |
1302 } \ |
1303 } \ |
1303 } \ |
1304 __offs += (ret); \ |
1304 __offs += (ret); \ |
1305 } \ |
1305 } \ |
1306 } else { \ |
1306 } else { \ |
1307 while (__offs < (cnt)) { \ |
1307 while (__offs < (cnt)) { \ |
1308 CLEAR_ERRNO; \ |
1308 CLEAR_ERRNO; \ |
1309 (ret) = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1309 (ret) = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs); \ |
1310 if ((ret) <= 0) { \ |
1310 if ((ret) <= 0) { \ |
1311 if ((ret) < 0) { \ |
1311 if ((ret) < 0) { \ |
1312 if (errno == EINTR){ \ |
1312 if (errno == EINTR){ \ |
1313 __HANDLE_INTERRUPTS__; \ |
1313 __HANDLE_INTERRUPTS__; \ |
1314 /* refetch */ \ |
1314 /* refetch */ \ |
1315 buf = (char *)(obj); \ |
1315 buf = (char *)(obj); \ |
1316 continue; \ |
1316 continue; \ |
1317 } \ |
1317 } \ |
1318 } \ |
1318 } \ |
1319 break; \ |
1319 break; \ |
1320 } \ |
1320 } \ |
1321 __offs += (ret); \ |
1321 __offs += (ret); \ |
1322 } \ |
1322 } \ |
1323 } \ |
1323 } \ |
1324 if (__offs > 0) \ |
1324 if (__offs > 0) \ |
1325 (ret) = __offs; \ |
1325 (ret) = __offs; \ |
1326 } |
1326 } |
1327 # endif /* use STDIO */ |
1327 # endif /* use STDIO */ |
1328 #endif /* unix */ |
1328 #endif /* unix */ |
1329 %} |
1329 %} |
1330 ! ! |
1330 ! ! |
2029 ! |
2029 ! |
2030 |
2030 |
2031 eolMode |
2031 eolMode |
2032 "return how end-of-line (EOL) is to be marked. |
2032 "return how end-of-line (EOL) is to be marked. |
2033 Returns one one of: |
2033 Returns one one of: |
2034 #crlf -> add a CR-NL, as in MSDOS |
2034 #crlf -> add a CR-NL, as in MSDOS |
2035 #cr -> add a CR, as in VMS |
2035 #cr -> add a CR, as in VMS |
2036 #nl -> add a NL, as in Unix |
2036 #nl -> add a NL, as in Unix |
2037 nil -> transparent |
2037 nil -> transparent |
2038 " |
2038 " |
2039 |
2039 |
2040 ^ eolMode |
2040 ^ eolMode |
2041 ! |
2041 ! |
2042 |
2042 |
2043 eolMode:aSymbolOrNil |
2043 eolMode:aSymbolOrNil |
2044 "specify how end-of-line (EOL) is to be marked. |
2044 "specify how end-of-line (EOL) is to be marked. |
2045 The argument may be one of: |
2045 The argument may be one of: |
2497 finalize |
2497 finalize |
2498 "some Stream has been collected - close the file if not already done" |
2498 "some Stream has been collected - close the file if not already done" |
2499 |
2499 |
2500 "/ with timeout to avoid blocking in a bad pty/socket |
2500 "/ with timeout to avoid blocking in a bad pty/socket |
2501 [ |
2501 [ |
2502 self closeFile |
2502 self closeFile |
2503 ] valueWithTimeout:30 seconds. |
2503 ] valueWithTimeout:30 seconds. |
2504 ! ! |
2504 ! ! |
2505 |
2505 |
2506 !ExternalStream methodsFor:'initialization'! |
2506 !ExternalStream methodsFor:'initialization'! |
2507 |
2507 |
2540 if ((__INST(handleType) == nil) |
2540 if ((__INST(handleType) == nil) |
2541 || (__INST(handleType) == @symbol(filePointer)) |
2541 || (__INST(handleType) == @symbol(filePointer)) |
2542 || (__INST(handleType) == @symbol(socketFilePointer)) |
2542 || (__INST(handleType) == @symbol(socketFilePointer)) |
2543 || (__INST(handleType) == @symbol(socketHandle)) |
2543 || (__INST(handleType) == @symbol(socketHandle)) |
2544 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2544 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2545 if (((fp = __INST(handle)) != nil) |
2545 if (((fp = __INST(handle)) != nil) |
2546 && (__INST(mode) != @symbol(writeonly)) |
2546 && (__INST(mode) != @symbol(writeonly)) |
2547 && (__INST(binary) != true) |
2547 && (__INST(binary) != true) |
2548 ) { |
2548 ) { |
2549 f = __FILEVal(fp); |
2549 f = __FILEVal(fp); |
2550 buffer[0] = '\0'; |
2550 buffer[0] = '\0'; |
2551 |
2551 |
2552 _buffered = (__INST(buffered) == true); |
2552 _buffered = (__INST(buffered) == true); |
2553 if (_buffered) { |
2553 if (_buffered) { |
2554 __READING__(f); |
2554 __READING__(f); |
2555 } |
2555 } |
2556 |
2556 |
2557 rslt = nextPtr = buffer; |
2557 rslt = nextPtr = buffer; |
2558 limit = buffer + sizeof(buffer) - 2; |
2558 limit = buffer + sizeof(buffer) - 2; |
2559 |
2559 |
2560 for (;;) { |
2560 for (;;) { |
2561 __READBYTE__(ret, f, nextPtr, _buffered, __INST(handleType)); |
2561 __READBYTE__(ret, f, nextPtr, _buffered, __INST(handleType)); |
2562 if (ret <= 0) { |
2562 if (ret <= 0) { |
2563 if (nextPtr == buffer) |
2563 if (nextPtr == buffer) |
2564 rslt = NULL; |
2564 rslt = NULL; |
2565 if (ret == 0) { |
2565 if (ret == 0) { |
2566 __INST(hitEOF) = true; |
2566 __INST(hitEOF) = true; |
2567 break; |
2567 break; |
2568 } else { |
2568 } else { |
2569 error = __mkSmallInteger(__threadErrno); |
2569 error = __mkSmallInteger(__threadErrno); |
2570 goto err; |
2570 goto err; |
2571 } |
2571 } |
2572 } |
2572 } |
2573 |
2573 |
2574 if (*nextPtr == '\n') { |
2574 if (*nextPtr == '\n') { |
2575 cutOff = 1; |
2575 cutOff = 1; |
2576 *nextPtr = '\0'; |
2576 *nextPtr = '\0'; |
2577 break; |
2577 break; |
2578 } |
2578 } |
2579 if (*nextPtr == '\r') { |
2579 if (*nextPtr == '\r') { |
2580 char peekChar; |
2580 char peekChar; |
2581 |
2581 |
2582 /* |
2582 /* |
2583 * peek ahead for a newLine ... |
2583 * peek ahead for a newLine ... |
2584 */ |
2584 */ |
2585 __READBYTE__(ret, f, &peekChar, _buffered, __INST(handleType)); |
2585 __READBYTE__(ret, f, &peekChar, _buffered, __INST(handleType)); |
2586 if (ret <= 0) { |
2586 if (ret <= 0) { |
2587 cutOff = 1; |
2587 cutOff = 1; |
2588 *nextPtr = '\0'; |
2588 *nextPtr = '\0'; |
2589 if (ret == 0) { |
2589 if (ret == 0) { |
2590 __INST(hitEOF) = true; |
2590 __INST(hitEOF) = true; |
2591 break; |
2591 break; |
2592 } |
2592 } |
2593 error = __mkSmallInteger(__threadErrno); |
2593 error = __mkSmallInteger(__threadErrno); |
2594 goto err; |
2594 goto err; |
2595 } |
2595 } |
2596 |
2596 |
2597 if (peekChar == '\n') { |
2597 if (peekChar == '\n') { |
2598 cutOff = 2; |
2598 cutOff = 2; |
2599 *nextPtr = '\0'; |
2599 *nextPtr = '\0'; |
2600 break; |
2600 break; |
2601 } |
2601 } |
2602 |
2602 |
2603 __UNGETC__(peekChar, f, _buffered); |
2603 __UNGETC__(peekChar, f, _buffered); |
2604 |
2604 |
2605 cutOff = 1; |
2605 cutOff = 1; |
2606 *nextPtr = '\0'; |
2606 *nextPtr = '\0'; |
2607 break; |
2607 break; |
2608 } |
2608 } |
2609 |
2609 |
2610 nextPtr++; |
2610 nextPtr++; |
2611 if (nextPtr >= limit) { |
2611 if (nextPtr >= limit) { |
2612 *nextPtr = '\0'; |
2612 *nextPtr = '\0'; |
2613 lineTooLong = 1; |
2613 lineTooLong = 1; |
2614 if (@global(InfoPrinting) == true) { |
2614 if (@global(InfoPrinting) == true) { |
2615 fprintf(stderr, "ExtStream [warning]: line truncated in nextLine\n"); |
2615 fprintf(stderr, "ExtStream [warning]: line truncated in nextLine\n"); |
2616 } |
2616 } |
2617 break; |
2617 break; |
2618 } |
2618 } |
2619 } |
2619 } |
2620 |
2620 |
2621 if (rslt != NULL) { |
2621 if (rslt != NULL) { |
2622 len = nextPtr-buffer; |
2622 len = nextPtr-buffer; |
2623 |
2623 |
2624 if (__isSmallInteger(__INST(position))) { |
2624 if (__isSmallInteger(__INST(position))) { |
2625 INT np = __intVal(__INST(position)) + len + cutOff; |
2625 INT np = __intVal(__INST(position)) + len + cutOff; |
2626 OBJ t; |
2626 OBJ t; |
2627 |
2627 |
2628 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
2628 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
2629 } else { |
2629 } else { |
2630 __INST(position) = nil; /* i.e. do not know */ |
2630 __INST(position) = nil; /* i.e. do not know */ |
2631 } |
2631 } |
2632 /* remove any EOL character */ |
2632 /* remove any EOL character */ |
2633 if (len != 0) { |
2633 if (len != 0) { |
2634 if (buffer[len-1] == '\n') { |
2634 if (buffer[len-1] == '\n') { |
2635 buffer[--len] = '\0'; |
2635 buffer[--len] = '\0'; |
2636 } |
2636 } |
2637 if ((len != 0) && (buffer[len-1] == '\r')) { |
2637 if ((len != 0) && (buffer[len-1] == '\r')) { |
2638 buffer[--len] = '\0'; |
2638 buffer[--len] = '\0'; |
2639 } |
2639 } |
2640 } |
2640 } |
2641 line = __MKSTRING_L(buffer, len); |
2641 line = __MKSTRING_L(buffer, len); |
2642 if (! lineTooLong) { |
2642 if (! lineTooLong) { |
2643 RETURN ( line ); |
2643 RETURN ( line ); |
2644 } |
2644 } |
2645 } |
2645 } |
2646 } |
2646 } |
2647 } |
2647 } |
2648 err: ; |
2648 err: ; |
2649 %}. |
2649 %}. |
2650 line notNil ifTrue:[ |
2650 line notNil ifTrue:[ |
2651 "/ the line as read is longer than 32k characters (boy - what a line) |
2651 "/ the line as read is longer than 32k characters (boy - what a line) |
2652 "/ The exception could be handled by reading more and returning the |
2652 "/ The exception could be handled by reading more and returning the |
2653 "/ concatenation in your exception handler (the receiver and the partial |
2653 "/ concatenation in your exception handler (the receiver and the partial |
2654 "/ line are passed as parameter) |
2654 "/ line are passed as parameter) |
2655 |
2655 |
2656 LineTooLongErrorSignal isHandled ifTrue:[ |
2656 LineTooLongErrorSignal isHandled ifTrue:[ |
2657 ^ LineTooLongErrorSignal |
2657 ^ LineTooLongErrorSignal |
2658 raiseRequestWith:(Array with:self with:line) |
2658 raiseRequestWith:(Array with:self with:line) |
2659 errorString:('line too long read error') |
2659 errorString:('line too long read error') |
2660 ]. |
2660 ]. |
2661 ^ line , self nextLine |
2661 ^ line , self nextLine |
2662 ]. |
2662 ]. |
2663 |
2663 |
2664 (hitEOF == true) ifTrue:[^ self pastEndRead]. |
2664 (hitEOF == true) ifTrue:[^ self pastEndRead]. |
2665 error notNil ifTrue:[ |
2665 error notNil ifTrue:[ |
2666 lastErrorNumber := error. |
2666 lastErrorNumber := error. |
2667 ^ self readError:error |
2667 ^ self readError:error |
2668 ]. |
2668 ]. |
2669 handle isNil ifTrue:[^ self errorNotOpen]. |
2669 handle isNil ifTrue:[^ self errorNotOpen]. |
2670 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
2670 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
2671 (binary == true) ifTrue:[^ self errorBinary]. |
2671 (binary == true) ifTrue:[^ self errorBinary]. |
2672 ^ super nextLine |
2672 ^ super nextLine |
4573 do { |
4573 do { |
4574 __threadErrno = 0; |
4574 __threadErrno = 0; |
4575 rslt = __STX_C_NOINT_CALL1("fclose", fclose, f); |
4575 rslt = __STX_C_NOINT_CALL1("fclose", fclose, f); |
4576 } while((rslt < 0) && (__threadErrno == EINTR)); |
4576 } while((rslt < 0) && (__threadErrno == EINTR)); |
4577 #else |
4577 #else |
4578 __BEGIN_INTERRUPTABLE__ |
4578 // cg: the pre Nov2014 code always did the fclose interruptable; |
4579 rslt = fclose(f); |
4579 // I am not sure, if fclose is actually prepared to do this; |
4580 __END_INTERRUPTABLE__ |
4580 // at least when only reading, this should not block, and we |
4581 // should be ableto do it without being interruptable. |
|
4582 // Must watch this - if it leads to blockings, change and think about it. |
|
4583 if (__INST(mode) != @symbol(readonly)) { |
|
4584 __BEGIN_INTERRUPTABLE__ |
|
4585 rslt = fclose(f); |
|
4586 __END_INTERRUPTABLE__ |
|
4587 } else { |
|
4588 rslt = fclose(f); |
|
4589 } |
|
4581 #endif |
4590 #endif |
4582 } else { |
4591 } else { |
4583 error = @symbol(badHandleType); |
4592 error = @symbol(badHandleType); |
4584 goto out; |
4593 goto out; |
4585 } |
4594 } |
4597 error == #errorNotOpen ifTrue:[ |
4606 error == #errorNotOpen ifTrue:[ |
4598 self errorNotOpen. |
4607 self errorNotOpen. |
4599 ]. |
4608 ]. |
4600 error isInteger ifTrue:[ |
4609 error isInteger ifTrue:[ |
4601 lastErrorNumber := error. |
4610 lastErrorNumber := error. |
4602 self writeError:error. |
4611 mode == #readonly ifTrue:[ |
4612 self ioError:error. |
|
4613 ] ifFalse:[ |
|
4614 self writeError:error. |
|
4615 ]. |
|
4603 ^ self. |
4616 ^ self. |
4604 ]. |
4617 ]. |
4605 self primitiveFailed:error. |
4618 self primitiveFailed:error. |
4606 ^ self. |
4619 ^ self. |
4607 ]. |
4620 ]. |
4990 if ((__INST(handleType) == nil) |
5003 if ((__INST(handleType) == nil) |
4991 || (__INST(handleType) == @symbol(filePointer)) |
5004 || (__INST(handleType) == @symbol(filePointer)) |
4992 || (__INST(handleType) == @symbol(socketFilePointer)) |
5005 || (__INST(handleType) == @symbol(socketFilePointer)) |
4993 || (__INST(handleType) == @symbol(socketHandle)) |
5006 || (__INST(handleType) == @symbol(socketHandle)) |
4994 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5007 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4995 if (((fp = __INST(handle)) != nil) |
5008 if (((fp = __INST(handle)) != nil) |
4996 && (__INST(mode) != @symbol(writeonly)) |
5009 && (__INST(mode) != @symbol(writeonly)) |
4997 ) { |
5010 ) { |
4998 f = __FILEVal(fp); |
5011 f = __FILEVal(fp); |
4999 |
5012 |
5000 _buffered = (__INST(buffered) == true); |
5013 _buffered = (__INST(buffered) == true); |
5001 if (_buffered) { |
5014 if (_buffered) { |
5002 __READING__(f) |
5015 __READING__(f) |
5003 } |
5016 } |
5004 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
5017 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
5005 |
5018 |
5006 if (ret > 0) { |
5019 if (ret > 0) { |
5007 pos = __INST(position); |
5020 pos = __INST(position); |
5008 if (__isSmallInteger(pos)) { |
5021 if (__isSmallInteger(pos)) { |
5009 OBJ t; |
5022 OBJ t; |
5010 |
5023 |
5011 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
5024 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
5012 } else { |
5025 } else { |
5013 __INST(position) = nil; /* i.e. do not know */ |
5026 __INST(position) = nil; /* i.e. do not know */ |
5014 } |
5027 } |
5015 if (__INST(binary) == true) { |
5028 if (__INST(binary) == true) { |
5016 RETURN ( __mkSmallInteger(ch) ); |
5029 RETURN ( __mkSmallInteger(ch) ); |
5017 } |
5030 } |
5018 RETURN ( __MKCHARACTER(ch) ); |
5031 RETURN ( __MKCHARACTER(ch) ); |
5019 } |
5032 } |
5020 |
5033 |
5021 __INST(position) = nil; |
5034 __INST(position) = nil; |
5022 if (ret < 0) { |
5035 if (ret < 0) { |
5023 error = __mkSmallInteger(__threadErrno); |
5036 error = __mkSmallInteger(__threadErrno); |
5024 } else /* ret == 0 */ { |
5037 } else /* ret == 0 */ { |
5025 __INST(hitEOF) = true; |
5038 __INST(hitEOF) = true; |
5026 } |
5039 } |
5027 } |
5040 } |
5028 } |
5041 } |
5029 %}. |
5042 %}. |
5030 hitEOF == true ifTrue:[^ self pastEndRead]. |
5043 hitEOF == true ifTrue:[^ self pastEndRead]. |
5031 error notNil ifTrue:[ |
5044 error notNil ifTrue:[ |
5032 lastErrorNumber := error. |
5045 lastErrorNumber := error. |
5033 ^ self readError:error |
5046 ^ self readError:error |
5034 ]. |
5047 ]. |
5035 handle isNil ifTrue:[^ self errorNotOpen]. |
5048 handle isNil ifTrue:[^ self errorNotOpen]. |
5036 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5049 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5037 |
5050 |
5038 readAhead notNil ifTrue:[ |
5051 readAhead notNil ifTrue:[ |
5039 c := readAhead. |
5052 c := readAhead. |
5040 readAhead := nil. |
5053 readAhead := nil. |
5041 ^ c. |
5054 ^ c. |
5042 ]. |
5055 ]. |
5043 c := self nextByteFromFile:handle. |
5056 c := self nextByteFromFile:handle. |
5044 c isNil ifTrue:[ |
5057 c isNil ifTrue:[ |
5045 ^ self pastEndRead. |
5058 ^ self pastEndRead. |
5046 ]. |
5059 ]. |
5047 binary == true ifTrue:[ |
5060 binary == true ifTrue:[ |
5048 ^ c |
5061 ^ c |
5049 ]. |
5062 ]. |
5050 ^ Character value:c |
5063 ^ Character value:c |
5051 ! |
5064 ! |
5052 |
5065 |
5053 next:count |
5066 next:count |
5055 Redefined to return a String or ByteArray instead of the default: Array." |
5068 Redefined to return a String or ByteArray instead of the default: Array." |
5056 |
5069 |
5057 |coll nRead| |
5070 |coll nRead| |
5058 |
5071 |
5059 binary ifTrue:[ |
5072 binary ifTrue:[ |
5060 coll := ByteArray uninitializedNew:count |
5073 coll := ByteArray uninitializedNew:count |
5061 ] ifFalse:[ |
5074 ] ifFalse:[ |
5062 coll := String new:count |
5075 coll := String new:count |
5063 ]. |
5076 ]. |
5064 nRead := self nextBytes:count into:coll startingAt:1. |
5077 nRead := self nextBytes:count into:coll startingAt:1. |
5065 |
5078 |
5066 "/ for readStream protocol compatibility, |
5079 "/ for readStream protocol compatibility, |
5067 "/ we must raise an exception here. |
5080 "/ we must raise an exception here. |
5068 |
5081 |
5069 nRead < count ifTrue:[ |
5082 nRead < count ifTrue:[ |
5070 ^ self pastEndRead |
5083 ^ self pastEndRead |
5071 ]. |
5084 ]. |
5072 ^ coll |
5085 ^ coll |
5073 |
5086 |
5074 "Modified: 11.1.1997 / 17:44:17 / cg" |
5087 "Modified: 11.1.1997 / 17:44:17 / cg" |
5075 ! |
5088 ! |
5091 if ((__INST(handleType) == nil) |
5104 if ((__INST(handleType) == nil) |
5092 || (__INST(handleType) == @symbol(filePointer)) |
5105 || (__INST(handleType) == @symbol(filePointer)) |
5093 || (__INST(handleType) == @symbol(socketFilePointer)) |
5106 || (__INST(handleType) == @symbol(socketFilePointer)) |
5094 || (__INST(handleType) == @symbol(socketHandle)) |
5107 || (__INST(handleType) == @symbol(socketHandle)) |
5095 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5108 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5096 if (((fp = __INST(handle)) != nil) |
5109 if (((fp = __INST(handle)) != nil) |
5097 && (__INST(mode) != @symbol(writeonly)) |
5110 && (__INST(mode) != @symbol(writeonly)) |
5098 ) { |
5111 ) { |
5099 f = __FILEVal(fp); |
5112 f = __FILEVal(fp); |
5100 |
5113 |
5101 _buffered = (__INST(buffered) == true); |
5114 _buffered = (__INST(buffered) == true); |
5102 if (_buffered) { |
5115 if (_buffered) { |
5103 __READING__(f) |
5116 __READING__(f) |
5104 } |
5117 } |
5105 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
5118 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
5106 |
5119 |
5107 if (ret > 0) { |
5120 if (ret > 0) { |
5108 pos = __INST(position); |
5121 pos = __INST(position); |
5109 if (__isSmallInteger(pos)) { |
5122 if (__isSmallInteger(pos)) { |
5110 OBJ t; |
5123 OBJ t; |
5111 |
5124 |
5112 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
5125 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
5113 } else { |
5126 } else { |
5114 __INST(position) = nil; /* i.e. do not know */ |
5127 __INST(position) = nil; /* i.e. do not know */ |
5115 } |
5128 } |
5116 if (__INST(binary) == true) { |
5129 if (__INST(binary) == true) { |
5117 RETURN ( __mkSmallInteger(ch) ); |
5130 RETURN ( __mkSmallInteger(ch) ); |
5118 } |
5131 } |
5119 RETURN ( __MKCHARACTER(ch) ); |
5132 RETURN ( __MKCHARACTER(ch) ); |
5120 } |
5133 } |
5121 |
5134 |
5122 __INST(position) = nil; |
5135 __INST(position) = nil; |
5123 if (ret < 0) { |
5136 if (ret < 0) { |
5124 error = __mkSmallInteger(__threadErrno); |
5137 error = __mkSmallInteger(__threadErrno); |
5125 } else /* ret == 0 */ { |
5138 } else /* ret == 0 */ { |
5126 __INST(hitEOF) = true; |
5139 __INST(hitEOF) = true; |
5127 } |
5140 } |
5128 } |
5141 } |
5129 } |
5142 } |
5130 %}. |
5143 %}. |
5131 hitEOF == true ifTrue:[^ nil]. |
5144 hitEOF == true ifTrue:[^ nil]. |
5132 error notNil ifTrue:[ |
5145 error notNil ifTrue:[ |
5133 lastErrorNumber := error. |
5146 lastErrorNumber := error. |
5134 ^ self readError:error. |
5147 ^ self readError:error. |
5135 ]. |
5148 ]. |
5136 handle isNil ifTrue:[^ self errorNotOpen]. |
5149 handle isNil ifTrue:[^ self errorNotOpen]. |
5137 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5150 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5138 |
5151 |
5139 readAhead notNil ifTrue:[ |
5152 readAhead notNil ifTrue:[ |
5140 c := readAhead. |
5153 c := readAhead. |
5141 readAhead := nil. |
5154 readAhead := nil. |
5142 ^ c. |
5155 ^ c. |
5143 ]. |
5156 ]. |
5144 c := self nextByteFromFile:handle. |
5157 c := self nextByteFromFile:handle. |
5145 c isNil ifTrue:[ |
5158 c isNil ifTrue:[ |
5146 ^ nil. |
5159 ^ nil. |
5147 ]. |
5160 ]. |
5148 binary == true ifTrue:[ |
5161 binary == true ifTrue:[ |
5149 ^ c |
5162 ^ c |
5150 ]. |
5163 ]. |
5151 ^ Character value:c |
5164 ^ Character value:c |
5152 ! |
5165 ! |
5153 |
5166 |
5154 peek |
5167 peek |
5164 int ret, _buffered; |
5177 int ret, _buffered; |
5165 OBJ fp; |
5178 OBJ fp; |
5166 OBJ ra; |
5179 OBJ ra; |
5167 |
5180 |
5168 if ((ra = __INST(readAhead)) != nil) { |
5181 if ((ra = __INST(readAhead)) != nil) { |
5169 if (__INST(binary) == true) { |
5182 if (__INST(binary) == true) { |
5170 RETURN ( ra ); |
5183 RETURN ( ra ); |
5171 } |
5184 } |
5172 c = __intVal(ra); |
5185 c = __intVal(ra); |
5173 RETURN ( __MKCHARACTER(c) ); |
5186 RETURN ( __MKCHARACTER(c) ); |
5174 } |
5187 } |
5175 |
5188 |
5176 __INST(lastErrorNumber) = nil; |
5189 __INST(lastErrorNumber) = nil; |
5177 |
5190 |
5178 if ((__INST(handleType) == nil) |
5191 if ((__INST(handleType) == nil) |
5179 || (__INST(handleType) == @symbol(filePointer)) |
5192 || (__INST(handleType) == @symbol(filePointer)) |
5180 || (__INST(handleType) == @symbol(socketFilePointer)) |
5193 || (__INST(handleType) == @symbol(socketFilePointer)) |
5181 || (__INST(handleType) == @symbol(socketHandle)) |
5194 || (__INST(handleType) == @symbol(socketHandle)) |
5182 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5195 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5183 if (((fp = __INST(handle)) != nil) |
5196 if (((fp = __INST(handle)) != nil) |
5184 && (__INST(mode) != @symbol(writeonly)) |
5197 && (__INST(mode) != @symbol(writeonly)) |
5185 ) { |
5198 ) { |
5186 f = __FILEVal(fp); |
5199 f = __FILEVal(fp); |
5187 _buffered = (__INST(buffered) == true); |
5200 _buffered = (__INST(buffered) == true); |
5188 if (_buffered) { |
5201 if (_buffered) { |
5189 __READING__(f) |
5202 __READING__(f) |
5190 } |
5203 } |
5191 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5204 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5192 |
5205 |
5193 if (ret > 0) { |
5206 if (ret > 0) { |
5194 __UNGETC__(c, f, _buffered); |
5207 __UNGETC__(c, f, _buffered); |
5195 |
5208 |
5196 if (__INST(binary) == true) { |
5209 if (__INST(binary) == true) { |
5197 RETURN ( __mkSmallInteger(c) ); |
5210 RETURN ( __mkSmallInteger(c) ); |
5198 } |
5211 } |
5199 RETURN ( __MKCHARACTER(c) ); |
5212 RETURN ( __MKCHARACTER(c) ); |
5200 } |
5213 } |
5201 if (ret < 0) { |
5214 if (ret < 0) { |
5202 error = __mkSmallInteger(__threadErrno); |
5215 error = __mkSmallInteger(__threadErrno); |
5203 } else /* ret == 0 */ { |
5216 } else /* ret == 0 */ { |
5204 __INST(hitEOF) = true; |
5217 __INST(hitEOF) = true; |
5205 } |
5218 } |
5206 } |
5219 } |
5207 } |
5220 } |
5208 %}. |
5221 %}. |
5209 hitEOF == true ifTrue:[^ self pastEndRead]. |
5222 hitEOF == true ifTrue:[^ self pastEndRead]. |
5210 error notNil ifTrue:[ |
5223 error notNil ifTrue:[ |
5211 lastErrorNumber := error. |
5224 lastErrorNumber := error. |
5212 ^ self readError:error. |
5225 ^ self readError:error. |
5213 ]. |
5226 ]. |
5214 handle isNil ifTrue:[^ self errorNotOpen]. |
5227 handle isNil ifTrue:[^ self errorNotOpen]. |
5215 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5228 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5216 |
5229 |
5217 readAhead isNil ifTrue:[ |
5230 readAhead isNil ifTrue:[ |
5218 readAhead := self nextOrNil. |
5231 readAhead := self nextOrNil. |
5219 readAhead isNil ifTrue:[ |
5232 readAhead isNil ifTrue:[ |
5220 ^ self pastEndRead. |
5233 ^ self pastEndRead. |
5221 ]. |
5234 ]. |
5222 ]. |
5235 ]. |
5223 ^ readAhead |
5236 ^ readAhead |
5224 ! |
5237 ! |
5225 |
5238 |
5226 peekOrNil |
5239 peekOrNil |
5236 int ret, _buffered; |
5249 int ret, _buffered; |
5237 OBJ fp; |
5250 OBJ fp; |
5238 OBJ ra; |
5251 OBJ ra; |
5239 |
5252 |
5240 if ((ra = __INST(readAhead)) != nil) { |
5253 if ((ra = __INST(readAhead)) != nil) { |
5241 if (__INST(binary) == true) { |
5254 if (__INST(binary) == true) { |
5242 RETURN ( ra ); |
5255 RETURN ( ra ); |
5243 } |
5256 } |
5244 c = __intVal(ra); |
5257 c = __intVal(ra); |
5245 RETURN ( __MKCHARACTER(c) ); |
5258 RETURN ( __MKCHARACTER(c) ); |
5246 } |
5259 } |
5247 |
5260 |
5248 __INST(lastErrorNumber) = nil; |
5261 __INST(lastErrorNumber) = nil; |
5249 |
5262 |
5250 if ((__INST(handleType) == nil) |
5263 if ((__INST(handleType) == nil) |
5251 || (__INST(handleType) == @symbol(filePointer)) |
5264 || (__INST(handleType) == @symbol(filePointer)) |
5252 || (__INST(handleType) == @symbol(socketFilePointer)) |
5265 || (__INST(handleType) == @symbol(socketFilePointer)) |
5253 || (__INST(handleType) == @symbol(socketHandle)) |
5266 || (__INST(handleType) == @symbol(socketHandle)) |
5254 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5267 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5255 if (((fp = __INST(handle)) != nil) |
5268 if (((fp = __INST(handle)) != nil) |
5256 && (__INST(mode) != @symbol(writeonly)) |
5269 && (__INST(mode) != @symbol(writeonly)) |
5257 ) { |
5270 ) { |
5258 f = __FILEVal(fp); |
5271 f = __FILEVal(fp); |
5259 _buffered = (__INST(buffered) == true); |
5272 _buffered = (__INST(buffered) == true); |
5260 if (_buffered) { |
5273 if (_buffered) { |
5261 __READING__(f) |
5274 __READING__(f) |
5262 } |
5275 } |
5263 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5276 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5264 |
5277 |
5265 if (ret > 0) { |
5278 if (ret > 0) { |
5266 __UNGETC__(c, f, _buffered); |
5279 __UNGETC__(c, f, _buffered); |
5267 |
5280 |
5268 if (__INST(binary) == true) { |
5281 if (__INST(binary) == true) { |
5269 RETURN ( __mkSmallInteger(c) ); |
5282 RETURN ( __mkSmallInteger(c) ); |
5270 } |
5283 } |
5271 RETURN ( __MKCHARACTER(c) ); |
5284 RETURN ( __MKCHARACTER(c) ); |
5272 } |
5285 } |
5273 if (ret < 0) { |
5286 if (ret < 0) { |
5274 error = __mkSmallInteger(__threadErrno); |
5287 error = __mkSmallInteger(__threadErrno); |
5275 } else /* ret == 0 */ { |
5288 } else /* ret == 0 */ { |
5276 __INST(hitEOF) = true; |
5289 __INST(hitEOF) = true; |
5277 } |
5290 } |
5278 } |
5291 } |
5279 } |
5292 } |
5280 %}. |
5293 %}. |
5281 hitEOF == true ifTrue:[^ nil]. |
5294 hitEOF == true ifTrue:[^ nil]. |
5282 error notNil ifTrue:[ |
5295 error notNil ifTrue:[ |
5283 lastErrorNumber := error. |
5296 lastErrorNumber := error. |
5284 ^ self readError:error. |
5297 ^ self readError:error. |
5285 ]. |
5298 ]. |
5286 handle isNil ifTrue:[^ self errorNotOpen]. |
5299 handle isNil ifTrue:[^ self errorNotOpen]. |
5287 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5300 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5288 |
5301 |
5289 readAhead isNil ifTrue:[ |
5302 readAhead isNil ifTrue:[ |
5290 readAhead := self nextOrNil. |
5303 readAhead := self nextOrNil. |
5291 ]. |
5304 ]. |
5292 ^ readAhead |
5305 ^ readAhead |
5293 ! |
5306 ! |
5294 |
5307 |
5295 upToEnd |
5308 upToEnd |
5351 OBJ fp, pos, lim; |
5364 OBJ fp, pos, lim; |
5352 char c; |
5365 char c; |
5353 int ret, _buffered; |
5366 int ret, _buffered; |
5354 |
5367 |
5355 if (__INST(hitEOF) == true) { |
5368 if (__INST(hitEOF) == true) { |
5356 RETURN (true); |
5369 RETURN (true); |
5357 } |
5370 } |
5358 pos = __INST(position); |
5371 pos = __INST(position); |
5359 lim = __INST(readLimit); |
5372 lim = __INST(readLimit); |
5360 if (lim != nil) { |
5373 if (lim != nil) { |
5361 off_t _pos, _readLimit; |
5374 off_t _pos, _readLimit; |
5362 |
5375 |
5363 _pos = __signedLongIntVal(pos); |
5376 _pos = __signedLongIntVal(pos); |
5364 _pos = _pos - __intVal( @global(PositionableStream:ZeroPosition)) + 1; |
5377 _pos = _pos - __intVal( @global(PositionableStream:ZeroPosition)) + 1; |
5365 _readLimit = __signedLongIntVal(lim); |
5378 _readLimit = __signedLongIntVal(lim); |
5366 if (_pos > _readLimit) { |
5379 if (_pos > _readLimit) { |
5367 RETURN (true); |
5380 RETURN (true); |
5368 } |
5381 } |
5369 } |
5382 } |
5370 |
5383 |
5371 __INST(lastErrorNumber) = nil; |
5384 __INST(lastErrorNumber) = nil; |
5372 |
5385 |
5373 if ((__INST(handleType) == nil) |
5386 if ((__INST(handleType) == nil) |
5374 || (__INST(handleType) == @symbol(filePointer)) |
5387 || (__INST(handleType) == @symbol(filePointer)) |
5375 || (__INST(handleType) == @symbol(socketFilePointer)) |
5388 || (__INST(handleType) == @symbol(socketFilePointer)) |
5376 || (__INST(handleType) == @symbol(socketHandle)) |
5389 || (__INST(handleType) == @symbol(socketHandle)) |
5377 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5390 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5378 if ((fp = __INST(handle)) != nil) { |
5391 if ((fp = __INST(handle)) != nil) { |
5379 f = __FILEVal(fp); |
5392 f = __FILEVal(fp); |
5380 if (_buffered = (__INST(buffered) == true)) { |
5393 if (_buffered = (__INST(buffered) == true)) { |
5381 __READING__(f); |
5394 __READING__(f); |
5382 } else { |
5395 } else { |
5383 if (__INST(readAhead) != nil) { |
5396 if (__INST(readAhead) != nil) { |
5384 RETURN (false); |
5397 RETURN (false); |
5385 } |
5398 } |
5386 } |
5399 } |
5387 |
5400 |
5388 /* |
5401 /* |
5389 * read ahead ... |
5402 * read ahead ... |
5390 */ |
5403 */ |
5391 do { |
5404 do { |
5392 #ifdef WIN32 |
5405 #ifdef WIN32 |
5393 # if 1 |
5406 # if 1 |
5394 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5407 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5395 |
5408 |
5396 # else |
5409 # else |
5397 __BEGIN_INTERRUPTABLE__ |
5410 __BEGIN_INTERRUPTABLE__ |
5398 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5411 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5399 __END_INTERRUPTABLE__ |
5412 __END_INTERRUPTABLE__ |
5400 # endif |
5413 # endif |
5401 #else /* not WIN32 */ |
5414 #else /* not WIN32 */ |
5402 __BEGIN_INTERRUPTABLE__ |
5415 __BEGIN_INTERRUPTABLE__ |
5403 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5416 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5404 __END_INTERRUPTABLE__ |
5417 __END_INTERRUPTABLE__ |
5405 #endif |
5418 #endif |
5406 } while ((ret < 0) && (__threadErrno == EINTR)); |
5419 } while ((ret < 0) && (__threadErrno == EINTR)); |
5407 |
5420 |
5408 if (ret > 0) { |
5421 if (ret > 0) { |
5409 __UNGETC__(c&0xff, f, _buffered); |
5422 __UNGETC__(c&0xff, f, _buffered); |
5410 RETURN (false); |
5423 RETURN (false); |
5411 } |
5424 } |
5412 if (ret == 0) { |
5425 if (ret == 0) { |
5413 __INST(hitEOF) = true; |
5426 __INST(hitEOF) = true; |
5414 RETURN (true); |
5427 RETURN (true); |
5415 } |
5428 } |
5416 |
5429 |
5417 /* ret < 0 */ |
5430 /* ret < 0 */ |
5418 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
5431 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
5419 } |
5432 } |
5420 } |
5433 } |
5421 %}. |
5434 %}. |
5422 lastErrorNumber notNil ifTrue:[^ self readError]. |
5435 lastErrorNumber notNil ifTrue:[^ self readError]. |
5423 handle isNil ifTrue:[^ self errorNotOpen]. |
5436 handle isNil ifTrue:[^ self errorNotOpen]. |
5424 mode == #writeonly ifTrue:[^ self errorWriteOnly]. |
5437 mode == #writeonly ifTrue:[^ self errorWriteOnly]. |
5425 readAhead notNil ifTrue:[^ false]. |
5438 readAhead notNil ifTrue:[^ false]. |
5426 |
5439 |
5427 "/ migration support |
5440 "/ migration support |
5428 ^ self |
5441 ^ self |
5429 atEndFile:handle |
5442 atEndFile:handle |
5430 |
5443 |
5431 "Modified: / 30.10.1998 / 20:16:06 / cg" |
5444 "Modified: / 30.10.1998 / 20:16:06 / cg" |
5432 ! |
5445 ! |
5433 |
5446 |
5434 canReadWithoutBlocking |
5447 canReadWithoutBlocking |
6093 ! ! |
6106 ! ! |
6094 |
6107 |
6095 !ExternalStream class methodsFor:'documentation'! |
6108 !ExternalStream class methodsFor:'documentation'! |
6096 |
6109 |
6097 version |
6110 version |
6098 ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.397 2014-11-18 20:17:17 cg Exp $' |
6111 ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.398 2014-11-24 14:37:58 cg Exp $' |
6099 ! |
6112 ! |
6100 |
6113 |
6101 version_CVS |
6114 version_CVS |
6102 ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.397 2014-11-18 20:17:17 cg Exp $' |
6115 ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.398 2014-11-24 14:37:58 cg Exp $' |
6103 ! ! |
6116 ! ! |
6104 |
6117 |
6105 |
6118 |
6106 ExternalStream initialize! |
6119 ExternalStream initialize! |