|
|
|||
File indexing completed on 2026-05-10 08:42:48
0001 //===-- File.h --------------------------------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLDB_HOST_FILE_H 0010 #define LLDB_HOST_FILE_H 0011 0012 #include "lldb/Host/PosixApi.h" 0013 #include "lldb/Host/Terminal.h" 0014 #include "lldb/Utility/IOObject.h" 0015 #include "lldb/Utility/Status.h" 0016 #include "lldb/lldb-private.h" 0017 #include "llvm/ADT/BitmaskEnum.h" 0018 0019 #include <cstdarg> 0020 #include <cstdio> 0021 #include <mutex> 0022 #include <optional> 0023 #include <sys/types.h> 0024 0025 namespace lldb_private { 0026 0027 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); 0028 0029 /// \class File File.h "lldb/Host/File.h" 0030 /// An abstract base class for files. 0031 /// 0032 /// Files will often be NativeFiles, which provides a wrapper 0033 /// around host OS file functionality. But it 0034 /// is also possible to subclass file to provide objects that have file 0035 /// or stream functionality but are not backed by any host OS file. 0036 class File : public IOObject { 0037 public: 0038 static int kInvalidDescriptor; 0039 static FILE *kInvalidStream; 0040 0041 // NB this enum is used in the lldb platform gdb-remote packet 0042 // vFile:open: and existing values cannot be modified. 0043 // 0044 // The first set of values is defined by gdb headers and can be found 0045 // in the documentation at: 0046 // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags 0047 // 0048 // The second half are LLDB extensions and use the highest uint32_t bits 0049 // to avoid risk of collisions with future gdb remote protocol changes. 0050 enum OpenOptions : uint32_t { 0051 eOpenOptionReadOnly = 0x0, // Open file for reading (only) 0052 eOpenOptionWriteOnly = 0x1, // Open file for writing (only) 0053 eOpenOptionReadWrite = 0x2, // Open file for both reading and writing 0054 eOpenOptionAppend = 0055 0x8, // Don't truncate file when opening, append to end of file 0056 eOpenOptionCanCreate = 0x200, // Create file if doesn't already exist 0057 eOpenOptionTruncate = 0x400, // Truncate file when opening 0058 eOpenOptionCanCreateNewOnly = 0059 0x800, // Can create file only if it doesn't already exist 0060 0061 eOpenOptionNonBlocking = (1u << 28), // File reads 0062 eOpenOptionDontFollowSymlinks = (1u << 29), 0063 eOpenOptionCloseOnExec = 0064 (1u << 30), // Close the file when executing a new process 0065 eOpenOptionInvalid = (1u << 31), // Used as invalid value 0066 LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionInvalid) 0067 }; 0068 0069 static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options); 0070 static llvm::Expected<OpenOptions> GetOptionsFromMode(llvm::StringRef mode); 0071 static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; }; 0072 static llvm::Expected<const char *> 0073 GetStreamOpenModeFromOptions(OpenOptions options); 0074 0075 File() : IOObject(eFDTypeFile){}; 0076 0077 /// Read bytes from a file from the current file position into buf. 0078 /// 0079 /// NOTE: This function is NOT thread safe. Use the read function 0080 /// that takes an "off_t &offset" to ensure correct operation in multi- 0081 /// threaded environments. 0082 /// 0083 /// \param[in,out] num_bytes 0084 /// Pass in the size of buf. Read will pass out the number 0085 /// of bytes read. Zero bytes read with no error indicates 0086 /// EOF. 0087 /// 0088 /// \return 0089 /// success, ENOTSUP, or another error. 0090 Status Read(void *buf, size_t &num_bytes) override; 0091 0092 /// Write bytes from buf to a file at the current file position. 0093 /// 0094 /// NOTE: This function is NOT thread safe. Use the write function 0095 /// that takes an "off_t &offset" to ensure correct operation in multi- 0096 /// threaded environments. 0097 /// 0098 /// \param[in,out] num_bytes 0099 /// Pass in the size of buf. Write will pass out the number 0100 /// of bytes written. Write will attempt write the full number 0101 /// of bytes and will not return early except on error. 0102 /// 0103 /// \return 0104 /// success, ENOTSUP, or another error. 0105 Status Write(const void *buf, size_t &num_bytes) override; 0106 0107 /// IsValid 0108 /// 0109 /// \return 0110 /// true iff the file is valid. 0111 bool IsValid() const override; 0112 0113 /// Flush any buffers and release any resources owned by the file. 0114 /// After Close() the file will be invalid. 0115 /// 0116 /// \return 0117 /// success or an error. 0118 Status Close() override; 0119 0120 /// Get a handle that can be used for OS polling interfaces, such 0121 /// as WaitForMultipleObjects, select, or epoll. This may return 0122 /// IOObject::kInvalidHandleValue if none is available. This will 0123 /// generally be the same as the file descriptor, this function 0124 /// is not interchangeable with GetDescriptor(). A WaitableHandle 0125 /// must only be used for polling, not actual I/O. 0126 /// 0127 /// \return 0128 /// a valid handle or IOObject::kInvalidHandleValue 0129 WaitableHandle GetWaitableHandle() override; 0130 0131 /// Get the file specification for this file, if possible. 0132 /// 0133 /// \param[out] file_spec 0134 /// the file specification. 0135 /// \return 0136 /// ENOTSUP, success, or another error. 0137 virtual Status GetFileSpec(FileSpec &file_spec) const; 0138 0139 /// Get underlying OS file descriptor for this file, or kInvalidDescriptor. 0140 /// If the descriptor is valid, then it may be used directly for I/O 0141 /// However, the File may also perform it's own buffering, so avoid using 0142 /// this if it is not necessary, or use Flush() appropriately. 0143 /// 0144 /// \return 0145 /// a valid file descriptor for this file or kInvalidDescriptor 0146 virtual int GetDescriptor() const; 0147 0148 /// Get the underlying libc stream for this file, or NULL. 0149 /// 0150 /// Not all valid files will have a FILE* stream. This should only be 0151 /// used if absolutely necessary, such as to interact with 3rd party 0152 /// libraries that need FILE* streams. 0153 /// 0154 /// \return 0155 /// a valid stream or NULL; 0156 virtual FILE *GetStream(); 0157 0158 /// Seek to an offset relative to the beginning of the file. 0159 /// 0160 /// NOTE: This function is NOT thread safe, other threads that 0161 /// access this object might also change the current file position. For 0162 /// thread safe reads and writes see the following functions: @see 0163 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 0164 /// size_t, off_t &) 0165 /// 0166 /// \param[in] offset 0167 /// The offset to seek to within the file relative to the 0168 /// beginning of the file. 0169 /// 0170 /// \param[in] error_ptr 0171 /// A pointer to a lldb_private::Status object that will be 0172 /// filled in if non-nullptr. 0173 /// 0174 /// \return 0175 /// The resulting seek offset, or -1 on error. 0176 virtual off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr); 0177 0178 /// Seek to an offset relative to the current file position. 0179 /// 0180 /// NOTE: This function is NOT thread safe, other threads that 0181 /// access this object might also change the current file position. For 0182 /// thread safe reads and writes see the following functions: @see 0183 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 0184 /// size_t, off_t &) 0185 /// 0186 /// \param[in] offset 0187 /// The offset to seek to within the file relative to the 0188 /// current file position. 0189 /// 0190 /// \param[in] error_ptr 0191 /// A pointer to a lldb_private::Status object that will be 0192 /// filled in if non-nullptr. 0193 /// 0194 /// \return 0195 /// The resulting seek offset, or -1 on error. 0196 virtual off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr); 0197 0198 /// Seek to an offset relative to the end of the file. 0199 /// 0200 /// NOTE: This function is NOT thread safe, other threads that 0201 /// access this object might also change the current file position. For 0202 /// thread safe reads and writes see the following functions: @see 0203 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 0204 /// size_t, off_t &) 0205 /// 0206 /// \param[in,out] offset 0207 /// The offset to seek to within the file relative to the 0208 /// end of the file which gets filled in with the resulting 0209 /// absolute file offset. 0210 /// 0211 /// \param[in] error_ptr 0212 /// A pointer to a lldb_private::Status object that will be 0213 /// filled in if non-nullptr. 0214 /// 0215 /// \return 0216 /// The resulting seek offset, or -1 on error. 0217 virtual off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr); 0218 0219 /// Read bytes from a file from the specified file offset. 0220 /// 0221 /// NOTE: This function is thread safe in that clients manager their 0222 /// own file position markers and reads on other threads won't mess up the 0223 /// current read. 0224 /// 0225 /// \param[in] dst 0226 /// A buffer where to put the bytes that are read. 0227 /// 0228 /// \param[in,out] num_bytes 0229 /// The number of bytes to read from the current file position 0230 /// which gets modified with the number of bytes that were read. 0231 /// 0232 /// \param[in,out] offset 0233 /// The offset within the file from which to read \a num_bytes 0234 /// bytes. This offset gets incremented by the number of bytes 0235 /// that were read. 0236 /// 0237 /// \return 0238 /// An error object that indicates success or the reason for 0239 /// failure. 0240 virtual Status Read(void *dst, size_t &num_bytes, off_t &offset); 0241 0242 /// Write bytes to a file at the specified file offset. 0243 /// 0244 /// NOTE: This function is thread safe in that clients manager their 0245 /// own file position markers, though clients will need to implement their 0246 /// own locking externally to avoid multiple people writing to the file at 0247 /// the same time. 0248 /// 0249 /// \param[in] src 0250 /// A buffer containing the bytes to write. 0251 /// 0252 /// \param[in,out] num_bytes 0253 /// The number of bytes to write to the file at offset \a offset. 0254 /// \a num_bytes gets modified with the number of bytes that 0255 /// were read. 0256 /// 0257 /// \param[in,out] offset 0258 /// The offset within the file at which to write \a num_bytes 0259 /// bytes. This offset gets incremented by the number of bytes 0260 /// that were written. 0261 /// 0262 /// \return 0263 /// An error object that indicates success or the reason for 0264 /// failure. 0265 virtual Status Write(const void *src, size_t &num_bytes, off_t &offset); 0266 0267 /// Flush the current stream 0268 /// 0269 /// \return 0270 /// An error object that indicates success or the reason for 0271 /// failure. 0272 virtual Status Flush(); 0273 0274 /// Sync to disk. 0275 /// 0276 /// \return 0277 /// An error object that indicates success or the reason for 0278 /// failure. 0279 virtual Status Sync(); 0280 0281 /// Output printf formatted output to the stream. 0282 /// 0283 /// NOTE: this is not virtual, because it just calls the va_list 0284 /// version of the function. 0285 /// 0286 /// Print some formatted output to the stream. 0287 /// 0288 /// \param[in] format 0289 /// A printf style format string. 0290 /// 0291 /// \param[in] ... 0292 /// Variable arguments that are needed for the printf style 0293 /// format string \a format. 0294 size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); 0295 0296 /// Output printf formatted output to the stream. 0297 /// 0298 /// Print some formatted output to the stream. 0299 /// 0300 /// \param[in] format 0301 /// A printf style format string. 0302 /// 0303 /// \param[in] args 0304 /// Variable arguments that are needed for the printf style 0305 /// format string \a format. 0306 virtual size_t PrintfVarArg(const char *format, va_list args); 0307 0308 /// Return the OpenOptions for this file. 0309 /// 0310 /// Some options like eOpenOptionDontFollowSymlinks only make 0311 /// sense when a file is being opened (or not at all) 0312 /// and may not be preserved for this method. But any valid 0313 /// File should return either eOpenOptionReadOnly, eOpenOptionWriteOnly 0314 /// or eOpenOptionReadWrite here. 0315 /// 0316 /// \return 0317 /// OpenOptions flags for this file, or an error. 0318 virtual llvm::Expected<OpenOptions> GetOptions() const; 0319 0320 llvm::Expected<const char *> GetOpenMode() const { 0321 auto opts = GetOptions(); 0322 if (!opts) 0323 return opts.takeError(); 0324 return GetStreamOpenModeFromOptions(opts.get()); 0325 } 0326 0327 /// Get the permissions for a this file. 0328 /// 0329 /// \return 0330 /// Bits logical OR'ed together from the permission bits defined 0331 /// in lldb_private::File::Permissions. 0332 uint32_t GetPermissions(Status &error) const; 0333 0334 /// Return true if this file is interactive. 0335 /// 0336 /// \return 0337 /// True if this file is a terminal (tty or pty), false 0338 /// otherwise. 0339 bool GetIsInteractive(); 0340 0341 /// Return true if this file from a real terminal. 0342 /// 0343 /// Just knowing a file is a interactive isn't enough, we also need to know 0344 /// if the terminal has a width and height so we can do cursor movement and 0345 /// other terminal manipulations by sending escape sequences. 0346 /// 0347 /// \return 0348 /// True if this file is a terminal (tty, not a pty) that has 0349 /// a non-zero width and height, false otherwise. 0350 bool GetIsRealTerminal(); 0351 0352 /// Return true if this file is a terminal which supports colors. 0353 /// 0354 /// \return 0355 /// True iff this is a terminal and it supports colors. 0356 bool GetIsTerminalWithColors(); 0357 0358 operator bool() const { return IsValid(); }; 0359 0360 bool operator!() const { return !IsValid(); }; 0361 0362 static char ID; 0363 virtual bool isA(const void *classID) const { return classID == &ID; } 0364 static bool classof(const File *file) { return file->isA(&ID); } 0365 0366 protected: 0367 LazyBool m_is_interactive = eLazyBoolCalculate; 0368 LazyBool m_is_real_terminal = eLazyBoolCalculate; 0369 LazyBool m_supports_colors = eLazyBoolCalculate; 0370 0371 void CalculateInteractiveAndTerminal(); 0372 0373 private: 0374 File(const File &) = delete; 0375 const File &operator=(const File &) = delete; 0376 }; 0377 0378 class NativeFile : public File { 0379 public: 0380 NativeFile() : m_descriptor(kInvalidDescriptor), m_stream(kInvalidStream) {} 0381 0382 NativeFile(FILE *fh, bool transfer_ownership) 0383 : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh), 0384 m_options(), m_own_stream(transfer_ownership) {} 0385 0386 NativeFile(int fd, OpenOptions options, bool transfer_ownership) 0387 : m_descriptor(fd), m_own_descriptor(transfer_ownership), 0388 m_stream(kInvalidStream), m_options(options), m_own_stream(false) {} 0389 0390 ~NativeFile() override { Close(); } 0391 0392 bool IsValid() const override; 0393 0394 Status Read(void *buf, size_t &num_bytes) override; 0395 Status Write(const void *buf, size_t &num_bytes) override; 0396 Status Close() override; 0397 WaitableHandle GetWaitableHandle() override; 0398 Status GetFileSpec(FileSpec &file_spec) const override; 0399 int GetDescriptor() const override; 0400 FILE *GetStream() override; 0401 off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr) override; 0402 off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr) override; 0403 off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr) override; 0404 Status Read(void *dst, size_t &num_bytes, off_t &offset) override; 0405 Status Write(const void *src, size_t &num_bytes, off_t &offset) override; 0406 Status Flush() override; 0407 Status Sync() override; 0408 size_t PrintfVarArg(const char *format, va_list args) override; 0409 llvm::Expected<OpenOptions> GetOptions() const override; 0410 0411 static char ID; 0412 bool isA(const void *classID) const override { 0413 return classID == &ID || File::isA(classID); 0414 } 0415 static bool classof(const File *file) { return file->isA(&ID); } 0416 0417 protected: 0418 struct ValueGuard { 0419 ValueGuard(std::mutex &m, bool b) : guard(m, std::adopt_lock), value(b) {} 0420 std::lock_guard<std::mutex> guard; 0421 bool value; 0422 operator bool() { return value; } 0423 }; 0424 0425 bool DescriptorIsValidUnlocked() const { 0426 0427 return File::DescriptorIsValid(m_descriptor); 0428 } 0429 0430 bool StreamIsValidUnlocked() const { return m_stream != kInvalidStream; } 0431 0432 ValueGuard DescriptorIsValid() const { 0433 m_descriptor_mutex.lock(); 0434 return ValueGuard(m_descriptor_mutex, DescriptorIsValidUnlocked()); 0435 } 0436 0437 ValueGuard StreamIsValid() const { 0438 m_stream_mutex.lock(); 0439 return ValueGuard(m_stream_mutex, StreamIsValidUnlocked()); 0440 } 0441 0442 int m_descriptor; 0443 bool m_own_descriptor = false; 0444 mutable std::mutex m_descriptor_mutex; 0445 0446 FILE *m_stream; 0447 mutable std::mutex m_stream_mutex; 0448 0449 OpenOptions m_options{}; 0450 bool m_own_stream = false; 0451 std::mutex offset_access_mutex; 0452 0453 private: 0454 NativeFile(const NativeFile &) = delete; 0455 const NativeFile &operator=(const NativeFile &) = delete; 0456 }; 0457 0458 class SerialPort : public NativeFile { 0459 public: 0460 struct Options { 0461 std::optional<unsigned int> BaudRate; 0462 std::optional<Terminal::Parity> Parity; 0463 std::optional<Terminal::ParityCheck> ParityCheck; 0464 std::optional<unsigned int> StopBits; 0465 }; 0466 0467 // Obtain Options corresponding to the passed URL query string 0468 // (i.e. the part after '?'). 0469 static llvm::Expected<Options> OptionsFromURL(llvm::StringRef urlqs); 0470 0471 static llvm::Expected<std::unique_ptr<SerialPort>> 0472 Create(int fd, OpenOptions options, Options serial_options, 0473 bool transfer_ownership); 0474 0475 bool IsValid() const override { 0476 return NativeFile::IsValid() && m_is_interactive == eLazyBoolYes; 0477 } 0478 0479 Status Close() override; 0480 0481 static char ID; 0482 bool isA(const void *classID) const override { 0483 return classID == &ID || File::isA(classID); 0484 } 0485 static bool classof(const File *file) { return file->isA(&ID); } 0486 0487 private: 0488 SerialPort(int fd, OpenOptions options, Options serial_options, 0489 bool transfer_ownership); 0490 0491 SerialPort(const SerialPort &) = delete; 0492 const SerialPort &operator=(const SerialPort &) = delete; 0493 0494 TerminalState m_state; 0495 }; 0496 0497 } // namespace lldb_private 0498 0499 #endif // LLDB_HOST_FILE_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|