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