diff --git a/flang/runtime/file.h b/flang/runtime/file.h --- a/flang/runtime/file.h +++ b/flang/runtime/file.h @@ -95,5 +95,9 @@ }; bool IsATerminal(int fd); +bool IsExtant(const char *path); +bool MayRead(const char *path); +bool MayWrite(const char *path); +bool MayReadAndWrite(const char *path); } // namespace Fortran::runtime::io #endif // FORTRAN_RUNTIME_FILE_H_ diff --git a/flang/runtime/file.cpp b/flang/runtime/file.cpp --- a/flang/runtime/file.cpp +++ b/flang/runtime/file.cpp @@ -18,6 +18,7 @@ #include #include #else +#include #include #endif @@ -84,8 +85,7 @@ fd_ = openfile_mkstemp(handler); } else { if (!path_.get()) { - handler.SignalError( - "FILE= is required unless STATUS='OLD' and unit is connected"); + handler.SignalError("FILE= is required"); return; } int flags{0}; @@ -134,8 +134,18 @@ mayWrite_ = *action != Action::Read; if (status == OpenStatus::Old || status == OpenStatus::Unknown) { knownSize_.reset(); +#ifndef _WIN32 + struct stat buf; + if (::fstat(fd_, &buf) == 0) { + mayPosition_ = S_ISREG(buf.st_mode); + knownSize_ = buf.st_size; + } +#else // TODO: _WIN32 + mayPosition_ = true; +#endif } else { knownSize_ = 0; + mayPosition_ = true; } } @@ -385,4 +395,11 @@ } bool IsATerminal(int fd) { return ::isatty(fd); } + +bool IsExtant(const char *path) { return ::access(path, F_OK) == 0; } +bool MayRead(const char *path) { return ::access(path, R_OK) == 0; } +bool MayWrite(const char *path) { return ::access(path, W_OK) == 0; } +bool MayReadAndWrite(const char *path) { + return ::access(path, R_OK | W_OK) == 0; +} } // namespace Fortran::runtime::io