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