Coverage Report

Created: 2022-01-25 06:29

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