IostatCannotReposition,
IostatBadWaitId,
IostatTooManyAsyncOps,
+ IostatBadBackspaceUnit,
};
const char *IostatErrorString(int);
Cookie IONAME(BeginBackspace)(
ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {
Terminator terminator{sourceFile, sourceLine};
- ExternalFileUnit &unit{
- ExternalFileUnit::LookUpOrCrash(unitNumber, terminator)};
- return &unit.BeginIoStatement<ExternalMiscIoStatementState>(
- unit, ExternalMiscIoStatementState::Backspace, sourceFile, sourceLine);
+ if (ExternalFileUnit * unit{ExternalFileUnit::LookUp(unitNumber)}) {
+ return &unit->BeginIoStatement<ExternalMiscIoStatementState>(
+ *unit, ExternalMiscIoStatementState::Backspace, sourceFile, sourceLine);
+ } else {
+ auto &io{
+ New<NoopStatementState>{terminator}(sourceFile, sourceLine, unitNumber)
+ .release()
+ ->ioStatementState()};
+ io.GetIoErrorHandler().SetPendingError(IostatBadBackspaceUnit);
+ return &io;
+ }
}
Cookie IONAME(BeginEndfile)(
}
void NoUnitIoStatementState::CompleteOperation() {
+ SignalPendingError();
IoStatementBase::CompleteOperation();
}
CloseStatus status_{CloseStatus::Keep};
};
-// For CLOSE(bad unit), WAIT(bad unit, ID=nonzero) and INQUIRE(unconnected unit)
+// For CLOSE(bad unit), WAIT(bad unit, ID=nonzero), INQUIRE(unconnected unit),
+// and recoverable BACKSPACE(bad unit)
class NoUnitIoStatementState : public IoStatementBase {
public:
IoStatementState &ioStatementState() { return ioStatementState_; }
return "WAIT(ID=nonzero) for an ID value that is not a pending operation";
case IostatTooManyAsyncOps:
return "Too many asynchronous operations pending on unit";
+ case IostatBadBackspaceUnit:
+ return "BACKSPACE on unconnected unit";
default:
return nullptr;
}
return GetUnitMap().LookUp(unit);
}
-ExternalFileUnit &ExternalFileUnit::LookUpOrCrash(
- int unit, const Terminator &terminator) {
- ExternalFileUnit *file{LookUp(unit)};
- if (!file) {
- terminator.Crash("%d is not an open I/O unit number", unit);
- }
- return *file;
-}
-
ExternalFileUnit &ExternalFileUnit::LookUpOrCreate(
int unit, const Terminator &terminator, bool &wasExtant) {
return GetUnitMap().LookUpOrCreate(unit, terminator, wasExtant);
bool createdForInternalChildIo() const { return createdForInternalChildIo_; }
static ExternalFileUnit *LookUp(int unit);
- static ExternalFileUnit &LookUpOrCrash(int unit, const Terminator &);
static ExternalFileUnit &LookUpOrCreate(
int unit, const Terminator &, bool &wasExtant);
static ExternalFileUnit &LookUpOrCreateAnonymous(int unit, Direction,