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