1 //===-- runtime/file.h ------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // Raw system I/O wrappers 10 11 #ifndef FORTRAN_RUNTIME_FILE_H_ 12 #define FORTRAN_RUNTIME_FILE_H_ 13 14 #include "io-error.h" 15 #include "flang/Common/optional.h" 16 #include "flang/Runtime/memory.h" 17 #include <cinttypes> 18 19 namespace Fortran::runtime::io { 20 21 enum class OpenStatus { Old, New, Scratch, Replace, Unknown }; 22 enum class CloseStatus { Keep, Delete }; 23 enum class Position { AsIs, Rewind, Append }; 24 enum class Action { Read, Write, ReadWrite }; 25 26 class OpenFile { 27 public: 28 using FileOffset = std::int64_t; 29 path()30 const char *path() const { return path_.get(); } pathLength()31 std::size_t pathLength() const { return pathLength_; } 32 void set_path(OwningPtr<char> &&, std::size_t bytes); mayRead()33 bool mayRead() const { return mayRead_; } mayWrite()34 bool mayWrite() const { return mayWrite_; } mayPosition()35 bool mayPosition() const { return mayPosition_; } mayAsynchronous()36 bool mayAsynchronous() const { return mayAsynchronous_; } set_mayAsynchronous(bool yes)37 void set_mayAsynchronous(bool yes) { mayAsynchronous_ = yes; } isTerminal()38 bool isTerminal() const { return isTerminal_; } isWindowsTextFile()39 bool isWindowsTextFile() const { return isWindowsTextFile_; } knownSize()40 Fortran::common::optional<FileOffset> knownSize() const { return knownSize_; } 41 IsConnected()42 bool IsConnected() const { return fd_ >= 0; } 43 void Open(OpenStatus, Fortran::common::optional<Action>, Position, 44 IoErrorHandler &); 45 void Predefine(int fd); 46 void Close(CloseStatus, IoErrorHandler &); 47 48 // Reads data into memory; returns amount acquired. Synchronous. 49 // Partial reads (less than minBytes) signify end-of-file. If the 50 // buffer is larger than minBytes, and extra returned data will be 51 // preserved for future consumption, set maxBytes larger than minBytes 52 // to reduce system calls This routine handles EAGAIN/EWOULDBLOCK and EINTR. 53 std::size_t Read(FileOffset, char *, std::size_t minBytes, 54 std::size_t maxBytes, IoErrorHandler &); 55 56 // Writes data. Synchronous. Partial writes indicate program-handled 57 // error conditions. 58 std::size_t Write(FileOffset, const char *, std::size_t, IoErrorHandler &); 59 60 // Truncates the file 61 void Truncate(FileOffset, IoErrorHandler &); 62 63 // Asynchronous transfers 64 int ReadAsynchronously(FileOffset, char *, std::size_t, IoErrorHandler &); 65 int WriteAsynchronously( 66 FileOffset, const char *, std::size_t, IoErrorHandler &); 67 void Wait(int id, IoErrorHandler &); 68 void WaitAll(IoErrorHandler &); 69 70 // INQUIRE(POSITION=) 71 Position InquirePosition() const; 72 73 private: 74 struct Pending { 75 int id; 76 int ioStat{0}; 77 OwningPtr<Pending> next; 78 }; 79 80 void CheckOpen(const Terminator &); 81 bool Seek(FileOffset, IoErrorHandler &); 82 bool RawSeek(FileOffset); 83 bool RawSeekToEnd(); 84 int PendingResult(const Terminator &, int); SetPosition(FileOffset pos)85 void SetPosition(FileOffset pos) { 86 position_ = pos; 87 openPosition_.reset(); 88 } 89 void CloseFd(IoErrorHandler &); 90 91 int fd_{-1}; 92 OwningPtr<char> path_; 93 std::size_t pathLength_; 94 bool mayRead_{false}; 95 bool mayWrite_{false}; 96 bool mayPosition_{false}; 97 bool mayAsynchronous_{false}; 98 Fortran::common::optional<Position> 99 openPosition_; // from Open(); reset after positioning 100 FileOffset position_{0}; 101 Fortran::common::optional<FileOffset> knownSize_; 102 bool isTerminal_{false}; 103 bool isWindowsTextFile_{false}; // expands LF to CR+LF on write 104 105 int nextId_; 106 OwningPtr<Pending> pending_; 107 }; 108 109 RT_API_ATTRS bool IsATerminal(int fd); 110 RT_API_ATTRS bool IsExtant(const char *path); 111 RT_API_ATTRS bool MayRead(const char *path); 112 RT_API_ATTRS bool MayWrite(const char *path); 113 RT_API_ATTRS bool MayReadAndWrite(const char *path); 114 RT_API_ATTRS std::int64_t SizeInBytes(const char *path); 115 } // namespace Fortran::runtime::io 116 #endif // FORTRAN_RUNTIME_FILE_H_ 117