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_
13 #include "lldb/Host/PosixApi.h"
14 #include "lldb/Utility/IOObject.h"
15 #include "lldb/Utility/Status.h"
16 #include "lldb/lldb-private.h"
20 #include <sys/types.h>
22 namespace lldb_private {
24 //----------------------------------------------------------------------
25 /// @class File File.h "lldb/Host/File.h"
26 /// @brief A file class.
28 /// A file class that divides abstracts the LLDB core from host file
30 //----------------------------------------------------------------------
31 class File : public IOObject {
33 static int kInvalidDescriptor;
34 static FILE *kInvalidStream;
37 eOpenOptionRead = (1u << 0), // Open file for reading
38 eOpenOptionWrite = (1u << 1), // Open file for writing
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
51 static mode_t ConvertOpenOptionsForPOSIXOpen(uint32_t open_options);
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) {}
59 File(FILE *fh, bool transfer_ownership)
60 : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
61 m_stream(fh), m_options(0), m_own_stream(transfer_ownership),
62 m_is_interactive(eLazyBoolCalculate),
63 m_is_real_terminal(eLazyBoolCalculate) {}
65 //------------------------------------------------------------------
66 /// Constructor with path.
68 /// Takes a path to a file which can be just a filename, or a full
69 /// path. If \a path is not nullptr or empty, this function will call
70 /// File::Open (const char *path, uint32_t options, uint32_t permissions).
73 /// The full or partial path to a file.
75 /// @param[in] options
76 /// Options to use when opening (see File::OpenOptions)
78 /// @param[in] permissions
79 /// Options to use when opening (see File::Permissions)
81 /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
82 //------------------------------------------------------------------
83 File(const char *path, uint32_t options,
84 uint32_t permissions = lldb::eFilePermissionsFileDefault);
86 //------------------------------------------------------------------
87 /// Constructor with FileSpec.
89 /// Takes a FileSpec pointing to a file which can be just a filename, or a
91 /// path. If \a path is not nullptr or empty, this function will call
92 /// File::Open (const char *path, uint32_t options, uint32_t permissions).
94 /// @param[in] filespec
95 /// The FileSpec for this file.
97 /// @param[in] options
98 /// Options to use when opening (see File::OpenOptions)
100 /// @param[in] permissions
101 /// Options to use when opening (see File::Permissions)
103 /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
104 //------------------------------------------------------------------
105 File(const FileSpec &filespec, uint32_t options,
106 uint32_t permissions = lldb::eFilePermissionsFileDefault);
108 File(int fd, bool transfer_ownership)
109 : IOObject(eFDTypeFile, transfer_ownership), m_descriptor(fd),
110 m_stream(kInvalidStream), m_options(0), m_own_stream(false),
111 m_is_interactive(eLazyBoolCalculate),
112 m_is_real_terminal(eLazyBoolCalculate) {}
114 //------------------------------------------------------------------
117 /// The destructor is virtual in case this class is subclassed.
118 //------------------------------------------------------------------
121 bool IsValid() const override {
122 return DescriptorIsValid() || StreamIsValid();
125 //------------------------------------------------------------------
126 /// Convert to pointer operator.
128 /// This allows code to check a File object to see if it
129 /// contains anything valid using code such as:
138 /// A pointer to this object if either the directory or filename
139 /// is valid, nullptr otherwise.
140 //------------------------------------------------------------------
141 operator bool() const { return DescriptorIsValid() || StreamIsValid(); }
143 //------------------------------------------------------------------
144 /// Logical NOT operator.
146 /// This allows code to check a File object to see if it is
147 /// invalid using code such as:
156 /// Returns \b true if the object has an empty directory and
157 /// filename, \b false otherwise.
158 //------------------------------------------------------------------
159 bool operator!() const { return !DescriptorIsValid() && !StreamIsValid(); }
161 //------------------------------------------------------------------
162 /// Get the file spec for this file.
165 /// A reference to the file specification object.
166 //------------------------------------------------------------------
167 Status GetFileSpec(FileSpec &file_spec) const;
169 //------------------------------------------------------------------
170 /// Open a file for read/writing with the specified options.
172 /// Takes a path to a file which can be just a filename, or a full
176 /// The full or partial path to a file.
178 /// @param[in] options
179 /// Options to use when opening (see File::OpenOptions)
181 /// @param[in] permissions
182 /// Options to use when opening (see File::Permissions)
183 //------------------------------------------------------------------
184 Status Open(const char *path, uint32_t options,
185 uint32_t permissions = lldb::eFilePermissionsFileDefault);
187 Status Close() override;
191 int GetDescriptor() const;
193 WaitableHandle GetWaitableHandle() override;
195 void SetDescriptor(int fd, bool transfer_ownership);
199 void SetStream(FILE *fh, bool transfer_ownership);
201 //------------------------------------------------------------------
202 /// Read bytes from a file from the current file position.
204 /// NOTE: This function is NOT thread safe. Use the read function
205 /// that takes an "off_t &offset" to ensure correct operation in
206 /// multi-threaded environments.
209 /// A buffer where to put the bytes that are read.
211 /// @param[in,out] num_bytes
212 /// The number of bytes to read form the current file position
213 /// which gets modified with the number of bytes that were read.
216 /// An error object that indicates success or the reason for
218 //------------------------------------------------------------------
219 Status Read(void *buf, size_t &num_bytes) override;
221 //------------------------------------------------------------------
222 /// Write bytes to a file at the current file position.
224 /// NOTE: This function is NOT thread safe. Use the write function
225 /// that takes an "off_t &offset" to ensure correct operation in
226 /// multi-threaded environments.
229 /// A buffer where to put the bytes that are read.
231 /// @param[in,out] num_bytes
232 /// The number of bytes to write to the current file position
233 /// which gets modified with the number of bytes that were
237 /// An error object that indicates success or the reason for
239 //------------------------------------------------------------------
240 Status Write(const void *buf, size_t &num_bytes) override;
242 //------------------------------------------------------------------
243 /// Seek to an offset relative to the beginning of the file.
245 /// NOTE: This function is NOT thread safe, other threads that
246 /// access this object might also change the current file position.
247 /// For thread safe reads and writes see the following functions:
248 /// @see File::Read (void *, size_t, off_t &)
249 /// @see File::Write (const void *, size_t, off_t &)
251 /// @param[in] offset
252 /// The offset to seek to within the file relative to the
253 /// beginning of the file.
255 /// @param[in] error_ptr
256 /// A pointer to a lldb_private::Status object that will be
257 /// filled in if non-nullptr.
260 /// The resulting seek offset, or -1 on error.
261 //------------------------------------------------------------------
262 off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr);
264 //------------------------------------------------------------------
265 /// Seek to an offset relative to the current file position.
267 /// NOTE: This function is NOT thread safe, other threads that
268 /// access this object might also change the current file position.
269 /// For thread safe reads and writes see the following functions:
270 /// @see File::Read (void *, size_t, off_t &)
271 /// @see File::Write (const void *, size_t, off_t &)
273 /// @param[in] offset
274 /// The offset to seek to within the file relative to the
275 /// current file position.
277 /// @param[in] error_ptr
278 /// A pointer to a lldb_private::Status object that will be
279 /// filled in if non-nullptr.
282 /// The resulting seek offset, or -1 on error.
283 //------------------------------------------------------------------
284 off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr);
286 //------------------------------------------------------------------
287 /// Seek to an offset relative to the end of the file.
289 /// NOTE: This function is NOT thread safe, other threads that
290 /// access this object might also change the current file position.
291 /// For thread safe reads and writes see the following functions:
292 /// @see File::Read (void *, size_t, off_t &)
293 /// @see File::Write (const void *, size_t, off_t &)
295 /// @param[in,out] offset
296 /// The offset to seek to within the file relative to the
297 /// end of the file which gets filled in with the resulting
298 /// absolute file offset.
300 /// @param[in] error_ptr
301 /// A pointer to a lldb_private::Status object that will be
302 /// filled in if non-nullptr.
305 /// The resulting seek offset, or -1 on error.
306 //------------------------------------------------------------------
307 off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr);
309 //------------------------------------------------------------------
310 /// Read bytes from a file from the specified file offset.
312 /// NOTE: This function is thread safe in that clients manager their
313 /// own file position markers and reads on other threads won't mess
314 /// up the current read.
317 /// A buffer where to put the bytes that are read.
319 /// @param[in,out] num_bytes
320 /// The number of bytes to read form the current file position
321 /// which gets modified with the number of bytes that were read.
323 /// @param[in,out] offset
324 /// The offset within the file from which to read \a num_bytes
325 /// bytes. This offset gets incremented by the number of bytes
329 /// An error object that indicates success or the reason for
331 //------------------------------------------------------------------
332 Status Read(void *dst, size_t &num_bytes, off_t &offset);
334 //------------------------------------------------------------------
335 /// Read bytes from a file from the specified file offset.
337 /// NOTE: This function is thread safe in that clients manager their
338 /// own file position markers and reads on other threads won't mess
339 /// up the current read.
341 /// @param[in,out] num_bytes
342 /// The number of bytes to read form the current file position
343 /// which gets modified with the number of bytes that were read.
345 /// @param[in,out] offset
346 /// The offset within the file from which to read \a num_bytes
347 /// bytes. This offset gets incremented by the number of bytes
350 /// @param[in] null_terminate
351 /// Ensure that the data that is read is terminated with a NULL
352 /// character so that the data can be used as a C string.
354 /// @param[out] data_buffer_sp
355 /// A data buffer to create and fill in that will contain any
356 /// data that is read from the file. This buffer will be reset
357 /// if an error occurs.
360 /// An error object that indicates success or the reason for
362 //------------------------------------------------------------------
363 Status Read(size_t &num_bytes, off_t &offset, bool null_terminate,
364 lldb::DataBufferSP &data_buffer_sp);
366 //------------------------------------------------------------------
367 /// Write bytes to a file at the specified file offset.
369 /// NOTE: This function is thread safe in that clients manager their
370 /// own file position markers, though clients will need to implement
371 /// their own locking externally to avoid multiple people writing
372 /// to the file at the same time.
375 /// A buffer containing the bytes to write.
377 /// @param[in,out] num_bytes
378 /// The number of bytes to write to the file at offset \a offset.
379 /// \a num_bytes gets modified with the number of bytes that
382 /// @param[in,out] offset
383 /// The offset within the file at which to write \a num_bytes
384 /// bytes. This offset gets incremented by the number of bytes
385 /// that were written.
388 /// An error object that indicates success or the reason for
390 //------------------------------------------------------------------
391 Status Write(const void *src, size_t &num_bytes, off_t &offset);
393 //------------------------------------------------------------------
394 /// Flush the current stream
397 /// An error object that indicates success or the reason for
399 //------------------------------------------------------------------
402 //------------------------------------------------------------------
406 /// An error object that indicates success or the reason for
408 //------------------------------------------------------------------
411 //------------------------------------------------------------------
412 /// Get the permissions for a this file.
415 /// Bits logical OR'ed together from the permission bits defined
416 /// in lldb_private::File::Permissions.
417 //------------------------------------------------------------------
418 uint32_t GetPermissions(Status &error) const;
420 static uint32_t GetPermissions(const FileSpec &file_spec, Status &error);
422 //------------------------------------------------------------------
423 /// Return true if this file is interactive.
426 /// True if this file is a terminal (tty or pty), false
428 //------------------------------------------------------------------
429 bool GetIsInteractive();
431 //------------------------------------------------------------------
432 /// Return true if this file from a real terminal.
434 /// Just knowing a file is a interactive isn't enough, we also need
435 /// to know if the terminal has a width and height so we can do
436 /// cursor movement and other terminal manipulations by sending
437 /// escape sequences.
440 /// True if this file is a terminal (tty, not a pty) that has
441 /// a non-zero width and height, false otherwise.
442 //------------------------------------------------------------------
443 bool GetIsRealTerminal();
445 bool GetIsTerminalWithColors();
447 //------------------------------------------------------------------
448 /// Output printf formatted output to the stream.
450 /// Print some formatted output to the stream.
452 /// @param[in] format
453 /// A printf style format string.
456 /// Variable arguments that are needed for the printf style
457 /// format string \a format.
458 //------------------------------------------------------------------
459 size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
461 size_t PrintfVarArg(const char *format, va_list args);
463 void SetOptions(uint32_t options) { m_options = options; }
466 bool DescriptorIsValid() const { return m_descriptor >= 0; }
468 bool StreamIsValid() const { return m_stream != kInvalidStream; }
470 void CalculateInteractiveAndTerminal();
472 //------------------------------------------------------------------
474 //------------------------------------------------------------------
479 LazyBool m_is_interactive;
480 LazyBool m_is_real_terminal;
481 LazyBool m_supports_colors;
484 DISALLOW_COPY_AND_ASSIGN(File);
487 } // namespace lldb_private
489 #endif // liblldb_File_h_