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