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