1 //===-- File.h --------------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_File_h_
11 #define liblldb_File_h_
12 
13 // C Includes
14 // C++ Includes
15 #include <stdarg.h>
16 #include <stdio.h>
17 #include <sys/types.h>
18 
19 // Other libraries and framework includes
20 // Project includes
21 #include "lldb/lldb-private.h"
22 #include "lldb/Host/IOObject.h"
23 
24 namespace lldb_private {
25 
26 //----------------------------------------------------------------------
27 /// @class File File.h "lldb/Host/File.h"
28 /// @brief A file class.
29 ///
30 /// A file class that divides abstracts the LLDB core from host file
31 /// functionality.
32 //----------------------------------------------------------------------
33 class File : public IOObject
34 {
35 public:
36     static int kInvalidDescriptor;
37     static FILE * kInvalidStream;
38 
39     enum OpenOptions
40     {
41         eOpenOptionRead                 = (1u << 0),    // Open file for reading
42         eOpenOptionWrite                = (1u << 1),    // Open file for writing
43         eOpenOptionAppend               = (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     = (1u << 6),    // Can create file only if it doesn't already exist
48         eOpenoptionDontFollowSymlinks   = (1u << 7),
49         eOpenOptionCloseOnExec          = (1u << 8)     // Close the file when executing a new process
50     };
51 
52     static mode_t
53     ConvertOpenOptionsForPOSIXOpen (uint32_t open_options);
54 
55     File() :
56         IOObject(eFDTypeFile, false),
57         m_descriptor (kInvalidDescriptor),
58         m_stream (kInvalidStream),
59         m_options (0),
60         m_own_stream (false),
61         m_is_interactive (eLazyBoolCalculate),
62         m_is_real_terminal (eLazyBoolCalculate)
63     {
64     }
65 
66     File (FILE *fh, bool transfer_ownership) :
67         IOObject(eFDTypeFile, false),
68         m_descriptor (kInvalidDescriptor),
69         m_stream (fh),
70         m_options (0),
71         m_own_stream (transfer_ownership),
72         m_is_interactive (eLazyBoolCalculate),
73         m_is_real_terminal (eLazyBoolCalculate)
74     {
75     }
76 
77     File (const File &rhs);
78 
79     //------------------------------------------------------------------
80     /// Constructor with path.
81     ///
82     /// Takes a path to a file which can be just a filename, or a full
83     /// path. If \a path is not nullptr or empty, this function will call
84     /// File::Open (const char *path, uint32_t options, uint32_t permissions).
85     ///
86     /// @param[in] path
87     ///     The full or partial path to a file.
88     ///
89     /// @param[in] options
90     ///     Options to use when opening (see File::OpenOptions)
91     ///
92     /// @param[in] permissions
93     ///     Options to use when opening (see File::Permissions)
94     ///
95     /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
96     //------------------------------------------------------------------
97     File (const char *path,
98           uint32_t options,
99           uint32_t permissions = lldb::eFilePermissionsFileDefault);
100 
101     //------------------------------------------------------------------
102     /// Constructor with FileSpec.
103     ///
104     /// Takes a FileSpec pointing to a file which can be just a filename, or a full
105     /// path. If \a path is not nullptr or empty, this function will call
106     /// File::Open (const char *path, uint32_t options, uint32_t permissions).
107     ///
108     /// @param[in] filespec
109     ///     The FileSpec for this file.
110     ///
111     /// @param[in] options
112     ///     Options to use when opening (see File::OpenOptions)
113     ///
114     /// @param[in] permissions
115     ///     Options to use when opening (see File::Permissions)
116     ///
117     /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
118     //------------------------------------------------------------------
119     File (const FileSpec& filespec,
120           uint32_t options,
121           uint32_t permissions = lldb::eFilePermissionsFileDefault);
122 
123     File (int fd, bool transfer_ownership) :
124         IOObject(eFDTypeFile, transfer_ownership),
125         m_descriptor (fd),
126         m_stream (kInvalidStream),
127         m_options (0),
128         m_own_stream (false),
129         m_is_interactive (eLazyBoolCalculate),
130         m_is_real_terminal (eLazyBoolCalculate)
131     {
132     }
133 
134     //------------------------------------------------------------------
135     /// Destructor.
136     ///
137     /// The destructor is virtual in case this class is subclassed.
138     //------------------------------------------------------------------
139     ~File() override;
140 
141     File &
142     operator= (const File &rhs);
143 
144     bool
145     IsValid() const override
146     {
147         return DescriptorIsValid() || StreamIsValid();
148     }
149 
150     //------------------------------------------------------------------
151     /// Convert to pointer operator.
152     ///
153     /// This allows code to check a File object to see if it
154     /// contains anything valid using code such as:
155     ///
156     /// @code
157     /// File file(...);
158     /// if (file)
159     /// { ...
160     /// @endcode
161     ///
162     /// @return
163     ///     A pointer to this object if either the directory or filename
164     ///     is valid, nullptr otherwise.
165     //------------------------------------------------------------------
166     operator
167     bool () const
168     {
169         return DescriptorIsValid() || StreamIsValid();
170     }
171 
172     //------------------------------------------------------------------
173     /// Logical NOT operator.
174     ///
175     /// This allows code to check a File object to see if it is
176     /// invalid using code such as:
177     ///
178     /// @code
179     /// File file(...);
180     /// if (!file)
181     /// { ...
182     /// @endcode
183     ///
184     /// @return
185     ///     Returns \b true if the object has an empty directory and
186     ///     filename, \b false otherwise.
187     //------------------------------------------------------------------
188     bool
189     operator! () const
190     {
191         return !DescriptorIsValid() && !StreamIsValid();
192     }
193 
194     //------------------------------------------------------------------
195     /// Get the file spec for this file.
196     ///
197     /// @return
198     ///     A reference to the file specification object.
199     //------------------------------------------------------------------
200     Error
201     GetFileSpec (FileSpec &file_spec) const;
202 
203     //------------------------------------------------------------------
204     /// Open a file for read/writing with the specified options.
205     ///
206     /// Takes a path to a file which can be just a filename, or a full
207     /// path.
208     ///
209     /// @param[in] path
210     ///     The full or partial path to a file.
211     ///
212     /// @param[in] options
213     ///     Options to use when opening (see File::OpenOptions)
214     ///
215     /// @param[in] permissions
216     ///     Options to use when opening (see File::Permissions)
217     //------------------------------------------------------------------
218     Error
219     Open (const char *path,
220           uint32_t options,
221           uint32_t permissions = lldb::eFilePermissionsFileDefault);
222 
223     Error
224     Close() override;
225 
226     Error
227     Duplicate (const File &rhs);
228 
229     int
230     GetDescriptor() const;
231 
232     WaitableHandle
233     GetWaitableHandle() override;
234 
235     void
236     SetDescriptor(int fd, bool transfer_ownership);
237 
238     FILE *
239     GetStream ();
240 
241     void
242     SetStream (FILE *fh, bool transfer_ownership);
243 
244     //------------------------------------------------------------------
245     /// Read bytes from a file from the current file position.
246     ///
247     /// NOTE: This function is NOT thread safe. Use the read function
248     /// that takes an "off_t &offset" to ensure correct operation in
249     /// multi-threaded environments.
250     ///
251     /// @param[in] buf
252     ///     A buffer where to put the bytes that are read.
253     ///
254     /// @param[in,out] num_bytes
255     ///     The number of bytes to read form the current file position
256     ///     which gets modified with the number of bytes that were read.
257     ///
258     /// @return
259     ///     An error object that indicates success or the reason for
260     ///     failure.
261     //------------------------------------------------------------------
262     Error
263     Read(void *buf, size_t &num_bytes) override;
264 
265     //------------------------------------------------------------------
266     /// Write bytes to a file at the current file position.
267     ///
268     /// NOTE: This function is NOT thread safe. Use the write function
269     /// that takes an "off_t &offset" to ensure correct operation in
270     /// multi-threaded environments.
271     ///
272     /// @param[in] buf
273     ///     A buffer where to put the bytes that are read.
274     ///
275     /// @param[in,out] num_bytes
276     ///     The number of bytes to write to the current file position
277     ///     which gets modified with the number of bytes that were
278     ///     written.
279     ///
280     /// @return
281     ///     An error object that indicates success or the reason for
282     ///     failure.
283     //------------------------------------------------------------------
284     Error
285     Write(const void *buf, size_t &num_bytes) override;
286 
287     //------------------------------------------------------------------
288     /// Seek to an offset relative to the beginning of the file.
289     ///
290     /// NOTE: This function is NOT thread safe, other threads that
291     /// access this object might also change the current file position.
292     /// For thread safe reads and writes see the following functions:
293     /// @see File::Read (void *, size_t, off_t &)
294     /// @see File::Write (const void *, size_t, off_t &)
295     ///
296     /// @param[in] offset
297     ///     The offset to seek to within the file relative to the
298     ///     beginning of the file.
299     ///
300     /// @param[in] error_ptr
301     ///     A pointer to a lldb_private::Error object that will be
302     ///     filled in if non-nullptr.
303     ///
304     /// @return
305     ///     The resulting seek offset, or -1 on error.
306     //------------------------------------------------------------------
307     off_t
308     SeekFromStart(off_t offset, Error *error_ptr = nullptr);
309 
310     //------------------------------------------------------------------
311     /// Seek to an offset relative to the current file position.
312     ///
313     /// NOTE: This function is NOT thread safe, other threads that
314     /// access this object might also change the current file position.
315     /// For thread safe reads and writes see the following functions:
316     /// @see File::Read (void *, size_t, off_t &)
317     /// @see File::Write (const void *, size_t, off_t &)
318     ///
319     /// @param[in] offset
320     ///     The offset to seek to within the file relative to the
321     ///     current file position.
322     ///
323     /// @param[in] error_ptr
324     ///     A pointer to a lldb_private::Error object that will be
325     ///     filled in if non-nullptr.
326     ///
327     /// @return
328     ///     The resulting seek offset, or -1 on error.
329     //------------------------------------------------------------------
330     off_t
331     SeekFromCurrent(off_t offset, Error *error_ptr = nullptr);
332 
333     //------------------------------------------------------------------
334     /// Seek to an offset relative to the end of the file.
335     ///
336     /// NOTE: This function is NOT thread safe, other threads that
337     /// access this object might also change the current file position.
338     /// For thread safe reads and writes see the following functions:
339     /// @see File::Read (void *, size_t, off_t &)
340     /// @see File::Write (const void *, size_t, off_t &)
341     ///
342     /// @param[in,out] offset
343     ///     The offset to seek to within the file relative to the
344     ///     end of the file which gets filled in with the resulting
345     ///     absolute file offset.
346     ///
347     /// @param[in] error_ptr
348     ///     A pointer to a lldb_private::Error object that will be
349     ///     filled in if non-nullptr.
350     ///
351     /// @return
352     ///     The resulting seek offset, or -1 on error.
353     //------------------------------------------------------------------
354     off_t
355     SeekFromEnd(off_t offset, Error *error_ptr = nullptr);
356 
357     //------------------------------------------------------------------
358     /// Read bytes from a file from the specified file offset.
359     ///
360     /// NOTE: This function is thread safe in that clients manager their
361     /// own file position markers and reads on other threads won't mess
362     /// up the current read.
363     ///
364     /// @param[in] dst
365     ///     A buffer where to put the bytes that are read.
366     ///
367     /// @param[in,out] num_bytes
368     ///     The number of bytes to read form the current file position
369     ///     which gets modified with the number of bytes that were read.
370     ///
371     /// @param[in,out] offset
372     ///     The offset within the file from which to read \a num_bytes
373     ///     bytes. This offset gets incremented by the number of bytes
374     ///     that were read.
375     ///
376     /// @return
377     ///     An error object that indicates success or the reason for
378     ///     failure.
379     //------------------------------------------------------------------
380     Error
381     Read (void *dst, size_t &num_bytes, off_t &offset);
382 
383     //------------------------------------------------------------------
384     /// Read bytes from a file from the specified file offset.
385     ///
386     /// NOTE: This function is thread safe in that clients manager their
387     /// own file position markers and reads on other threads won't mess
388     /// up the current read.
389     ///
390     /// @param[in,out] num_bytes
391     ///     The number of bytes to read form the current file position
392     ///     which gets modified with the number of bytes that were read.
393     ///
394     /// @param[in,out] offset
395     ///     The offset within the file from which to read \a num_bytes
396     ///     bytes. This offset gets incremented by the number of bytes
397     ///     that were read.
398     ///
399     /// @param[in] null_terminate
400     ///     Ensure that the data that is read is terminated with a NULL
401     ///     character so that the data can be used as a C string.
402     ///
403     /// @param[out] data_buffer_sp
404     ///     A data buffer to create and fill in that will contain any
405     ///     data that is read from the file. This buffer will be reset
406     ///     if an error occurs.
407     ///
408     /// @return
409     ///     An error object that indicates success or the reason for
410     ///     failure.
411     //------------------------------------------------------------------
412     Error
413     Read (size_t &num_bytes,
414           off_t &offset,
415           bool null_terminate,
416           lldb::DataBufferSP &data_buffer_sp);
417 
418     //------------------------------------------------------------------
419     /// Write bytes to a file at the specified file offset.
420     ///
421     /// NOTE: This function is thread safe in that clients manager their
422     /// own file position markers, though clients will need to implement
423     /// their own locking externally to avoid multiple people writing
424     /// to the file at the same time.
425     ///
426     /// @param[in] src
427     ///     A buffer containing the bytes to write.
428     ///
429     /// @param[in,out] num_bytes
430     ///     The number of bytes to write to the file at offset \a offset.
431     ///     \a num_bytes gets modified with the number of bytes that
432     ///     were read.
433     ///
434     /// @param[in,out] offset
435     ///     The offset within the file at which to write \a num_bytes
436     ///     bytes. This offset gets incremented by the number of bytes
437     ///     that were written.
438     ///
439     /// @return
440     ///     An error object that indicates success or the reason for
441     ///     failure.
442     //------------------------------------------------------------------
443     Error
444     Write (const void *src, size_t &num_bytes, off_t &offset);
445 
446     //------------------------------------------------------------------
447     /// Flush the current stream
448     ///
449     /// @return
450     ///     An error object that indicates success or the reason for
451     ///     failure.
452     //------------------------------------------------------------------
453     Error
454     Flush ();
455 
456     //------------------------------------------------------------------
457     /// Sync to disk.
458     ///
459     /// @return
460     ///     An error object that indicates success or the reason for
461     ///     failure.
462     //------------------------------------------------------------------
463     Error
464     Sync ();
465 
466     //------------------------------------------------------------------
467     /// Get the permissions for a this file.
468     ///
469     /// @return
470     ///     Bits logical OR'ed together from the permission bits defined
471     ///     in lldb_private::File::Permissions.
472     //------------------------------------------------------------------
473     uint32_t
474     GetPermissions(Error &error) const;
475 
476     static uint32_t
477     GetPermissions(const FileSpec &file_spec, Error &error);
478 
479     //------------------------------------------------------------------
480     /// Return true if this file is interactive.
481     ///
482     /// @return
483     ///     True if this file is a terminal (tty or pty), false
484     ///     otherwise.
485     //------------------------------------------------------------------
486     bool
487     GetIsInteractive ();
488 
489     //------------------------------------------------------------------
490     /// Return true if this file from a real terminal.
491     ///
492     /// Just knowing a file is a interactive isn't enough, we also need
493     /// to know if the terminal has a width and height so we can do
494     /// cursor movement and other terminal manipulations by sending
495     /// escape sequences.
496     ///
497     /// @return
498     ///     True if this file is a terminal (tty, not a pty) that has
499     ///     a non-zero width and height, false otherwise.
500     //------------------------------------------------------------------
501     bool
502     GetIsRealTerminal ();
503 
504     bool
505     GetIsTerminalWithColors ();
506 
507     //------------------------------------------------------------------
508     /// Output printf formatted output to the stream.
509     ///
510     /// Print some formatted output to the stream.
511     ///
512     /// @param[in] format
513     ///     A printf style format string.
514     ///
515     /// @param[in] ...
516     ///     Variable arguments that are needed for the printf style
517     ///     format string \a format.
518     //------------------------------------------------------------------
519     size_t
520     Printf (const char *format, ...)  __attribute__ ((format (printf, 2, 3)));
521 
522     size_t
523     PrintfVarArg(const char *format, va_list args);
524 
525     void
526     SetOptions (uint32_t options)
527     {
528         m_options = options;
529     }
530 
531 protected:
532     bool
533     DescriptorIsValid () const
534     {
535         return m_descriptor >= 0;
536     }
537 
538     bool
539     StreamIsValid () const
540     {
541         return m_stream != kInvalidStream;
542     }
543 
544     void
545     CalculateInteractiveAndTerminal ();
546 
547     //------------------------------------------------------------------
548     // Member variables
549     //------------------------------------------------------------------
550     int m_descriptor;
551     FILE *m_stream;
552     uint32_t m_options;
553     bool m_own_stream;
554     LazyBool m_is_interactive;
555     LazyBool m_is_real_terminal;
556     LazyBool m_supports_colors;
557 };
558 
559 } // namespace lldb_private
560 
561 #endif // liblldb_File_h_
562