fs.hpp revision 275988
1// Copyright (c) 2007 The NetBSD Foundation, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1. Redistributions of source code must retain the above copyright
8//    notice, this list of conditions and the following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright
10//    notice, this list of conditions and the following disclaimer in the
11//    documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26#if !defined(ATF_CXX_DETAIL_FS_HPP)
27#define ATF_CXX_DETAIL_FS_HPP
28
29extern "C" {
30#include <sys/types.h>
31}
32
33#include <map>
34#include <memory>
35#include <ostream>
36#include <set>
37#include <stdexcept>
38#include <string>
39
40extern "C" {
41#include "atf-c/detail/fs.h"
42}
43
44namespace atf {
45
46namespace io {
47class systembuf;
48} // namespace io
49
50namespace fs {
51
52// ------------------------------------------------------------------------
53// The "path" class.
54// ------------------------------------------------------------------------
55
56//!
57//! \brief A class to represent a path to a file.
58//!
59//! The path class represents the route to a file or directory in the
60//! file system.  All file manipulation operations use this class to
61//! represent their arguments as it takes care of normalizing user-provided
62//! strings and ensures they are valid.
63//!
64//! It is important to note that the file pointed to by a path need not
65//! exist.
66//!
67class path {
68    //!
69    //! \brief Internal representation of a path.
70    //!
71    atf_fs_path_t m_path;
72
73public:
74    //! \brief Constructs a new path from a user-provided string.
75    //!
76    //! This constructor takes a string, either provided by the program's
77    //! code or by the user and constructs a new path object.  The string
78    //! is normalized to not contain multiple delimiters together and to
79    //! remove any trailing one.
80    //!
81    //! The input string cannot be empty.
82    //!
83    explicit path(const std::string&);
84
85    //!
86    //! \brief Copy constructor.
87    //!
88    path(const path&);
89
90    //!
91    //! \brief Copy constructor.
92    //!
93    path(const atf_fs_path_t *);
94
95    //!
96    //! \brief Destructor for the path class.
97    //!
98    ~path(void);
99
100    //!
101    //! \brief Returns a pointer to a C-style string representing this path.
102    //!
103    const char* c_str(void) const;
104
105    //!
106    //! \brief Returns a pointer to the implementation data.
107    //!
108    const atf_fs_path_t* c_path(void) const;
109
110    //!
111    //! \brief Returns a string representing this path.
112    //! XXX Really needed?
113    //!
114    std::string str(void) const;
115
116    //!
117    //! \brief Returns the branch path of this path.
118    //!
119    //! Calculates and returns the branch path of this path.  In other
120    //! words, it returns what the standard ::dirname function would return.
121    //!
122    path branch_path(void) const;
123
124    //!
125    //! \brief Returns the leaf name of this path.
126    //!
127    //! Calculates and returns the leaf name of this path.  In other words,
128    //! it returns what the standard ::basename function would return.
129    //!
130    std::string leaf_name(void) const;
131
132    //!
133    //! \brief Checks whether this path is absolute or not.
134    //!
135    //! Returns a boolean indicating if this is an absolute path or not;
136    //! i.e. if it starts with a slash.
137    //!
138    bool is_absolute(void) const;
139
140    //!
141    //! \brief Checks whether this path points to the root directory or not.
142    //!
143    //! Returns a boolean indicating if this is path points to the root
144    //! directory or not.  The checks made by this are extremely simple (so
145    //! the results cannot always be trusted) but they are enough for our
146    //! modest sanity-checking needs.  I.e. "/../" could return false.
147    //!
148    bool is_root(void) const;
149
150    //!
151    //! \brief Converts the path to be absolute.
152    //!
153    //! \pre The path was not absolute.
154    //!
155    path to_absolute(void) const;
156
157    //!
158    //! \brief Assignment operator.
159    //!
160    path& operator=(const path&);
161
162    //!
163    //! \brief Checks if two paths are equal.
164    //!
165    bool operator==(const path&) const;
166
167    //!
168    //! \brief Checks if two paths are different.
169    //!
170    bool operator!=(const path&) const;
171
172    //!
173    //! \brief Concatenates a path with a string.
174    //!
175    //! Constructs a new path object that is the concatenation of the
176    //! left-hand path with the right-hand string.  The string is normalized
177    //! before the concatenation, and a path delimiter is introduced between
178    //! the two components if needed.
179    //!
180    path operator/(const std::string&) const;
181
182    //!
183    //! \brief Concatenates a path with another path.
184    //!
185    //! Constructs a new path object that is the concatenation of the
186    //! left-hand path with the right-hand one. A path delimiter is
187    //! introduced between the two components if needed.
188    //!
189    path operator/(const path&) const;
190
191    //!
192    //! \brief Checks if a path has to be sorted before another one
193    //!        lexicographically.
194    //!
195    bool operator<(const path&) const;
196};
197
198// ------------------------------------------------------------------------
199// The "file_info" class.
200// ------------------------------------------------------------------------
201
202class directory;
203
204//!
205//! \brief A class that contains information about a file.
206//!
207//! The file_info class holds information about an specific file that
208//! exists in the file system.
209//!
210class file_info {
211    atf_fs_stat_t m_stat;
212
213public:
214    //!
215    //! \brief The file's type.
216    //!
217    static const int blk_type;
218    static const int chr_type;
219    static const int dir_type;
220    static const int fifo_type;
221    static const int lnk_type;
222    static const int reg_type;
223    static const int sock_type;
224    static const int wht_type;
225
226    //!
227    //! \brief Constructs a new file_info based on a given file.
228    //!
229    //! This constructor creates a new file_info object and fills it with
230    //! the data returned by ::stat when run on the given file, which must
231    //! exist.
232    //!
233    explicit file_info(const path&);
234
235    //!
236    //! \brief The copy constructor.
237    //!
238    file_info(const file_info&);
239
240    //!
241    //! \brief The destructor.
242    //!
243    ~file_info(void);
244
245    //!
246    //! \brief Returns the device containing the file.
247    //!
248    dev_t get_device(void) const;
249
250    //!
251    //! \brief Returns the file's inode.
252    //!
253    ino_t get_inode(void) const;
254
255    //!
256    //! \brief Returns the file's permissions.
257    //!
258    mode_t get_mode(void) const;
259
260    //!
261    //! \brief Returns the file's size.
262    //!
263    off_t get_size(void) const;
264
265    //!
266    //! \brief Returns the file's type.
267    //!
268    int get_type(void) const;
269
270    //!
271    //! \brief Returns whether the file is readable by its owner or not.
272    //!
273    bool is_owner_readable(void) const;
274
275    //!
276    //! \brief Returns whether the file is writable by its owner or not.
277    //!
278    bool is_owner_writable(void) const;
279
280    //!
281    //! \brief Returns whether the file is executable by its owner or not.
282    //!
283    bool is_owner_executable(void) const;
284
285    //!
286    //! \brief Returns whether the file is readable by the users belonging
287    //! to its group or not.
288    //!
289    bool is_group_readable(void) const;
290
291    //!
292    //! \brief Returns whether the file is writable the users belonging to
293    //! its group or not.
294    //!
295    bool is_group_writable(void) const;
296
297    //!
298    //! \brief Returns whether the file is executable by the users
299    //! belonging to its group or not.
300    //!
301    bool is_group_executable(void) const;
302
303    //!
304    //! \brief Returns whether the file is readable by people different
305    //! than the owner and those belonging to the group or not.
306    //!
307    bool is_other_readable(void) const;
308
309    //!
310    //! \brief Returns whether the file is write by people different
311    //! than the owner and those belonging to the group or not.
312    //!
313    bool is_other_writable(void) const;
314
315    //!
316    //! \brief Returns whether the file is executable by people different
317    //! than the owner and those belonging to the group or not.
318    //!
319    bool is_other_executable(void) const;
320};
321
322// ------------------------------------------------------------------------
323// The "directory" class.
324// ------------------------------------------------------------------------
325
326//!
327//! \brief A class representing a file system directory.
328//!
329//! The directory class represents a group of files in the file system and
330//! corresponds to exactly one directory.
331//!
332class directory : public std::map< std::string, file_info > {
333public:
334    //!
335    //! \brief Constructs a new directory.
336    //!
337    //! Constructs a new directory object representing the given path.
338    //! The directory must exist at creation time as the contents of the
339    //! class are gathered from it.
340    //!
341    directory(const path&);
342
343    //!
344    //! \brief Returns the file names of the files in the directory.
345    //!
346    //! Returns the leaf names of all files contained in the directory.
347    //! I.e. the keys of the directory map.
348    //!
349    std::set< std::string > names(void) const;
350};
351
352// ------------------------------------------------------------------------
353// Free functions.
354// ------------------------------------------------------------------------
355
356//!
357//! \brief Checks if the given path exists.
358//!
359bool exists(const path&);
360
361//!
362//! \brief Looks for the given program in the PATH.
363//!
364//! Given a program name (without slashes) looks for it in the path and
365//! returns its full path name if found, otherwise an empty path.
366//!
367bool have_prog_in_path(const std::string&);
368
369//!
370//! \brief Checks if the given path exists, is accessible and is executable.
371//!
372bool is_executable(const path&);
373
374//!
375//! \brief Removes a given file.
376//!
377void remove(const path&);
378
379//!
380//! \brief Removes an empty directory.
381//!
382void rmdir(const path&);
383
384} // namespace fs
385} // namespace atf
386
387#endif // !defined(ATF_CXX_DETAIL_FS_HPP)
388