Back to home page

EIC code displayed by LXR

 
 

    


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