1 //===-- File.h --------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_File_h_
11 #define liblldb_File_h_
17 #include <sys/types.h>
19 // Other libraries and framework includes
21 #include "lldb/Host/IOObject.h"
22 #include "lldb/Host/PosixApi.h"
23 #include "lldb/lldb-private.h"
25 namespace lldb_private {
27 //----------------------------------------------------------------------
28 /// @class File File.h "lldb/Host/File.h"
29 /// @brief A file class.
31 /// A file class that divides abstracts the LLDB core from host file
33 //----------------------------------------------------------------------
34 class File : public IOObject {
36 static int kInvalidDescriptor;
37 static FILE *kInvalidStream;
40 eOpenOptionRead = (1u << 0), // Open file for reading
41 eOpenOptionWrite = (1u << 1), // Open file for writing
43 (1u << 2), // Don't truncate file when opening, append to end of file
44 eOpenOptionTruncate = (1u << 3), // Truncate file when opening
45 eOpenOptionNonBlocking = (1u << 4), // File reads
46 eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist
47 eOpenOptionCanCreateNewOnly =
48 (1u << 6), // Can create file only if it doesn't already exist
49 eOpenOptionDontFollowSymlinks = (1u << 7),
50 eOpenOptionCloseOnExec =
51 (1u << 8) // Close the file when executing a new process
54 static mode_t ConvertOpenOptionsForPOSIXOpen(uint32_t open_options);
57 : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
58 m_stream(kInvalidStream), m_options(0), m_own_stream(false),
59 m_is_interactive(eLazyBoolCalculate),
60 m_is_real_terminal(eLazyBoolCalculate) {}
62 File(FILE *fh, bool transfer_ownership)
63 : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
64 m_stream(fh), m_options(0), m_own_stream(transfer_ownership),
65 m_is_interactive(eLazyBoolCalculate),
66 m_is_real_terminal(eLazyBoolCalculate) {}
68 //------------------------------------------------------------------
69 /// Constructor with path.
71 /// Takes a path to a file which can be just a filename, or a full
72 /// path. If \a path is not nullptr or empty, this function will call
73 /// File::Open (const char *path, uint32_t options, uint32_t permissions).
76 /// The full or partial path to a file.
78 /// @param[in] options
79 /// Options to use when opening (see File::OpenOptions)
81 /// @param[in] permissions
82 /// Options to use when opening (see File::Permissions)
84 /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
85 //------------------------------------------------------------------
86 File(const char *path, uint32_t options,
87 uint32_t permissions = lldb::eFilePermissionsFileDefault);
89 //------------------------------------------------------------------
90 /// Constructor with FileSpec.
92 /// Takes a FileSpec pointing to a file which can be just a filename, or a
94 /// path. If \a path is not nullptr or empty, this function will call
95 /// File::Open (const char *path, uint32_t options, uint32_t permissions).
97 /// @param[in] filespec
98 /// The FileSpec for this file.
100 /// @param[in] options
101 /// Options to use when opening (see File::OpenOptions)
103 /// @param[in] permissions
104 /// Options to use when opening (see File::Permissions)
106 /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
107 //------------------------------------------------------------------
108 File(const FileSpec &filespec, uint32_t options,
109 uint32_t permissions = lldb::eFilePermissionsFileDefault);
111 File(int fd, bool transfer_ownership)
112 : IOObject(eFDTypeFile, transfer_ownership), m_descriptor(fd),
113 m_stream(kInvalidStream), m_options(0), m_own_stream(false),
114 m_is_interactive(eLazyBoolCalculate),
115 m_is_real_terminal(eLazyBoolCalculate) {}
117 //------------------------------------------------------------------
120 /// The destructor is virtual in case this class is subclassed.
121 //------------------------------------------------------------------
124 bool IsValid() const override {
125 return DescriptorIsValid() || StreamIsValid();
128 //------------------------------------------------------------------
129 /// Convert to pointer operator.
131 /// This allows code to check a File object to see if it
132 /// contains anything valid using code such as:
141 /// A pointer to this object if either the directory or filename
142 /// is valid, nullptr otherwise.
143 //------------------------------------------------------------------
144 operator bool() const { return DescriptorIsValid() || StreamIsValid(); }
146 //------------------------------------------------------------------
147 /// Logical NOT operator.
149 /// This allows code to check a File object to see if it is
150 /// invalid using code such as:
159 /// Returns \b true if the object has an empty directory and
160 /// filename, \b false otherwise.
161 //------------------------------------------------------------------
162 bool operator!() const { return !DescriptorIsValid() && !StreamIsValid(); }
164 //------------------------------------------------------------------
165 /// Get the file spec for this file.
168 /// A reference to the file specification object.
169 //------------------------------------------------------------------
170 Error GetFileSpec(FileSpec &file_spec) const;
172 //------------------------------------------------------------------
173 /// Open a file for read/writing with the specified options.
175 /// Takes a path to a file which can be just a filename, or a full
179 /// The full or partial path to a file.
181 /// @param[in] options
182 /// Options to use when opening (see File::OpenOptions)
184 /// @param[in] permissions
185 /// Options to use when opening (see File::Permissions)
186 //------------------------------------------------------------------
187 Error Open(const char *path, uint32_t options,
188 uint32_t permissions = lldb::eFilePermissionsFileDefault);
190 Error Close() override;
194 int GetDescriptor() const;
196 WaitableHandle GetWaitableHandle() override;
198 void SetDescriptor(int fd, bool transfer_ownership);
202 void SetStream(FILE *fh, bool transfer_ownership);
204 //------------------------------------------------------------------
205 /// Read bytes from a file from the current file position.
207 /// NOTE: This function is NOT thread safe. Use the read function
208 /// that takes an "off_t &offset" to ensure correct operation in
209 /// multi-threaded environments.
212 /// A buffer where to put the bytes that are read.
214 /// @param[in,out] num_bytes
215 /// The number of bytes to read form the current file position
216 /// which gets modified with the number of bytes that were read.
219 /// An error object that indicates success or the reason for
221 //------------------------------------------------------------------
222 Error Read(void *buf, size_t &num_bytes) override;
224 //------------------------------------------------------------------
225 /// Write bytes to a file at the current file position.
227 /// NOTE: This function is NOT thread safe. Use the write function
228 /// that takes an "off_t &offset" to ensure correct operation in
229 /// multi-threaded environments.
232 /// A buffer where to put the bytes that are read.
234 /// @param[in,out] num_bytes
235 /// The number of bytes to write to the current file position
236 /// which gets modified with the number of bytes that were
240 /// An error object that indicates success or the reason for
242 //------------------------------------------------------------------
243 Error Write(const void *buf, size_t &num_bytes) override;
245 //------------------------------------------------------------------
246 /// Seek to an offset relative to the beginning of the file.
248 /// NOTE: This function is NOT thread safe, other threads that
249 /// access this object might also change the current file position.
250 /// For thread safe reads and writes see the following functions:
251 /// @see File::Read (void *, size_t, off_t &)
252 /// @see File::Write (const void *, size_t, off_t &)
254 /// @param[in] offset
255 /// The offset to seek to within the file relative to the
256 /// beginning of the file.
258 /// @param[in] error_ptr
259 /// A pointer to a lldb_private::Error object that will be
260 /// filled in if non-nullptr.
263 /// The resulting seek offset, or -1 on error.
264 //------------------------------------------------------------------
265 off_t SeekFromStart(off_t offset, Error *error_ptr = nullptr);
267 //------------------------------------------------------------------
268 /// Seek to an offset relative to the current file position.
270 /// NOTE: This function is NOT thread safe, other threads that
271 /// access this object might also change the current file position.
272 /// For thread safe reads and writes see the following functions:
273 /// @see File::Read (void *, size_t, off_t &)
274 /// @see File::Write (const void *, size_t, off_t &)
276 /// @param[in] offset
277 /// The offset to seek to within the file relative to the
278 /// current file position.
280 /// @param[in] error_ptr
281 /// A pointer to a lldb_private::Error object that will be
282 /// filled in if non-nullptr.
285 /// The resulting seek offset, or -1 on error.
286 //------------------------------------------------------------------
287 off_t SeekFromCurrent(off_t offset, Error *error_ptr = nullptr);
289 //------------------------------------------------------------------
290 /// Seek to an offset relative to the end of the file.
292 /// NOTE: This function is NOT thread safe, other threads that
293 /// access this object might also change the current file position.
294 /// For thread safe reads and writes see the following functions:
295 /// @see File::Read (void *, size_t, off_t &)
296 /// @see File::Write (const void *, size_t, off_t &)
298 /// @param[in,out] offset
299 /// The offset to seek to within the file relative to the
300 /// end of the file which gets filled in with the resulting
301 /// absolute file offset.
303 /// @param[in] error_ptr
304 /// A pointer to a lldb_private::Error object that will be
305 /// filled in if non-nullptr.
308 /// The resulting seek offset, or -1 on error.
309 //------------------------------------------------------------------
310 off_t SeekFromEnd(off_t offset, Error *error_ptr = nullptr);
312 //------------------------------------------------------------------
313 /// Read bytes from a file from the specified file offset.
315 /// NOTE: This function is thread safe in that clients manager their
316 /// own file position markers and reads on other threads won't mess
317 /// up the current read.
320 /// A buffer where to put the bytes that are read.
322 /// @param[in,out] num_bytes
323 /// The number of bytes to read form the current file position
324 /// which gets modified with the number of bytes that were read.
326 /// @param[in,out] offset
327 /// The offset within the file from which to read \a num_bytes
328 /// bytes. This offset gets incremented by the number of bytes
332 /// An error object that indicates success or the reason for
334 //------------------------------------------------------------------
335 Error Read(void *dst, size_t &num_bytes, off_t &offset);
337 //------------------------------------------------------------------
338 /// Read bytes from a file from the specified file offset.
340 /// NOTE: This function is thread safe in that clients manager their
341 /// own file position markers and reads on other threads won't mess
342 /// up the current read.
344 /// @param[in,out] num_bytes
345 /// The number of bytes to read form the current file position
346 /// which gets modified with the number of bytes that were read.
348 /// @param[in,out] offset
349 /// The offset within the file from which to read \a num_bytes
350 /// bytes. This offset gets incremented by the number of bytes
353 /// @param[in] null_terminate
354 /// Ensure that the data that is read is terminated with a NULL
355 /// character so that the data can be used as a C string.
357 /// @param[out] data_buffer_sp
358 /// A data buffer to create and fill in that will contain any
359 /// data that is read from the file. This buffer will be reset
360 /// if an error occurs.
363 /// An error object that indicates success or the reason for
365 //------------------------------------------------------------------
366 Error Read(size_t &num_bytes, off_t &offset, bool null_terminate,
367 lldb::DataBufferSP &data_buffer_sp);
369 //------------------------------------------------------------------
370 /// Write bytes to a file at the specified file offset.
372 /// NOTE: This function is thread safe in that clients manager their
373 /// own file position markers, though clients will need to implement
374 /// their own locking externally to avoid multiple people writing
375 /// to the file at the same time.
378 /// A buffer containing the bytes to write.
380 /// @param[in,out] num_bytes
381 /// The number of bytes to write to the file at offset \a offset.
382 /// \a num_bytes gets modified with the number of bytes that
385 /// @param[in,out] offset
386 /// The offset within the file at which to write \a num_bytes
387 /// bytes. This offset gets incremented by the number of bytes
388 /// that were written.
391 /// An error object that indicates success or the reason for
393 //------------------------------------------------------------------
394 Error Write(const void *src, size_t &num_bytes, off_t &offset);
396 //------------------------------------------------------------------
397 /// Flush the current stream
400 /// An error object that indicates success or the reason for
402 //------------------------------------------------------------------
405 //------------------------------------------------------------------
409 /// An error object that indicates success or the reason for
411 //------------------------------------------------------------------
414 //------------------------------------------------------------------
415 /// Get the permissions for a this file.
418 /// Bits logical OR'ed together from the permission bits defined
419 /// in lldb_private::File::Permissions.
420 //------------------------------------------------------------------
421 uint32_t GetPermissions(Error &error) const;
423 static uint32_t GetPermissions(const FileSpec &file_spec, Error &error);
425 //------------------------------------------------------------------
426 /// Return true if this file is interactive.
429 /// True if this file is a terminal (tty or pty), false
431 //------------------------------------------------------------------
432 bool GetIsInteractive();
434 //------------------------------------------------------------------
435 /// Return true if this file from a real terminal.
437 /// Just knowing a file is a interactive isn't enough, we also need
438 /// to know if the terminal has a width and height so we can do
439 /// cursor movement and other terminal manipulations by sending
440 /// escape sequences.
443 /// True if this file is a terminal (tty, not a pty) that has
444 /// a non-zero width and height, false otherwise.
445 //------------------------------------------------------------------
446 bool GetIsRealTerminal();
448 bool GetIsTerminalWithColors();
450 //------------------------------------------------------------------
451 /// Output printf formatted output to the stream.
453 /// Print some formatted output to the stream.
455 /// @param[in] format
456 /// A printf style format string.
459 /// Variable arguments that are needed for the printf style
460 /// format string \a format.
461 //------------------------------------------------------------------
462 size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
464 size_t PrintfVarArg(const char *format, va_list args);
466 void SetOptions(uint32_t options) { m_options = options; }
469 bool DescriptorIsValid() const { return m_descriptor >= 0; }
471 bool StreamIsValid() const { return m_stream != kInvalidStream; }
473 void CalculateInteractiveAndTerminal();
475 //------------------------------------------------------------------
477 //------------------------------------------------------------------
482 LazyBool m_is_interactive;
483 LazyBool m_is_real_terminal;
484 LazyBool m_supports_colors;
487 DISALLOW_COPY_AND_ASSIGN(File);
490 } // namespace lldb_private
492 #endif // liblldb_File_h_