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