xref: /minix/external/bsd/atf/dist/tools/fs.hpp (revision 0a6a1f1d)
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(TOOLS_FS_HPP)
31 #define TOOLS_FS_HPP
32 
33 extern "C" {
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 }
37 
38 #include <map>
39 #include <memory>
40 #include <ostream>
41 #include <set>
42 #include <stdexcept>
43 #include <string>
44 
45 namespace tools {
46 namespace fs {
47 
48 // ------------------------------------------------------------------------
49 // The "path" class.
50 // ------------------------------------------------------------------------
51 
52 //!
53 //! \brief A class to represent a path to a file.
54 //!
55 //! The path class represents the route to a file or directory in the
56 //! file system.  All file manipulation operations use this class to
57 //! represent their arguments as it takes care of normalizing user-provided
58 //! strings and ensures they are valid.
59 //!
60 //! It is important to note that the file pointed to by a path need not
61 //! exist.
62 //!
63 class path {
64     //!
65     //! \brief Internal representation of a path.
66     //!
67     std::string m_data;
68 
69 public:
70     //! \brief Constructs a new path from a user-provided string.
71     //!
72     //! This constructor takes a string, either provided by the program's
73     //! code or by the user and constructs a new path object.  The string
74     //! is normalized to not contain multiple delimiters together and to
75     //! remove any trailing one.
76     //!
77     //! The input string cannot be empty.
78     //!
79     explicit path(const std::string&);
80 
81     //!
82     //! \brief Destructor for the path class.
83     //!
84     ~path(void);
85 
86     //!
87     //! \brief Returns a pointer to a C-style string representing this path.
88     //!
89     const char* c_str(void) const;
90 
91     //!
92     //! \brief Returns a string representing this path.
93     //! XXX Really needed?
94     //!
95     std::string str(void) const;
96 
97     //!
98     //! \brief Returns the branch path of this path.
99     //!
100     //! Calculates and returns the branch path of this path.  In other
101     //! words, it returns what the standard ::dirname function would return.
102     //!
103     path branch_path(void) const;
104 
105     //!
106     //! \brief Returns the leaf name of this path.
107     //!
108     //! Calculates and returns the leaf name of this path.  In other words,
109     //! it returns what the standard ::basename function would return.
110     //!
111     std::string leaf_name(void) const;
112 
113     //!
114     //! \brief Checks whether this path is absolute or not.
115     //!
116     //! Returns a boolean indicating if this is an absolute path or not;
117     //! i.e. if it starts with a slash.
118     //!
119     bool is_absolute(void) const;
120 
121     //!
122     //! \brief Checks whether this path points to the root directory or not.
123     //!
124     //! Returns a boolean indicating if this is path points to the root
125     //! directory or not.  The checks made by this are extremely simple (so
126     //! the results cannot always be trusted) but they are enough for our
127     //! modest sanity-checking needs.  I.e. "/../" could return false.
128     //!
129     bool is_root(void) const;
130 
131     //!
132     //! \brief Converts the path to be absolute.
133     //!
134     //! \pre The path was not absolute.
135     //!
136     path to_absolute(void) const;
137 
138     //!
139     //! \brief Checks if two paths are equal.
140     //!
141     bool operator==(const path&) const;
142 
143     //!
144     //! \brief Checks if two paths are different.
145     //!
146     bool operator!=(const path&) const;
147 
148     //!
149     //! \brief Concatenates a path with a string.
150     //!
151     //! Constructs a new path object that is the concatenation of the
152     //! left-hand path with the right-hand string.  The string is normalized
153     //! before the concatenation, and a path delimiter is introduced between
154     //! the two components if needed.
155     //!
156     path operator/(const std::string&) const;
157 
158     //!
159     //! \brief Concatenates a path with another path.
160     //!
161     //! Constructs a new path object that is the concatenation of the
162     //! left-hand path with the right-hand one. A path delimiter is
163     //! introduced between the two components if needed.
164     //!
165     path operator/(const path&) const;
166 
167     //!
168     //! \brief Checks if a path has to be sorted before another one
169     //!        lexicographically.
170     //!
171     bool operator<(const path&) const;
172 };
173 
174 // ------------------------------------------------------------------------
175 // The "file_info" class.
176 // ------------------------------------------------------------------------
177 
178 class directory;
179 
180 //!
181 //! \brief A class that contains information about a file.
182 //!
183 //! The file_info class holds information about an specific file that
184 //! exists in the file system.
185 //!
186 class file_info {
187     int m_type;
188     struct stat m_sb;
189 
190 public:
191     //!
192     //! \brief The file's type.
193     //!
194     static const int blk_type;
195     static const int chr_type;
196     static const int dir_type;
197     static const int fifo_type;
198     static const int lnk_type;
199     static const int reg_type;
200     static const int sock_type;
201     static const int wht_type;
202 
203     //!
204     //! \brief Constructs a new file_info based on a given file.
205     //!
206     //! This constructor creates a new file_info object and fills it with
207     //! the data returned by ::stat when run on the given file, which must
208     //! exist.
209     //!
210     explicit file_info(const path&);
211 
212     //!
213     //! \brief The destructor.
214     //!
215     ~file_info(void);
216 
217     //!
218     //! \brief Returns the device containing the file.
219     //!
220     dev_t get_device(void) const;
221 
222     //!
223     //! \brief Returns the file's inode.
224     //!
225     ino_t get_inode(void) const;
226 
227     //!
228     //! \brief Returns the file's permissions.
229     //!
230     mode_t get_mode(void) const;
231 
232     //!
233     //! \brief Returns the file's size.
234     //!
235     off_t get_size(void) const;
236 
237     //!
238     //! \brief Returns the file's type.
239     //!
240     int get_type(void) const;
241 
242     //!
243     //! \brief Returns whether the file is readable by its owner or not.
244     //!
245     bool is_owner_readable(void) const;
246 
247     //!
248     //! \brief Returns whether the file is writable by its owner or not.
249     //!
250     bool is_owner_writable(void) const;
251 
252     //!
253     //! \brief Returns whether the file is executable by its owner or not.
254     //!
255     bool is_owner_executable(void) const;
256 
257     //!
258     //! \brief Returns whether the file is readable by the users belonging
259     //! to its group or not.
260     //!
261     bool is_group_readable(void) const;
262 
263     //!
264     //! \brief Returns whether the file is writable the users belonging to
265     //! its group or not.
266     //!
267     bool is_group_writable(void) const;
268 
269     //!
270     //! \brief Returns whether the file is executable by the users
271     //! belonging to its group or not.
272     //!
273     bool is_group_executable(void) const;
274 
275     //!
276     //! \brief Returns whether the file is readable by people different
277     //! than the owner and those belonging to the group or not.
278     //!
279     bool is_other_readable(void) const;
280 
281     //!
282     //! \brief Returns whether the file is write by people different
283     //! than the owner and those belonging to the group or not.
284     //!
285     bool is_other_writable(void) const;
286 
287     //!
288     //! \brief Returns whether the file is executable by people different
289     //! than the owner and those belonging to the group or not.
290     //!
291     bool is_other_executable(void) const;
292 };
293 
294 // ------------------------------------------------------------------------
295 // The "directory" class.
296 // ------------------------------------------------------------------------
297 
298 //!
299 //! \brief A class representing a file system directory.
300 //!
301 //! The directory class represents a group of files in the file system and
302 //! corresponds to exactly one directory.
303 //!
304 class directory : public std::map< std::string, file_info > {
305 public:
306     //!
307     //! \brief Constructs a new directory.
308     //!
309     //! Constructs a new directory object representing the given path.
310     //! The directory must exist at creation time as the contents of the
311     //! class are gathered from it.
312     //!
313     directory(const path&);
314 
315     //!
316     //! \brief Returns the file names of the files in the directory.
317     //!
318     //! Returns the leaf names of all files contained in the directory.
319     //! I.e. the keys of the directory map.
320     //!
321     std::set< std::string > names(void) const;
322 };
323 
324 // ------------------------------------------------------------------------
325 // The "temp_dir" class.
326 // ------------------------------------------------------------------------
327 
328 class temp_dir {
329     std::auto_ptr< tools::fs::path > m_path;
330 
331 public:
332     temp_dir(const tools::fs::path&);
333     ~temp_dir(void);
334 
335     const tools::fs::path& get_path(void) const;
336 };
337 
338 // ------------------------------------------------------------------------
339 // Free functions.
340 // ------------------------------------------------------------------------
341 
342 //!
343 //! \brief Checks if the given path exists.
344 //!
345 bool exists(const path&);
346 
347 //!
348 //! \brief Looks for the given program in the PATH.
349 //!
350 //! Given a program name (without slashes) looks for it in the path and
351 //! returns its full path name if found, otherwise an empty path.
352 //!
353 bool have_prog_in_path(const std::string&);
354 
355 //!
356 //! \brief Checks if the given path exists, is accessible and is executable.
357 //!
358 bool is_executable(const path&);
359 
360 //!
361 //! \brief Removes a given file.
362 //!
363 void remove(const path&);
364 
365 //!
366 //! \brief Removes an empty directory.
367 //!
368 void rmdir(const path&);
369 
370 tools::fs::path change_directory(const tools::fs::path&);
371 void cleanup(const tools::fs::path&);
372 tools::fs::path get_current_dir(void);
373 
374 } // namespace fs
375 } // namespace tools
376 
377 #endif // !defined(TOOLS_FS_HPP)
378