1 //===-- 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 #ifndef LLDB_HOST_FILE_H 10 #define LLDB_HOST_FILE_H 11 12 #include "lldb/Host/PosixApi.h" 13 #include "lldb/Utility/IOObject.h" 14 #include "lldb/Utility/Status.h" 15 #include "lldb/lldb-private.h" 16 #include "llvm/ADT/BitmaskEnum.h" 17 18 #include <mutex> 19 #include <stdarg.h> 20 #include <stdio.h> 21 #include <sys/types.h> 22 23 namespace lldb_private { 24 25 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); 26 27 /// \class File File.h "lldb/Host/File.h" 28 /// An abstract base class for files. 29 /// 30 /// Files will often be NativeFiles, which provides a wrapper 31 /// around host OS file functionality. But it 32 /// is also possible to subclass file to provide objects that have file 33 /// or stream functionality but are not backed by any host OS file. 34 class File : public IOObject { 35 public: 36 static int kInvalidDescriptor; 37 static FILE *kInvalidStream; 38 39 // NB this enum is used in the lldb platform gdb-remote packet 40 // vFile:open: and existing values cannot be modified. 41 // 42 // FIXME 43 // These values do not match the values used by GDB 44 // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags 45 // * rdar://problem/46788934 46 enum OpenOptions : uint32_t { 47 eOpenOptionRead = (1u << 0), // Open file for reading 48 eOpenOptionWrite = (1u << 1), // Open file for writing 49 eOpenOptionAppend = 50 (1u << 2), // Don't truncate file when opening, append to end of file 51 eOpenOptionTruncate = (1u << 3), // Truncate file when opening 52 eOpenOptionNonBlocking = (1u << 4), // File reads 53 eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist 54 eOpenOptionCanCreateNewOnly = 55 (1u << 6), // Can create file only if it doesn't already exist 56 eOpenOptionDontFollowSymlinks = (1u << 7), 57 eOpenOptionCloseOnExec = 58 (1u << 8), // Close the file when executing a new process 59 LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionCloseOnExec) 60 }; 61 62 static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options); 63 static llvm::Expected<OpenOptions> GetOptionsFromMode(llvm::StringRef mode); DescriptorIsValid(int descriptor)64 static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; }; 65 static llvm::Expected<const char *> 66 GetStreamOpenModeFromOptions(OpenOptions options); 67 File()68 File() 69 : IOObject(eFDTypeFile), m_is_interactive(eLazyBoolCalculate), 70 m_is_real_terminal(eLazyBoolCalculate), 71 m_supports_colors(eLazyBoolCalculate){}; 72 73 /// Read bytes from a file from the current file position into buf. 74 /// 75 /// NOTE: This function is NOT thread safe. Use the read function 76 /// that takes an "off_t &offset" to ensure correct operation in multi- 77 /// threaded environments. 78 /// 79 /// \param[in,out] num_bytes 80 /// Pass in the size of buf. Read will pass out the number 81 /// of bytes read. Zero bytes read with no error indicates 82 /// EOF. 83 /// 84 /// \return 85 /// success, ENOTSUP, or another error. 86 Status Read(void *buf, size_t &num_bytes) override; 87 88 /// Write bytes from buf to a file at the current file position. 89 /// 90 /// NOTE: This function is NOT thread safe. Use the write function 91 /// that takes an "off_t &offset" to ensure correct operation in multi- 92 /// threaded environments. 93 /// 94 /// \param[in,out] num_bytes 95 /// Pass in the size of buf. Write will pass out the number 96 /// of bytes written. Write will attempt write the full number 97 /// of bytes and will not return early except on error. 98 /// 99 /// \return 100 /// success, ENOTSUP, or another error. 101 Status Write(const void *buf, size_t &num_bytes) override; 102 103 /// IsValid 104 /// 105 /// \return 106 /// true iff the file is valid. 107 bool IsValid() const override; 108 109 /// Flush any buffers and release any resources owned by the file. 110 /// After Close() the file will be invalid. 111 /// 112 /// \return 113 /// success or an error. 114 Status Close() override; 115 116 /// Get a handle that can be used for OS polling interfaces, such 117 /// as WaitForMultipleObjects, select, or epoll. This may return 118 /// IOObject::kInvalidHandleValue if none is available. This will 119 /// generally be the same as the file descriptor, this function 120 /// is not interchangeable with GetDescriptor(). A WaitableHandle 121 /// must only be used for polling, not actual I/O. 122 /// 123 /// \return 124 /// a valid handle or IOObject::kInvalidHandleValue 125 WaitableHandle GetWaitableHandle() override; 126 127 /// Get the file specification for this file, if possible. 128 /// 129 /// \param[out] file_spec 130 /// the file specification. 131 /// \return 132 /// ENOTSUP, success, or another error. 133 virtual Status GetFileSpec(FileSpec &file_spec) const; 134 135 /// Get underlying OS file descriptor for this file, or kInvalidDescriptor. 136 /// If the descriptor is valid, then it may be used directly for I/O 137 /// However, the File may also perform it's own buffering, so avoid using 138 /// this if it is not necessary, or use Flush() appropriately. 139 /// 140 /// \return 141 /// a valid file descriptor for this file or kInvalidDescriptor 142 virtual int GetDescriptor() const; 143 144 /// Get the underlying libc stream for this file, or NULL. 145 /// 146 /// Not all valid files will have a FILE* stream. This should only be 147 /// used if absolutely necessary, such as to interact with 3rd party 148 /// libraries that need FILE* streams. 149 /// 150 /// \return 151 /// a valid stream or NULL; 152 virtual FILE *GetStream(); 153 154 /// Seek to an offset relative to the beginning of the file. 155 /// 156 /// NOTE: This function is NOT thread safe, other threads that 157 /// access this object might also change the current file position. For 158 /// thread safe reads and writes see the following functions: @see 159 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 160 /// size_t, off_t &) 161 /// 162 /// \param[in] offset 163 /// The offset to seek to within the file relative to the 164 /// beginning of the file. 165 /// 166 /// \param[in] error_ptr 167 /// A pointer to a lldb_private::Status object that will be 168 /// filled in if non-nullptr. 169 /// 170 /// \return 171 /// The resulting seek offset, or -1 on error. 172 virtual off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr); 173 174 /// Seek to an offset relative to the current file position. 175 /// 176 /// NOTE: This function is NOT thread safe, other threads that 177 /// access this object might also change the current file position. For 178 /// thread safe reads and writes see the following functions: @see 179 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 180 /// size_t, off_t &) 181 /// 182 /// \param[in] offset 183 /// The offset to seek to within the file relative to the 184 /// current file position. 185 /// 186 /// \param[in] error_ptr 187 /// A pointer to a lldb_private::Status object that will be 188 /// filled in if non-nullptr. 189 /// 190 /// \return 191 /// The resulting seek offset, or -1 on error. 192 virtual off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr); 193 194 /// Seek to an offset relative to the end of the file. 195 /// 196 /// NOTE: This function is NOT thread safe, other threads that 197 /// access this object might also change the current file position. For 198 /// thread safe reads and writes see the following functions: @see 199 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 200 /// size_t, off_t &) 201 /// 202 /// \param[in,out] offset 203 /// The offset to seek to within the file relative to the 204 /// end of the file which gets filled in with the resulting 205 /// absolute file offset. 206 /// 207 /// \param[in] error_ptr 208 /// A pointer to a lldb_private::Status object that will be 209 /// filled in if non-nullptr. 210 /// 211 /// \return 212 /// The resulting seek offset, or -1 on error. 213 virtual off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr); 214 215 /// Read bytes from a file from the specified file offset. 216 /// 217 /// NOTE: This function is thread safe in that clients manager their 218 /// own file position markers and reads on other threads won't mess up the 219 /// current read. 220 /// 221 /// \param[in] dst 222 /// A buffer where to put the bytes that are read. 223 /// 224 /// \param[in,out] num_bytes 225 /// The number of bytes to read form the current file position 226 /// which gets modified with the number of bytes that were read. 227 /// 228 /// \param[in,out] offset 229 /// The offset within the file from which to read \a num_bytes 230 /// bytes. This offset gets incremented by the number of bytes 231 /// that were read. 232 /// 233 /// \return 234 /// An error object that indicates success or the reason for 235 /// failure. 236 virtual Status Read(void *dst, size_t &num_bytes, off_t &offset); 237 238 /// Write bytes to a file at the specified file offset. 239 /// 240 /// NOTE: This function is thread safe in that clients manager their 241 /// own file position markers, though clients will need to implement their 242 /// own locking externally to avoid multiple people writing to the file at 243 /// the same time. 244 /// 245 /// \param[in] src 246 /// A buffer containing the bytes to write. 247 /// 248 /// \param[in,out] num_bytes 249 /// The number of bytes to write to the file at offset \a offset. 250 /// \a num_bytes gets modified with the number of bytes that 251 /// were read. 252 /// 253 /// \param[in,out] offset 254 /// The offset within the file at which to write \a num_bytes 255 /// bytes. This offset gets incremented by the number of bytes 256 /// that were written. 257 /// 258 /// \return 259 /// An error object that indicates success or the reason for 260 /// failure. 261 virtual Status Write(const void *src, size_t &num_bytes, off_t &offset); 262 263 /// Flush the current stream 264 /// 265 /// \return 266 /// An error object that indicates success or the reason for 267 /// failure. 268 virtual Status Flush(); 269 270 /// Sync to disk. 271 /// 272 /// \return 273 /// An error object that indicates success or the reason for 274 /// failure. 275 virtual Status Sync(); 276 277 /// Output printf formatted output to the stream. 278 /// 279 /// NOTE: this is not virtual, because it just calls the va_list 280 /// version of the function. 281 /// 282 /// Print some formatted output to the stream. 283 /// 284 /// \param[in] format 285 /// A printf style format string. 286 /// 287 /// \param[in] ... 288 /// Variable arguments that are needed for the printf style 289 /// format string \a format. 290 size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); 291 292 /// Output printf formatted output to the stream. 293 /// 294 /// Print some formatted output to the stream. 295 /// 296 /// \param[in] format 297 /// A printf style format string. 298 /// 299 /// \param[in] args 300 /// Variable arguments that are needed for the printf style 301 /// format string \a format. 302 virtual size_t PrintfVarArg(const char *format, va_list args); 303 304 /// Return the OpenOptions for this file. 305 /// 306 /// Some options like eOpenOptionDontFollowSymlinks only make 307 /// sense when a file is being opened (or not at all) 308 /// and may not be preserved for this method. But any valid 309 /// File should return either or both of eOpenOptionRead and 310 /// eOpenOptionWrite here. 311 /// 312 /// \return 313 /// OpenOptions flags for this file, or an error. 314 virtual llvm::Expected<OpenOptions> GetOptions() const; 315 GetOpenMode()316 llvm::Expected<const char *> GetOpenMode() const { 317 auto opts = GetOptions(); 318 if (!opts) 319 return opts.takeError(); 320 return GetStreamOpenModeFromOptions(opts.get()); 321 } 322 323 /// Get the permissions for a this file. 324 /// 325 /// \return 326 /// Bits logical OR'ed together from the permission bits defined 327 /// in lldb_private::File::Permissions. 328 uint32_t GetPermissions(Status &error) const; 329 330 /// Return true if this file is interactive. 331 /// 332 /// \return 333 /// True if this file is a terminal (tty or pty), false 334 /// otherwise. 335 bool GetIsInteractive(); 336 337 /// Return true if this file from a real terminal. 338 /// 339 /// Just knowing a file is a interactive isn't enough, we also need to know 340 /// if the terminal has a width and height so we can do cursor movement and 341 /// other terminal manipulations by sending escape sequences. 342 /// 343 /// \return 344 /// True if this file is a terminal (tty, not a pty) that has 345 /// a non-zero width and height, false otherwise. 346 bool GetIsRealTerminal(); 347 348 /// Return true if this file is a terminal which supports colors. 349 /// 350 /// \return 351 /// True iff this is a terminal and it supports colors. 352 bool GetIsTerminalWithColors(); 353 354 operator bool() const { return IsValid(); }; 355 356 bool operator!() const { return !IsValid(); }; 357 358 static char ID; isA(const void * classID)359 virtual bool isA(const void *classID) const { return classID == &ID; } classof(const File * file)360 static bool classof(const File *file) { return file->isA(&ID); } 361 362 protected: 363 LazyBool m_is_interactive; 364 LazyBool m_is_real_terminal; 365 LazyBool m_supports_colors; 366 367 void CalculateInteractiveAndTerminal(); 368 369 private: 370 File(const File &) = delete; 371 const File &operator=(const File &) = delete; 372 }; 373 374 class NativeFile : public File { 375 public: NativeFile()376 NativeFile() 377 : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), 378 m_stream(kInvalidStream), m_options(), m_own_stream(false) {} 379 NativeFile(FILE * fh,bool transfer_ownership)380 NativeFile(FILE *fh, bool transfer_ownership) 381 : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh), 382 m_options(), m_own_stream(transfer_ownership) {} 383 NativeFile(int fd,OpenOptions options,bool transfer_ownership)384 NativeFile(int fd, OpenOptions options, bool transfer_ownership) 385 : m_descriptor(fd), m_own_descriptor(transfer_ownership), 386 m_stream(kInvalidStream), m_options(options), m_own_stream(false) {} 387 ~NativeFile()388 ~NativeFile() override { Close(); } 389 IsValid()390 bool IsValid() const override { 391 return DescriptorIsValid() || StreamIsValid(); 392 } 393 394 Status Read(void *buf, size_t &num_bytes) override; 395 Status Write(const void *buf, size_t &num_bytes) override; 396 Status Close() override; 397 WaitableHandle GetWaitableHandle() override; 398 Status GetFileSpec(FileSpec &file_spec) const override; 399 int GetDescriptor() const override; 400 FILE *GetStream() override; 401 off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr) override; 402 off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr) override; 403 off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr) override; 404 Status Read(void *dst, size_t &num_bytes, off_t &offset) override; 405 Status Write(const void *src, size_t &num_bytes, off_t &offset) override; 406 Status Flush() override; 407 Status Sync() override; 408 size_t PrintfVarArg(const char *format, va_list args) override; 409 llvm::Expected<OpenOptions> GetOptions() const override; 410 411 static char ID; isA(const void * classID)412 virtual bool isA(const void *classID) const override { 413 return classID == &ID || File::isA(classID); 414 } classof(const File * file)415 static bool classof(const File *file) { return file->isA(&ID); } 416 417 protected: DescriptorIsValid()418 bool DescriptorIsValid() const { 419 return File::DescriptorIsValid(m_descriptor); 420 } StreamIsValid()421 bool StreamIsValid() const { return m_stream != kInvalidStream; } 422 423 // Member variables 424 int m_descriptor; 425 bool m_own_descriptor; 426 FILE *m_stream; 427 OpenOptions m_options; 428 bool m_own_stream; 429 std::mutex offset_access_mutex; 430 431 private: 432 NativeFile(const NativeFile &) = delete; 433 const NativeFile &operator=(const NativeFile &) = delete; 434 }; 435 436 } // namespace lldb_private 437 438 #endif // LLDB_HOST_FILE_H 439