7 inclusion of the above copyright notice. This software may not |
7 inclusion of the above copyright notice. This software may not |
8 be provided or otherwise made available to, or used by, any |
8 be provided or otherwise made available to, or used by, any |
9 other person. No title to or ownership of the software is |
9 other person. No title to or ownership of the software is |
10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 |
|
13 "{ Package: 'stx:libbasic' }" |
12 "{ Package: 'stx:libbasic' }" |
14 |
13 |
15 ReadWriteStream subclass:#ExternalStream |
14 ReadWriteStream subclass:#ExternalStream |
16 instanceVariableNames:'handleType handle mode buffered binary eolMode hitEOF didWrite |
15 instanceVariableNames:'handleType handle mode buffered binary eolMode hitEOF didWrite |
17 lastErrorNumber readAhead' |
16 lastErrorNumber readAhead' |
4405 |
4401 |
4406 !ExternalStream methodsFor:'private'! |
4402 !ExternalStream methodsFor:'private'! |
4407 |
4403 |
4408 clearEOF |
4404 clearEOF |
4409 hitEOF := false |
4405 hitEOF := false |
4410 ! |
4406 ! ! |
|
4407 |
|
4408 !ExternalStream protectedMethodsFor:'private'! |
4411 |
4409 |
4412 closeFile |
4410 closeFile |
4413 "low level close - may be redefined in subclasses |
4411 "low level close - may be redefined in subclasses |
4414 Don't send this message, send #close instead" |
4412 Don't send this message, send #close instead" |
4415 |
4413 |
4416 |fp error| |
4414 |fp error| |
4417 |
4415 |
4418 %{ |
4416 %{ |
4419 if ((__INST(handleType) == nil) |
4417 if ((__INST(handleType) == nil) |
4420 || (__INST(handleType) == @symbol(filePointer)) |
4418 || (__INST(handleType) == @symbol(filePointer)) |
4421 || (__INST(handleType) == @symbol(socketFilePointer)) |
4419 || (__INST(handleType) == @symbol(socketFilePointer)) |
4422 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4420 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4423 if ((fp = __INST(handle)) != nil) { |
4421 if ((fp = __INST(handle)) == nil) { |
4424 FILEPOINTER f; |
4422 error = @symbol(errorNotOpen); |
4425 int rslt; |
4423 } else { |
4426 |
4424 FILEPOINTER f = __FILEVal(fp); |
4427 f = __FILEVal(fp); |
4425 int rslt; |
4428 if (@global(FileOpenTrace) == true) { |
4426 |
4429 fprintf(stderr, "fclose [ExternalStream] %"_lx_"\n", (INT)f); |
4427 // whether the fclose() will be successful or not - the handle is invalid now! |
4430 } |
4428 __INST(handle) = nil; |
|
4429 |
|
4430 if (@global(FileOpenTrace) == true) { |
|
4431 fprintf(stderr, "fclose [ExternalStream] %"_lx_"\n", (INT)f); |
|
4432 } |
4431 #ifdef WIN32 |
4433 #ifdef WIN32 |
4432 if (__INST(mode) != @symbol(readonly)) { |
4434 if (__INST(mode) != @symbol(readonly)) { |
4433 // do a fflush() first, so that fclose() doesn't block |
4435 // do a fflush() first, so that fclose() doesn't block |
4434 // we suspect, that EINTR causes problems in fclose() |
4436 // we suspect, that EINTR causes problems in fclose() |
4435 do { |
4437 do { |
4436 __threadErrno = 0; |
4438 __threadErrno = 0; |
4437 rslt = __STX_C_CALL1("fflush", fflush, f); |
4439 rslt = __STX_C_CALL1("fflush", fflush, f); |
4438 } while((rslt < 0) && (__threadErrno == EINTR)); |
4440 } while((rslt < 0) && (__threadErrno == EINTR)); |
4439 } |
4441 } |
4440 do { |
4442 do { |
4441 __threadErrno = 0; |
4443 __threadErrno = 0; |
4442 rslt = __STX_C_NOINT_CALL1("fclose", fclose, f); |
4444 rslt = __STX_C_NOINT_CALL1("fclose", fclose, f); |
4443 } while((rslt < 0) && (__threadErrno == EINTR)); |
4445 } while((rslt < 0) && (__threadErrno == EINTR)); |
4444 #else |
4446 #else |
4445 __BEGIN_INTERRUPTABLE__ |
4447 __BEGIN_INTERRUPTABLE__ |
4446 rslt = fclose(f); |
4448 rslt = fclose(f); |
4447 __END_INTERRUPTABLE__ |
4449 __END_INTERRUPTABLE__ |
4448 #endif |
4450 #endif |
4449 if (rslt < 0) { |
4451 if (rslt < 0) { |
4450 error = __mkSmallInteger(__threadErrno); |
4452 error = __mkSmallInteger(__threadErrno); |
4451 goto out; |
4453 goto out; |
4452 } |
4454 } |
4453 __INST(handle) = nil; |
4455 } |
4454 } |
4456 RETURN (self); |
4455 RETURN (self); |
|
4456 } |
4457 } |
4457 out:; |
4458 out:; |
4458 %}. |
4459 %}. |
4459 |
4460 |
4460 error notNil ifTrue:[ |
4461 error notNil ifTrue:[ |
4461 self primitiveFailed. |
4462 error == #errorNotOpen ifTrue:[ |
4462 ^ self. |
4463 self errorNotOpen. |
|
4464 ]. |
|
4465 error isInteger ifTrue:[ |
|
4466 lastErrorNumber := error. |
|
4467 self writeError:error. |
|
4468 ^ self. |
|
4469 ]. |
|
4470 self primitiveFailed:error. |
|
4471 ^ self. |
4463 ]. |
4472 ]. |
4464 |
4473 |
4465 "/ fallback for rel5 |
4474 "/ fallback for rel5 |
4466 |
4475 |
4467 fp := handle. |
4476 fp := handle. |
4468 fp notNil ifTrue:[ |
4477 fp notNil ifTrue:[ |
4469 handle := nil. |
4478 handle := nil. |
4470 self closeFile:fp |
4479 self closeFile:fp |
4471 ] |
4480 ] |
4472 ! |
4481 ! ! |
|
4482 |
|
4483 !ExternalStream methodsFor:'private'! |
4473 |
4484 |
4474 closeFile:handle |
4485 closeFile:handle |
4475 "for rel5 only" |
4486 "for rel5 only" |
4476 |
4487 |
4477 self primitiveFailed |
4488 self primitiveFailed |