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