xref: /freebsd/contrib/atf/atf-c++/detail/fs.hpp (revision a0409676120c1e558d0ade943019934e0f15118d)
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 
29 extern "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 
40 extern "C" {
41 #include "atf-c/detail/fs.h"
42 }
43 
44 namespace atf {
45 
46 namespace io {
47 class systembuf;
48 } // namespace io
49 
50 namespace 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 //!
67 class path {
68     //!
69     //! \brief Internal representation of a path.
70     //!
71     atf_fs_path_t m_path;
72 
73 public:
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 
202 class 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 //!
210 class file_info {
211     atf_fs_stat_t m_stat;
212 
213 public:
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 //!
332 class directory : public std::map< std::string, file_info > {
333 public:
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 //!
359 bool 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 //!
367 bool have_prog_in_path(const std::string&);
368 
369 //!
370 //! \brief Checks if the given path exists, is accessible and is executable.
371 //!
372 bool is_executable(const path&);
373 
374 //!
375 //! \brief Removes a given file.
376 //!
377 void remove(const path&);
378 
379 //!
380 //! \brief Removes an empty directory.
381 //!
382 void rmdir(const path&);
383 
384 } // namespace fs
385 } // namespace atf
386 
387 #endif // !defined(ATF_CXX_DETAIL_FS_HPP)
388