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 liblldb_File_h_ 10 #define liblldb_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 17 #include <mutex> 18 #include <stdarg.h> 19 #include <stdio.h> 20 #include <sys/types.h> 21 22 namespace lldb_private { 23 24 /// \class File File.h "lldb/Host/File.h" 25 /// A file class. 26 /// 27 /// A file class that divides abstracts the LLDB core from host file 28 /// functionality. 29 class File : public IOObject { 30 public: 31 static int kInvalidDescriptor; 32 static FILE *kInvalidStream; 33 34 // NB this enum is used in the lldb platform gdb-remote packet 35 // vFile:open: and existing values cannot be modified. 36 enum OpenOptions { 37 eOpenOptionRead = (1u << 0), // Open file for reading 38 eOpenOptionWrite = (1u << 1), // Open file for writing 39 eOpenOptionAppend = 40 (1u << 2), // Don't truncate file when opening, append to end of file 41 eOpenOptionTruncate = (1u << 3), // Truncate file when opening 42 eOpenOptionNonBlocking = (1u << 4), // File reads 43 eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist 44 eOpenOptionCanCreateNewOnly = 45 (1u << 6), // Can create file only if it doesn't already exist 46 eOpenOptionDontFollowSymlinks = (1u << 7), 47 eOpenOptionCloseOnExec = 48 (1u << 8) // Close the file when executing a new process 49 }; 50 51 static mode_t ConvertOpenOptionsForPOSIXOpen(uint32_t open_options); 52 53 File() 54 : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor), 55 m_stream(kInvalidStream), m_options(0), m_own_stream(false), 56 m_is_interactive(eLazyBoolCalculate), 57 m_is_real_terminal(eLazyBoolCalculate), 58 m_supports_colors(eLazyBoolCalculate) {} 59 60 File(FILE *fh, bool transfer_ownership) 61 : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor), 62 m_stream(fh), m_options(0), m_own_stream(transfer_ownership), 63 m_is_interactive(eLazyBoolCalculate), 64 m_is_real_terminal(eLazyBoolCalculate), 65 m_supports_colors(eLazyBoolCalculate) {} 66 67 File(int fd, bool transfer_ownership) 68 : IOObject(eFDTypeFile, transfer_ownership), m_descriptor(fd), 69 m_stream(kInvalidStream), m_options(0), m_own_stream(false), 70 m_is_interactive(eLazyBoolCalculate), 71 m_is_real_terminal(eLazyBoolCalculate) {} 72 73 /// Destructor. 74 /// 75 /// The destructor is virtual in case this class is subclassed. 76 ~File() override; 77 78 bool IsValid() const override { 79 return DescriptorIsValid() || StreamIsValid(); 80 } 81 82 /// Convert to pointer operator. 83 /// 84 /// This allows code to check a File object to see if it contains anything 85 /// valid using code such as: 86 /// 87 /// \code 88 /// File file(...); 89 /// if (file) 90 /// { ... 91 /// \endcode 92 /// 93 /// \return 94 /// A pointer to this object if either the directory or filename 95 /// is valid, nullptr otherwise. 96 operator bool() const { return DescriptorIsValid() || StreamIsValid(); } 97 98 /// Logical NOT operator. 99 /// 100 /// This allows code to check a File object to see if it is invalid using 101 /// code such as: 102 /// 103 /// \code 104 /// File file(...); 105 /// if (!file) 106 /// { ... 107 /// \endcode 108 /// 109 /// \return 110 /// Returns \b true if the object has an empty directory and 111 /// filename, \b false otherwise. 112 bool operator!() const { return !DescriptorIsValid() && !StreamIsValid(); } 113 114 /// Get the file spec for this file. 115 /// 116 /// \return 117 /// A reference to the file specification object. 118 Status GetFileSpec(FileSpec &file_spec) const; 119 120 Status Close() override; 121 122 void Clear(); 123 124 int GetDescriptor() const; 125 126 WaitableHandle GetWaitableHandle() override; 127 128 void SetDescriptor(int fd, bool transfer_ownership); 129 130 FILE *GetStream(); 131 132 void SetStream(FILE *fh, bool transfer_ownership); 133 134 /// Read bytes from a file from the current file position. 135 /// 136 /// NOTE: This function is NOT thread safe. Use the read function 137 /// that takes an "off_t &offset" to ensure correct operation in multi- 138 /// threaded environments. 139 /// 140 /// \param[in] buf 141 /// A buffer where to put the bytes that are read. 142 /// 143 /// \param[in,out] num_bytes 144 /// The number of bytes to read form the current file position 145 /// which gets modified with the number of bytes that were read. 146 /// 147 /// \return 148 /// An error object that indicates success or the reason for 149 /// failure. 150 Status Read(void *buf, size_t &num_bytes) override; 151 152 /// Write bytes to a file at the current file position. 153 /// 154 /// NOTE: This function is NOT thread safe. Use the write function 155 /// that takes an "off_t &offset" to ensure correct operation in multi- 156 /// threaded environments. 157 /// 158 /// \param[in] buf 159 /// A buffer where to put the bytes that are read. 160 /// 161 /// \param[in,out] num_bytes 162 /// The number of bytes to write to the current file position 163 /// which gets modified with the number of bytes that were 164 /// written. 165 /// 166 /// \return 167 /// An error object that indicates success or the reason for 168 /// failure. 169 Status Write(const void *buf, size_t &num_bytes) override; 170 171 /// Seek to an offset relative to the beginning of the file. 172 /// 173 /// NOTE: This function is NOT thread safe, other threads that 174 /// access this object might also change the current file position. For 175 /// thread safe reads and writes see the following functions: @see 176 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 177 /// size_t, off_t &) 178 /// 179 /// \param[in] offset 180 /// The offset to seek to within the file relative to the 181 /// beginning of the file. 182 /// 183 /// \param[in] error_ptr 184 /// A pointer to a lldb_private::Status object that will be 185 /// filled in if non-nullptr. 186 /// 187 /// \return 188 /// The resulting seek offset, or -1 on error. 189 off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr); 190 191 /// Seek to an offset relative to the current file position. 192 /// 193 /// NOTE: This function is NOT thread safe, other threads that 194 /// access this object might also change the current file position. For 195 /// thread safe reads and writes see the following functions: @see 196 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 197 /// size_t, off_t &) 198 /// 199 /// \param[in] offset 200 /// The offset to seek to within the file relative to the 201 /// current file position. 202 /// 203 /// \param[in] error_ptr 204 /// A pointer to a lldb_private::Status object that will be 205 /// filled in if non-nullptr. 206 /// 207 /// \return 208 /// The resulting seek offset, or -1 on error. 209 off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr); 210 211 /// Seek to an offset relative to the end of the file. 212 /// 213 /// NOTE: This function is NOT thread safe, other threads that 214 /// access this object might also change the current file position. For 215 /// thread safe reads and writes see the following functions: @see 216 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *, 217 /// size_t, off_t &) 218 /// 219 /// \param[in,out] offset 220 /// The offset to seek to within the file relative to the 221 /// end of the file which gets filled in with the resulting 222 /// absolute file offset. 223 /// 224 /// \param[in] error_ptr 225 /// A pointer to a lldb_private::Status object that will be 226 /// filled in if non-nullptr. 227 /// 228 /// \return 229 /// The resulting seek offset, or -1 on error. 230 off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr); 231 232 /// Read bytes from a file from the specified file offset. 233 /// 234 /// NOTE: This function is thread safe in that clients manager their 235 /// own file position markers and reads on other threads won't mess up the 236 /// current read. 237 /// 238 /// \param[in] dst 239 /// A buffer where to put the bytes that are read. 240 /// 241 /// \param[in,out] num_bytes 242 /// The number of bytes to read form the current file position 243 /// which gets modified with the number of bytes that were read. 244 /// 245 /// \param[in,out] offset 246 /// The offset within the file from which to read \a num_bytes 247 /// bytes. This offset gets incremented by the number of bytes 248 /// that were read. 249 /// 250 /// \return 251 /// An error object that indicates success or the reason for 252 /// failure. 253 Status Read(void *dst, size_t &num_bytes, off_t &offset); 254 255 /// Read bytes from a file from the specified file offset. 256 /// 257 /// NOTE: This function is thread safe in that clients manager their 258 /// own file position markers and reads on other threads won't mess up the 259 /// current read. 260 /// 261 /// \param[in,out] num_bytes 262 /// The number of bytes to read form the current file position 263 /// which gets modified with the number of bytes that were read. 264 /// 265 /// \param[in,out] offset 266 /// The offset within the file from which to read \a num_bytes 267 /// bytes. This offset gets incremented by the number of bytes 268 /// that were read. 269 /// 270 /// \param[in] null_terminate 271 /// Ensure that the data that is read is terminated with a NULL 272 /// character so that the data can be used as a C string. 273 /// 274 /// \param[out] data_buffer_sp 275 /// A data buffer to create and fill in that will contain any 276 /// data that is read from the file. This buffer will be reset 277 /// if an error occurs. 278 /// 279 /// \return 280 /// An error object that indicates success or the reason for 281 /// failure. 282 Status Read(size_t &num_bytes, off_t &offset, bool null_terminate, 283 lldb::DataBufferSP &data_buffer_sp); 284 285 /// Write bytes to a file at the specified file offset. 286 /// 287 /// NOTE: This function is thread safe in that clients manager their 288 /// own file position markers, though clients will need to implement their 289 /// own locking externally to avoid multiple people writing to the file at 290 /// the same time. 291 /// 292 /// \param[in] src 293 /// A buffer containing the bytes to write. 294 /// 295 /// \param[in,out] num_bytes 296 /// The number of bytes to write to the file at offset \a offset. 297 /// \a num_bytes gets modified with the number of bytes that 298 /// were read. 299 /// 300 /// \param[in,out] offset 301 /// The offset within the file at which to write \a num_bytes 302 /// bytes. This offset gets incremented by the number of bytes 303 /// that were written. 304 /// 305 /// \return 306 /// An error object that indicates success or the reason for 307 /// failure. 308 Status Write(const void *src, size_t &num_bytes, off_t &offset); 309 310 /// Flush the current stream 311 /// 312 /// \return 313 /// An error object that indicates success or the reason for 314 /// failure. 315 Status Flush(); 316 317 /// Sync to disk. 318 /// 319 /// \return 320 /// An error object that indicates success or the reason for 321 /// failure. 322 Status Sync(); 323 324 /// Get the permissions for a this file. 325 /// 326 /// \return 327 /// Bits logical OR'ed together from the permission bits defined 328 /// in lldb_private::File::Permissions. 329 uint32_t GetPermissions(Status &error) const; 330 331 /// Return true if this file is interactive. 332 /// 333 /// \return 334 /// True if this file is a terminal (tty or pty), false 335 /// otherwise. 336 bool GetIsInteractive(); 337 338 /// Return true if this file from a real terminal. 339 /// 340 /// Just knowing a file is a interactive isn't enough, we also need to know 341 /// if the terminal has a width and height so we can do cursor movement and 342 /// other terminal manipulations by sending escape sequences. 343 /// 344 /// \return 345 /// True if this file is a terminal (tty, not a pty) that has 346 /// a non-zero width and height, false otherwise. 347 bool GetIsRealTerminal(); 348 349 bool GetIsTerminalWithColors(); 350 351 /// Output printf formatted output to the stream. 352 /// 353 /// Print some formatted output to the stream. 354 /// 355 /// \param[in] format 356 /// A printf style format string. 357 /// 358 /// \param[in] ... 359 /// Variable arguments that are needed for the printf style 360 /// format string \a format. 361 size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); 362 363 size_t PrintfVarArg(const char *format, va_list args); 364 365 void SetOptions(uint32_t options) { m_options = options; } 366 367 static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; }; 368 369 protected: 370 bool DescriptorIsValid() const { return DescriptorIsValid(m_descriptor); } 371 372 bool StreamIsValid() const { return m_stream != kInvalidStream; } 373 374 void CalculateInteractiveAndTerminal(); 375 376 // Member variables 377 int m_descriptor; 378 FILE *m_stream; 379 uint32_t m_options; 380 bool m_own_stream; 381 LazyBool m_is_interactive; 382 LazyBool m_is_real_terminal; 383 LazyBool m_supports_colors; 384 std::mutex offset_access_mutex; 385 386 private: 387 DISALLOW_COPY_AND_ASSIGN(File); 388 }; 389 390 } // namespace lldb_private 391 392 #endif // liblldb_File_h_ 393