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 LLDB_HOST_FILE_H
10#define LLDB_HOST_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#include "llvm/ADT/BitmaskEnum.h"
17
18#include <mutex>
19#include <stdarg.h>
20#include <stdio.h>
21#include <sys/types.h>
22
23namespace lldb_private {
24
25LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
26
27/// \class File File.h "lldb/Host/File.h"
28/// An abstract base class for files.
29///
30/// Files will often be NativeFiles, which provides a wrapper
31/// around host OS file functionality. But it
32/// is also possible to subclass file to provide objects that have file
33/// or stream functionality but are not backed by any host OS file.
34class File : public IOObject {
35public:
36 static int kInvalidDescriptor;
37 static FILE *kInvalidStream;
38
39 // NB this enum is used in the lldb platform gdb-remote packet
40 // vFile:open: and existing values cannot be modified.
41 //
42 // FIXME
43 // These values do not match the values used by GDB
44 // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
45 // * rdar://problem/46788934
46 enum OpenOptions : uint32_t {
47 eOpenOptionRead = (1u << 0), // Open file for reading
48 eOpenOptionWrite = (1u << 1), // Open file for writing
49 eOpenOptionAppend =
50 (1u << 2), // Don't truncate file when opening, append to end of file
51 eOpenOptionTruncate = (1u << 3), // Truncate file when opening
52 eOpenOptionNonBlocking = (1u << 4), // File reads
53 eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist
54 eOpenOptionCanCreateNewOnly =
55 (1u << 6), // Can create file only if it doesn't already exist
56 eOpenOptionDontFollowSymlinks = (1u << 7),
57 eOpenOptionCloseOnExec =
58 (1u << 8), // Close the file when executing a new process
59 LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionCloseOnExec)
60 };
61
62 static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options);
63 static llvm::Expected<OpenOptions> GetOptionsFromMode(llvm::StringRef mode);
64 static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; };
65 static llvm::Expected<const char *>
66 GetStreamOpenModeFromOptions(OpenOptions options);
67
68 File()
69 : IOObject(eFDTypeFile), m_is_interactive(eLazyBoolCalculate),
70 m_is_real_terminal(eLazyBoolCalculate),
71 m_supports_colors(eLazyBoolCalculate){};
72
73 /// Read bytes from a file from the current file position into buf.
74 ///
75 /// NOTE: This function is NOT thread safe. Use the read function
76 /// that takes an "off_t &offset" to ensure correct operation in multi-
77 /// threaded environments.
78 ///
79 /// \param[in,out] num_bytes
80 /// Pass in the size of buf. Read will pass out the number
81 /// of bytes read. Zero bytes read with no error indicates
82 /// EOF.
83 ///
84 /// \return
85 /// success, ENOTSUP, or another error.
86 Status Read(void *buf, size_t &num_bytes) override;
87
88 /// Write bytes from buf to a file at the current file position.
89 ///
90 /// NOTE: This function is NOT thread safe. Use the write function
91 /// that takes an "off_t &offset" to ensure correct operation in multi-
92 /// threaded environments.
93 ///
94 /// \param[in,out] num_bytes
95 /// Pass in the size of buf. Write will pass out the number
96 /// of bytes written. Write will attempt write the full number
97 /// of bytes and will not return early except on error.
98 ///
99 /// \return
100 /// success, ENOTSUP, or another error.
101 Status Write(const void *buf, size_t &num_bytes) override;
102
103 /// IsValid
104 ///
105 /// \return
106 /// true iff the file is valid.
107 bool IsValid() const override;
108
109 /// Flush any buffers and release any resources owned by the file.
110 /// After Close() the file will be invalid.
111 ///
112 /// \return
113 /// success or an error.
114 Status Close() override;
115
116 /// Get a handle that can be used for OS polling interfaces, such
117 /// as WaitForMultipleObjects, select, or epoll. This may return
118 /// IOObject::kInvalidHandleValue if none is available. This will
119 /// generally be the same as the file descriptor, this function
120 /// is not interchangeable with GetDescriptor(). A WaitableHandle
121 /// must only be used for polling, not actual I/O.
122 ///
123 /// \return
124 /// a valid handle or IOObject::kInvalidHandleValue
125 WaitableHandle GetWaitableHandle() override;
126
127 /// Get the file specification for this file, if possible.
128 ///
129 /// \param[out] file_spec
130 /// the file specification.
131 /// \return
132 /// ENOTSUP, success, or another error.
133 virtual Status GetFileSpec(FileSpec &file_spec) const;
134
135 /// Get underlying OS file descriptor for this file, or kInvalidDescriptor.
136 /// If the descriptor is valid, then it may be used directly for I/O
137 /// However, the File may also perform it's own buffering, so avoid using
138 /// this if it is not necessary, or use Flush() appropriately.
139 ///
140 /// \return
141 /// a valid file descriptor for this file or kInvalidDescriptor
142 virtual int GetDescriptor() const;
143
144 /// Get the underlying libc stream for this file, or NULL.
145 ///
146 /// Not all valid files will have a FILE* stream. This should only be
147 /// used if absolutely necessary, such as to interact with 3rd party
148 /// libraries that need FILE* streams.
149 ///
150 /// \return
151 /// a valid stream or NULL;
152 virtual FILE *GetStream();
153
154 /// Seek to an offset relative to the beginning of the file.
155 ///
156 /// NOTE: This function is NOT thread safe, other threads that
157 /// access this object might also change the current file position. For
158 /// thread safe reads and writes see the following functions: @see
159 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *,
160 /// size_t, off_t &)
161 ///
162 /// \param[in] offset
163 /// The offset to seek to within the file relative to the
164 /// beginning of the file.
165 ///
166 /// \param[in] error_ptr
167 /// A pointer to a lldb_private::Status object that will be
168 /// filled in if non-nullptr.
169 ///
170 /// \return
171 /// The resulting seek offset, or -1 on error.
172 virtual off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr);
173
174 /// Seek to an offset relative to the current file position.
175 ///
176 /// NOTE: This function is NOT thread safe, other threads that
177 /// access this object might also change the current file position. For
178 /// thread safe reads and writes see the following functions: @see
179 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *,
180 /// size_t, off_t &)
181 ///
182 /// \param[in] offset
183 /// The offset to seek to within the file relative to the
184 /// current file position.
185 ///
186 /// \param[in] error_ptr
187 /// A pointer to a lldb_private::Status object that will be
188 /// filled in if non-nullptr.
189 ///
190 /// \return
191 /// The resulting seek offset, or -1 on error.
192 virtual off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr);
193
194 /// Seek to an offset relative to the end of the file.
195 ///
196 /// NOTE: This function is NOT thread safe, other threads that
197 /// access this object might also change the current file position. For
198 /// thread safe reads and writes see the following functions: @see
199 /// File::Read (void *, size_t, off_t &) \see File::Write (const void *,
200 /// size_t, off_t &)
201 ///
202 /// \param[in,out] offset
203 /// The offset to seek to within the file relative to the
204 /// end of the file which gets filled in with the resulting
205 /// absolute file offset.
206 ///
207 /// \param[in] error_ptr
208 /// A pointer to a lldb_private::Status object that will be
209 /// filled in if non-nullptr.
210 ///
211 /// \return
212 /// The resulting seek offset, or -1 on error.
213 virtual off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr);
214
215 /// Read bytes from a file from the specified file offset.
216 ///
217 /// NOTE: This function is thread safe in that clients manager their
218 /// own file position markers and reads on other threads won't mess up the
219 /// current read.
220 ///
221 /// \param[in] dst
222 /// A buffer where to put the bytes that are read.
223 ///
224 /// \param[in,out] num_bytes
225 /// The number of bytes to read form the current file position
226 /// which gets modified with the number of bytes that were read.
227 ///
228 /// \param[in,out] offset
229 /// The offset within the file from which to read \a num_bytes
230 /// bytes. This offset gets incremented by the number of bytes
231 /// that were read.
232 ///
233 /// \return
234 /// An error object that indicates success or the reason for
235 /// failure.
236 virtual Status Read(void *dst, size_t &num_bytes, off_t &offset);
237
238 /// Write bytes to a file at the specified file offset.
239 ///
240 /// NOTE: This function is thread safe in that clients manager their
241 /// own file position markers, though clients will need to implement their
242 /// own locking externally to avoid multiple people writing to the file at
243 /// the same time.
244 ///
245 /// \param[in] src
246 /// A buffer containing the bytes to write.
247 ///
248 /// \param[in,out] num_bytes
249 /// The number of bytes to write to the file at offset \a offset.
250 /// \a num_bytes gets modified with the number of bytes that
251 /// were read.
252 ///
253 /// \param[in,out] offset
254 /// The offset within the file at which to write \a num_bytes
255 /// bytes. This offset gets incremented by the number of bytes
256 /// that were written.
257 ///
258 /// \return
259 /// An error object that indicates success or the reason for
260 /// failure.
261 virtual Status Write(const void *src, size_t &num_bytes, off_t &offset);
262
263 /// Flush the current stream
264 ///
265 /// \return
266 /// An error object that indicates success or the reason for
267 /// failure.
268 virtual Status Flush();
269
270 /// Sync to disk.
271 ///
272 /// \return
273 /// An error object that indicates success or the reason for
274 /// failure.
275 virtual Status Sync();
276
277 /// Output printf formatted output to the stream.
278 ///
279 /// NOTE: this is not virtual, because it just calls the va_list
280 /// version of the function.
281 ///
282 /// Print some formatted output to the stream.
283 ///
284 /// \param[in] format
285 /// A printf style format string.
286 ///
287 /// \param[in] ...
288 /// Variable arguments that are needed for the printf style
289 /// format string \a format.
290 size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
291
292 /// Output printf formatted output to the stream.
293 ///
294 /// Print some formatted output to the stream.
295 ///
296 /// \param[in] format
297 /// A printf style format string.
298 ///
299 /// \param[in] args
300 /// Variable arguments that are needed for the printf style
301 /// format string \a format.
302 virtual size_t PrintfVarArg(const char *format, va_list args);
303
304 /// Return the OpenOptions for this file.
305 ///
306 /// Some options like eOpenOptionDontFollowSymlinks only make
307 /// sense when a file is being opened (or not at all)
308 /// and may not be preserved for this method. But any valid
309 /// File should return either or both of eOpenOptionRead and
310 /// eOpenOptionWrite here.
311 ///
312 /// \return
313 /// OpenOptions flags for this file, or an error.
314 virtual llvm::Expected<OpenOptions> GetOptions() const;
315
316 llvm::Expected<const char *> GetOpenMode() const {
317 auto opts = GetOptions();
318 if (!opts)
319 return opts.takeError();
320 return GetStreamOpenModeFromOptions(opts.get());
321 }
322
323 /// Get the permissions for a this file.
324 ///
325 /// \return
326 /// Bits logical OR'ed together from the permission bits defined
327 /// in lldb_private::File::Permissions.
328 uint32_t GetPermissions(Status &error) const;
329
330 /// Return true if this file is interactive.
331 ///
332 /// \return
333 /// True if this file is a terminal (tty or pty), false
334 /// otherwise.
335 bool GetIsInteractive();
336
337 /// Return true if this file from a real terminal.
338 ///
339 /// Just knowing a file is a interactive isn't enough, we also need to know
340 /// if the terminal has a width and height so we can do cursor movement and
341 /// other terminal manipulations by sending escape sequences.
342 ///
343 /// \return
344 /// True if this file is a terminal (tty, not a pty) that has
345 /// a non-zero width and height, false otherwise.
346 bool GetIsRealTerminal();
347
348 /// Return true if this file is a terminal which supports colors.
349 ///
350 /// \return
351 /// True iff this is a terminal and it supports colors.
352 bool GetIsTerminalWithColors();
353
354 operator bool() const { return IsValid(); };
355
356 bool operator!() const { return !IsValid(); };
357
358 static char ID;
359 virtual bool isA(const void *classID) const { return classID == &ID; }
360 static bool classof(const File *file) { return file->isA(&ID); }
361
362protected:
363 LazyBool m_is_interactive;
364 LazyBool m_is_real_terminal;
365 LazyBool m_supports_colors;
366
367 void CalculateInteractiveAndTerminal();
368
369private:
370 File(const File &) = delete;
371 const File &operator=(const File &) = delete;
372};
373
374class NativeFile : public File {
375public:
376 NativeFile()
377 : m_descriptor(kInvalidDescriptor), m_own_descriptor(false),
378 m_stream(kInvalidStream), m_options(), m_own_stream(false) {}
379
380 NativeFile(FILE *fh, bool transfer_ownership)
381 : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh),
382 m_options(), m_own_stream(transfer_ownership) {}
383
384 NativeFile(int fd, OpenOptions options, bool transfer_ownership)
385 : m_descriptor(fd), m_own_descriptor(transfer_ownership),
386 m_stream(kInvalidStream), m_options(options), m_own_stream(false) {}
387
388 ~NativeFile() override { Close(); }
389
390 bool IsValid() const override {
391 return DescriptorIsValid() || StreamIsValid();
392 }
393
394 Status Read(void *buf, size_t &num_bytes) override;
395 Status Write(const void *buf, size_t &num_bytes) override;
396 Status Close() override;
397 WaitableHandle GetWaitableHandle() override;
398 Status GetFileSpec(FileSpec &file_spec) const override;
399 int GetDescriptor() const override;
400 FILE *GetStream() override;
401 off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr) override;
402 off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr) override;
403 off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr) override;
404 Status Read(void *dst, size_t &num_bytes, off_t &offset) override;
405 Status Write(const void *src, size_t &num_bytes, off_t &offset) override;
406 Status Flush() override;
407 Status Sync() override;
408 size_t PrintfVarArg(const char *format, va_list args) override;
409 llvm::Expected<OpenOptions> GetOptions() const override;
410
411 static char ID;
412 virtual bool isA(const void *classID) const override {
413 return classID == &ID || File::isA(classID);
414 }
415 static bool classof(const File *file) { return file->isA(&ID); }
416
417protected:
418 bool DescriptorIsValid() const {
419 return File::DescriptorIsValid(m_descriptor);
420 }
421 bool StreamIsValid() const { return m_stream != kInvalidStream; }
422
423 // Member variables
424 int m_descriptor;
425 bool m_own_descriptor;
426 FILE *m_stream;
427 OpenOptions m_options;
428 bool m_own_stream;
429 std::mutex offset_access_mutex;
430
431private:
432 NativeFile(const NativeFile &) = delete;
433 const NativeFile &operator=(const NativeFile &) = delete;
434};
435
436} // namespace lldb_private
437
438#endif // LLDB_HOST_FILE_H
439