xref: /freebsd/contrib/atf/atf-c++/detail/fs.cpp (revision 8f0ea33f2bbf3a6aa80235f0a02fa5f2780c2b17)
1c243e490SMarcel Moolenaar // Copyright (c) 2007 The NetBSD Foundation, Inc.
2c243e490SMarcel Moolenaar // All rights reserved.
3c243e490SMarcel Moolenaar //
4c243e490SMarcel Moolenaar // Redistribution and use in source and binary forms, with or without
5c243e490SMarcel Moolenaar // modification, are permitted provided that the following conditions
6c243e490SMarcel Moolenaar // are met:
7c243e490SMarcel Moolenaar // 1. Redistributions of source code must retain the above copyright
8c243e490SMarcel Moolenaar //    notice, this list of conditions and the following disclaimer.
9c243e490SMarcel Moolenaar // 2. Redistributions in binary form must reproduce the above copyright
10c243e490SMarcel Moolenaar //    notice, this list of conditions and the following disclaimer in the
11c243e490SMarcel Moolenaar //    documentation and/or other materials provided with the distribution.
12c243e490SMarcel Moolenaar //
13c243e490SMarcel Moolenaar // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14c243e490SMarcel Moolenaar // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15c243e490SMarcel Moolenaar // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16c243e490SMarcel Moolenaar // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17c243e490SMarcel Moolenaar // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18c243e490SMarcel Moolenaar // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19c243e490SMarcel Moolenaar // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20c243e490SMarcel Moolenaar // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21c243e490SMarcel Moolenaar // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22c243e490SMarcel Moolenaar // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23c243e490SMarcel Moolenaar // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24c243e490SMarcel Moolenaar // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*0677dfd1SJulio Merino 
26*0677dfd1SJulio Merino #include "atf-c++/detail/fs.hpp"
27c243e490SMarcel Moolenaar 
28c243e490SMarcel Moolenaar #if defined(HAVE_CONFIG_H)
29*0677dfd1SJulio Merino #include "config.h"
30c243e490SMarcel Moolenaar #endif
31c243e490SMarcel Moolenaar 
32c243e490SMarcel Moolenaar extern "C" {
33c243e490SMarcel Moolenaar #include <sys/param.h>
34c243e490SMarcel Moolenaar #include <sys/types.h>
35c243e490SMarcel Moolenaar #include <sys/mount.h>
36c243e490SMarcel Moolenaar #include <sys/stat.h>
37c243e490SMarcel Moolenaar #include <sys/wait.h>
38c243e490SMarcel Moolenaar #include <dirent.h>
39c243e490SMarcel Moolenaar #include <libgen.h>
40c243e490SMarcel Moolenaar #include <unistd.h>
41c243e490SMarcel Moolenaar }
42c243e490SMarcel Moolenaar 
43c243e490SMarcel Moolenaar #include <cerrno>
44c243e490SMarcel Moolenaar #include <cstdlib>
45c243e490SMarcel Moolenaar #include <cstring>
46c243e490SMarcel Moolenaar 
47c243e490SMarcel Moolenaar extern "C" {
48*0677dfd1SJulio Merino #include "atf-c/error.h"
49c243e490SMarcel Moolenaar }
50c243e490SMarcel Moolenaar 
51*0677dfd1SJulio Merino #include "atf-c++/detail/env.hpp"
52*0677dfd1SJulio Merino #include "atf-c++/detail/exceptions.hpp"
53*0677dfd1SJulio Merino #include "atf-c++/detail/process.hpp"
54*0677dfd1SJulio Merino #include "atf-c++/detail/sanity.hpp"
55*0677dfd1SJulio Merino #include "atf-c++/detail/text.hpp"
56*0677dfd1SJulio Merino #include "atf-c++/utils.hpp"
57c243e490SMarcel Moolenaar 
58c243e490SMarcel Moolenaar namespace impl = atf::fs;
59c243e490SMarcel Moolenaar #define IMPL_NAME "atf::fs"
60c243e490SMarcel Moolenaar 
61c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
62c243e490SMarcel Moolenaar // Auxiliary functions.
63c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
64c243e490SMarcel Moolenaar 
65c243e490SMarcel Moolenaar static bool safe_access(const impl::path&, int, int);
66c243e490SMarcel Moolenaar 
67c243e490SMarcel Moolenaar //!
68c243e490SMarcel Moolenaar //! \brief A controlled version of access(2).
69c243e490SMarcel Moolenaar //!
70c243e490SMarcel Moolenaar //! This function reimplements the standard access(2) system call to
71c243e490SMarcel Moolenaar //! safely control its exit status and raise an exception in case of
72c243e490SMarcel Moolenaar //! failure.
73c243e490SMarcel Moolenaar //!
74c243e490SMarcel Moolenaar static
75c243e490SMarcel Moolenaar bool
safe_access(const impl::path & p,int mode,int experr)76c243e490SMarcel Moolenaar safe_access(const impl::path& p, int mode, int experr)
77c243e490SMarcel Moolenaar {
78c243e490SMarcel Moolenaar     bool ok;
79c243e490SMarcel Moolenaar 
80c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_eaccess(p.c_path(), mode);
81c243e490SMarcel Moolenaar     if (atf_is_error(err)) {
82c243e490SMarcel Moolenaar         if (atf_error_is(err, "libc")) {
83c243e490SMarcel Moolenaar             if (atf_libc_error_code(err) == experr) {
84c243e490SMarcel Moolenaar                 atf_error_free(err);
85c243e490SMarcel Moolenaar                 ok = false;
86c243e490SMarcel Moolenaar             } else {
87c243e490SMarcel Moolenaar                 atf::throw_atf_error(err);
88c243e490SMarcel Moolenaar                 // XXX Silence warning; maybe throw_atf_error should be
89c243e490SMarcel Moolenaar                 // an exception and not a function.
90c243e490SMarcel Moolenaar                 ok = false;
91c243e490SMarcel Moolenaar             }
92c243e490SMarcel Moolenaar         } else {
93c243e490SMarcel Moolenaar             atf::throw_atf_error(err);
94c243e490SMarcel Moolenaar             // XXX Silence warning; maybe throw_atf_error should be
95c243e490SMarcel Moolenaar             // an exception and not a function.
96c243e490SMarcel Moolenaar             ok = false;
97c243e490SMarcel Moolenaar         }
98c243e490SMarcel Moolenaar     } else
99c243e490SMarcel Moolenaar         ok = true;
100c243e490SMarcel Moolenaar 
101c243e490SMarcel Moolenaar     return ok;
102c243e490SMarcel Moolenaar }
103c243e490SMarcel Moolenaar 
104c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
105c243e490SMarcel Moolenaar // The "path" class.
106c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
107c243e490SMarcel Moolenaar 
path(const std::string & s)108c243e490SMarcel Moolenaar impl::path::path(const std::string& s)
109c243e490SMarcel Moolenaar {
110c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_path_init_fmt(&m_path, "%s", s.c_str());
111c243e490SMarcel Moolenaar     if (atf_is_error(err))
112c243e490SMarcel Moolenaar         throw_atf_error(err);
113c243e490SMarcel Moolenaar }
114c243e490SMarcel Moolenaar 
path(const path & p)115c243e490SMarcel Moolenaar impl::path::path(const path& p)
116c243e490SMarcel Moolenaar {
117c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_path_copy(&m_path, &p.m_path);
118c243e490SMarcel Moolenaar     if (atf_is_error(err))
119c243e490SMarcel Moolenaar         throw_atf_error(err);
120c243e490SMarcel Moolenaar }
121c243e490SMarcel Moolenaar 
path(const atf_fs_path_t * p)122c243e490SMarcel Moolenaar impl::path::path(const atf_fs_path_t *p)
123c243e490SMarcel Moolenaar {
124c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_path_copy(&m_path, p);
125c243e490SMarcel Moolenaar     if (atf_is_error(err))
126c243e490SMarcel Moolenaar         throw_atf_error(err);
127c243e490SMarcel Moolenaar }
128c243e490SMarcel Moolenaar 
~path(void)129c243e490SMarcel Moolenaar impl::path::~path(void)
130c243e490SMarcel Moolenaar {
131c243e490SMarcel Moolenaar     atf_fs_path_fini(&m_path);
132c243e490SMarcel Moolenaar }
133c243e490SMarcel Moolenaar 
134c243e490SMarcel Moolenaar const char*
c_str(void) const135c243e490SMarcel Moolenaar impl::path::c_str(void)
136c243e490SMarcel Moolenaar     const
137c243e490SMarcel Moolenaar {
138c243e490SMarcel Moolenaar     return atf_fs_path_cstring(&m_path);
139c243e490SMarcel Moolenaar }
140c243e490SMarcel Moolenaar 
141c243e490SMarcel Moolenaar const atf_fs_path_t*
c_path(void) const142c243e490SMarcel Moolenaar impl::path::c_path(void)
143c243e490SMarcel Moolenaar     const
144c243e490SMarcel Moolenaar {
145c243e490SMarcel Moolenaar     return &m_path;
146c243e490SMarcel Moolenaar }
147c243e490SMarcel Moolenaar 
148c243e490SMarcel Moolenaar std::string
str(void) const149c243e490SMarcel Moolenaar impl::path::str(void)
150c243e490SMarcel Moolenaar     const
151c243e490SMarcel Moolenaar {
152c243e490SMarcel Moolenaar     return c_str();
153c243e490SMarcel Moolenaar }
154c243e490SMarcel Moolenaar 
155c243e490SMarcel Moolenaar bool
is_absolute(void) const156c243e490SMarcel Moolenaar impl::path::is_absolute(void)
157c243e490SMarcel Moolenaar     const
158c243e490SMarcel Moolenaar {
159c243e490SMarcel Moolenaar     return atf_fs_path_is_absolute(&m_path);
160c243e490SMarcel Moolenaar }
161c243e490SMarcel Moolenaar 
162c243e490SMarcel Moolenaar bool
is_root(void) const163c243e490SMarcel Moolenaar impl::path::is_root(void)
164c243e490SMarcel Moolenaar     const
165c243e490SMarcel Moolenaar {
166c243e490SMarcel Moolenaar     return atf_fs_path_is_root(&m_path);
167c243e490SMarcel Moolenaar }
168c243e490SMarcel Moolenaar 
169c243e490SMarcel Moolenaar impl::path
branch_path(void) const170c243e490SMarcel Moolenaar impl::path::branch_path(void)
171c243e490SMarcel Moolenaar     const
172c243e490SMarcel Moolenaar {
173c243e490SMarcel Moolenaar     atf_fs_path_t bp;
174c243e490SMarcel Moolenaar     atf_error_t err;
175c243e490SMarcel Moolenaar 
176c243e490SMarcel Moolenaar     err = atf_fs_path_branch_path(&m_path, &bp);
177c243e490SMarcel Moolenaar     if (atf_is_error(err))
178c243e490SMarcel Moolenaar         throw_atf_error(err);
179c243e490SMarcel Moolenaar 
180c243e490SMarcel Moolenaar     path p(atf_fs_path_cstring(&bp));
181c243e490SMarcel Moolenaar     atf_fs_path_fini(&bp);
182c243e490SMarcel Moolenaar     return p;
183c243e490SMarcel Moolenaar }
184c243e490SMarcel Moolenaar 
185c243e490SMarcel Moolenaar std::string
leaf_name(void) const186c243e490SMarcel Moolenaar impl::path::leaf_name(void)
187c243e490SMarcel Moolenaar     const
188c243e490SMarcel Moolenaar {
189c243e490SMarcel Moolenaar     atf_dynstr_t ln;
190c243e490SMarcel Moolenaar     atf_error_t err;
191c243e490SMarcel Moolenaar 
192c243e490SMarcel Moolenaar     err = atf_fs_path_leaf_name(&m_path, &ln);
193c243e490SMarcel Moolenaar     if (atf_is_error(err))
194c243e490SMarcel Moolenaar         throw_atf_error(err);
195c243e490SMarcel Moolenaar 
196c243e490SMarcel Moolenaar     std::string s(atf_dynstr_cstring(&ln));
197c243e490SMarcel Moolenaar     atf_dynstr_fini(&ln);
198c243e490SMarcel Moolenaar     return s;
199c243e490SMarcel Moolenaar }
200c243e490SMarcel Moolenaar 
201c243e490SMarcel Moolenaar impl::path
to_absolute(void) const202c243e490SMarcel Moolenaar impl::path::to_absolute(void)
203c243e490SMarcel Moolenaar     const
204c243e490SMarcel Moolenaar {
205c243e490SMarcel Moolenaar     atf_fs_path_t pa;
206c243e490SMarcel Moolenaar 
207c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_path_to_absolute(&m_path, &pa);
208c243e490SMarcel Moolenaar     if (atf_is_error(err))
209c243e490SMarcel Moolenaar         throw_atf_error(err);
210c243e490SMarcel Moolenaar 
211c243e490SMarcel Moolenaar     path p(atf_fs_path_cstring(&pa));
212c243e490SMarcel Moolenaar     atf_fs_path_fini(&pa);
213c243e490SMarcel Moolenaar     return p;
214c243e490SMarcel Moolenaar }
215c243e490SMarcel Moolenaar 
216c243e490SMarcel Moolenaar impl::path&
operator =(const path & p)217c243e490SMarcel Moolenaar impl::path::operator=(const path& p)
218c243e490SMarcel Moolenaar {
219c243e490SMarcel Moolenaar     atf_fs_path_t tmp;
220c243e490SMarcel Moolenaar 
221c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_path_init_fmt(&tmp, "%s", p.c_str());
222c243e490SMarcel Moolenaar     if (atf_is_error(err))
223c243e490SMarcel Moolenaar         throw_atf_error(err);
224c243e490SMarcel Moolenaar     else {
225c243e490SMarcel Moolenaar         atf_fs_path_fini(&m_path);
226c243e490SMarcel Moolenaar         m_path = tmp;
227c243e490SMarcel Moolenaar     }
228c243e490SMarcel Moolenaar 
229c243e490SMarcel Moolenaar     return *this;
230c243e490SMarcel Moolenaar }
231c243e490SMarcel Moolenaar 
232c243e490SMarcel Moolenaar bool
operator ==(const path & p) const233c243e490SMarcel Moolenaar impl::path::operator==(const path& p)
234c243e490SMarcel Moolenaar     const
235c243e490SMarcel Moolenaar {
236c243e490SMarcel Moolenaar     return atf_equal_fs_path_fs_path(&m_path, &p.m_path);
237c243e490SMarcel Moolenaar }
238c243e490SMarcel Moolenaar 
239c243e490SMarcel Moolenaar bool
operator !=(const path & p) const240c243e490SMarcel Moolenaar impl::path::operator!=(const path& p)
241c243e490SMarcel Moolenaar     const
242c243e490SMarcel Moolenaar {
243c243e490SMarcel Moolenaar     return !atf_equal_fs_path_fs_path(&m_path, &p.m_path);
244c243e490SMarcel Moolenaar }
245c243e490SMarcel Moolenaar 
246c243e490SMarcel Moolenaar impl::path
operator /(const std::string & p) const247c243e490SMarcel Moolenaar impl::path::operator/(const std::string& p)
248c243e490SMarcel Moolenaar     const
249c243e490SMarcel Moolenaar {
250c243e490SMarcel Moolenaar     path p2 = *this;
251c243e490SMarcel Moolenaar 
252c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_path_append_fmt(&p2.m_path, "%s", p.c_str());
253c243e490SMarcel Moolenaar     if (atf_is_error(err))
254c243e490SMarcel Moolenaar         throw_atf_error(err);
255c243e490SMarcel Moolenaar 
256c243e490SMarcel Moolenaar     return p2;
257c243e490SMarcel Moolenaar }
258c243e490SMarcel Moolenaar 
259c243e490SMarcel Moolenaar impl::path
operator /(const path & p) const260c243e490SMarcel Moolenaar impl::path::operator/(const path& p)
261c243e490SMarcel Moolenaar     const
262c243e490SMarcel Moolenaar {
263c243e490SMarcel Moolenaar     path p2 = *this;
264c243e490SMarcel Moolenaar 
265c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_path_append_fmt(&p2.m_path, "%s",
266c243e490SMarcel Moolenaar                                              atf_fs_path_cstring(&p.m_path));
267c243e490SMarcel Moolenaar     if (atf_is_error(err))
268c243e490SMarcel Moolenaar         throw_atf_error(err);
269c243e490SMarcel Moolenaar 
270c243e490SMarcel Moolenaar     return p2;
271c243e490SMarcel Moolenaar }
272c243e490SMarcel Moolenaar 
273c243e490SMarcel Moolenaar bool
operator <(const path & p) const274c243e490SMarcel Moolenaar impl::path::operator<(const path& p)
275c243e490SMarcel Moolenaar     const
276c243e490SMarcel Moolenaar {
277c243e490SMarcel Moolenaar     const char *s1 = atf_fs_path_cstring(&m_path);
278c243e490SMarcel Moolenaar     const char *s2 = atf_fs_path_cstring(&p.m_path);
279c243e490SMarcel Moolenaar     return std::strcmp(s1, s2) < 0;
280c243e490SMarcel Moolenaar }
281c243e490SMarcel Moolenaar 
282c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
283c243e490SMarcel Moolenaar // The "file_info" class.
284c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
285c243e490SMarcel Moolenaar 
286c243e490SMarcel Moolenaar const int impl::file_info::blk_type = atf_fs_stat_blk_type;
287c243e490SMarcel Moolenaar const int impl::file_info::chr_type = atf_fs_stat_chr_type;
288c243e490SMarcel Moolenaar const int impl::file_info::dir_type = atf_fs_stat_dir_type;
289c243e490SMarcel Moolenaar const int impl::file_info::fifo_type = atf_fs_stat_fifo_type;
290c243e490SMarcel Moolenaar const int impl::file_info::lnk_type = atf_fs_stat_lnk_type;
291c243e490SMarcel Moolenaar const int impl::file_info::reg_type = atf_fs_stat_reg_type;
292c243e490SMarcel Moolenaar const int impl::file_info::sock_type = atf_fs_stat_sock_type;
293c243e490SMarcel Moolenaar const int impl::file_info::wht_type = atf_fs_stat_wht_type;
294c243e490SMarcel Moolenaar 
file_info(const path & p)295c243e490SMarcel Moolenaar impl::file_info::file_info(const path& p)
296c243e490SMarcel Moolenaar {
297c243e490SMarcel Moolenaar     atf_error_t err;
298c243e490SMarcel Moolenaar 
299c243e490SMarcel Moolenaar     err = atf_fs_stat_init(&m_stat, p.c_path());
300c243e490SMarcel Moolenaar     if (atf_is_error(err))
301c243e490SMarcel Moolenaar         throw_atf_error(err);
302c243e490SMarcel Moolenaar }
303c243e490SMarcel Moolenaar 
file_info(const file_info & fi)304c243e490SMarcel Moolenaar impl::file_info::file_info(const file_info& fi)
305c243e490SMarcel Moolenaar {
306c243e490SMarcel Moolenaar     atf_fs_stat_copy(&m_stat, &fi.m_stat);
307c243e490SMarcel Moolenaar }
308c243e490SMarcel Moolenaar 
~file_info(void)309c243e490SMarcel Moolenaar impl::file_info::~file_info(void)
310c243e490SMarcel Moolenaar {
311c243e490SMarcel Moolenaar     atf_fs_stat_fini(&m_stat);
312c243e490SMarcel Moolenaar }
313c243e490SMarcel Moolenaar 
314c243e490SMarcel Moolenaar dev_t
get_device(void) const315c243e490SMarcel Moolenaar impl::file_info::get_device(void)
316c243e490SMarcel Moolenaar     const
317c243e490SMarcel Moolenaar {
318c243e490SMarcel Moolenaar     return atf_fs_stat_get_device(&m_stat);
319c243e490SMarcel Moolenaar }
320c243e490SMarcel Moolenaar 
321c243e490SMarcel Moolenaar ino_t
get_inode(void) const322c243e490SMarcel Moolenaar impl::file_info::get_inode(void)
323c243e490SMarcel Moolenaar     const
324c243e490SMarcel Moolenaar {
325c243e490SMarcel Moolenaar     return atf_fs_stat_get_inode(&m_stat);
326c243e490SMarcel Moolenaar }
327c243e490SMarcel Moolenaar 
328c243e490SMarcel Moolenaar mode_t
get_mode(void) const329c243e490SMarcel Moolenaar impl::file_info::get_mode(void)
330c243e490SMarcel Moolenaar     const
331c243e490SMarcel Moolenaar {
332c243e490SMarcel Moolenaar     return atf_fs_stat_get_mode(&m_stat);
333c243e490SMarcel Moolenaar }
334c243e490SMarcel Moolenaar 
335c243e490SMarcel Moolenaar off_t
get_size(void) const336c243e490SMarcel Moolenaar impl::file_info::get_size(void)
337c243e490SMarcel Moolenaar     const
338c243e490SMarcel Moolenaar {
339c243e490SMarcel Moolenaar     return atf_fs_stat_get_size(&m_stat);
340c243e490SMarcel Moolenaar }
341c243e490SMarcel Moolenaar 
342c243e490SMarcel Moolenaar int
get_type(void) const343c243e490SMarcel Moolenaar impl::file_info::get_type(void)
344c243e490SMarcel Moolenaar     const
345c243e490SMarcel Moolenaar {
346c243e490SMarcel Moolenaar     return atf_fs_stat_get_type(&m_stat);
347c243e490SMarcel Moolenaar }
348c243e490SMarcel Moolenaar 
349c243e490SMarcel Moolenaar bool
is_owner_readable(void) const350c243e490SMarcel Moolenaar impl::file_info::is_owner_readable(void)
351c243e490SMarcel Moolenaar     const
352c243e490SMarcel Moolenaar {
353c243e490SMarcel Moolenaar     return atf_fs_stat_is_owner_readable(&m_stat);
354c243e490SMarcel Moolenaar }
355c243e490SMarcel Moolenaar 
356c243e490SMarcel Moolenaar bool
is_owner_writable(void) const357c243e490SMarcel Moolenaar impl::file_info::is_owner_writable(void)
358c243e490SMarcel Moolenaar     const
359c243e490SMarcel Moolenaar {
360c243e490SMarcel Moolenaar     return atf_fs_stat_is_owner_writable(&m_stat);
361c243e490SMarcel Moolenaar }
362c243e490SMarcel Moolenaar 
363c243e490SMarcel Moolenaar bool
is_owner_executable(void) const364c243e490SMarcel Moolenaar impl::file_info::is_owner_executable(void)
365c243e490SMarcel Moolenaar     const
366c243e490SMarcel Moolenaar {
367c243e490SMarcel Moolenaar     return atf_fs_stat_is_owner_executable(&m_stat);
368c243e490SMarcel Moolenaar }
369c243e490SMarcel Moolenaar 
370c243e490SMarcel Moolenaar bool
is_group_readable(void) const371c243e490SMarcel Moolenaar impl::file_info::is_group_readable(void)
372c243e490SMarcel Moolenaar     const
373c243e490SMarcel Moolenaar {
374c243e490SMarcel Moolenaar     return atf_fs_stat_is_group_readable(&m_stat);
375c243e490SMarcel Moolenaar }
376c243e490SMarcel Moolenaar 
377c243e490SMarcel Moolenaar bool
is_group_writable(void) const378c243e490SMarcel Moolenaar impl::file_info::is_group_writable(void)
379c243e490SMarcel Moolenaar     const
380c243e490SMarcel Moolenaar {
381c243e490SMarcel Moolenaar     return atf_fs_stat_is_group_writable(&m_stat);
382c243e490SMarcel Moolenaar }
383c243e490SMarcel Moolenaar 
384c243e490SMarcel Moolenaar bool
is_group_executable(void) const385c243e490SMarcel Moolenaar impl::file_info::is_group_executable(void)
386c243e490SMarcel Moolenaar     const
387c243e490SMarcel Moolenaar {
388c243e490SMarcel Moolenaar     return atf_fs_stat_is_group_executable(&m_stat);
389c243e490SMarcel Moolenaar }
390c243e490SMarcel Moolenaar 
391c243e490SMarcel Moolenaar bool
is_other_readable(void) const392c243e490SMarcel Moolenaar impl::file_info::is_other_readable(void)
393c243e490SMarcel Moolenaar     const
394c243e490SMarcel Moolenaar {
395c243e490SMarcel Moolenaar     return atf_fs_stat_is_other_readable(&m_stat);
396c243e490SMarcel Moolenaar }
397c243e490SMarcel Moolenaar 
398c243e490SMarcel Moolenaar bool
is_other_writable(void) const399c243e490SMarcel Moolenaar impl::file_info::is_other_writable(void)
400c243e490SMarcel Moolenaar     const
401c243e490SMarcel Moolenaar {
402c243e490SMarcel Moolenaar     return atf_fs_stat_is_other_writable(&m_stat);
403c243e490SMarcel Moolenaar }
404c243e490SMarcel Moolenaar 
405c243e490SMarcel Moolenaar bool
is_other_executable(void) const406c243e490SMarcel Moolenaar impl::file_info::is_other_executable(void)
407c243e490SMarcel Moolenaar     const
408c243e490SMarcel Moolenaar {
409c243e490SMarcel Moolenaar     return atf_fs_stat_is_other_executable(&m_stat);
410c243e490SMarcel Moolenaar }
411c243e490SMarcel Moolenaar 
412c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
413c243e490SMarcel Moolenaar // The "directory" class.
414c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
415c243e490SMarcel Moolenaar 
directory(const path & p)416c243e490SMarcel Moolenaar impl::directory::directory(const path& p)
417c243e490SMarcel Moolenaar {
418c243e490SMarcel Moolenaar     DIR* dp = ::opendir(p.c_str());
419c243e490SMarcel Moolenaar     if (dp == NULL)
420c243e490SMarcel Moolenaar         throw system_error(IMPL_NAME "::directory::directory(" +
421c243e490SMarcel Moolenaar                            p.str() + ")", "opendir(3) failed", errno);
422c243e490SMarcel Moolenaar 
423c243e490SMarcel Moolenaar     struct dirent* dep;
424c243e490SMarcel Moolenaar     while ((dep = ::readdir(dp)) != NULL) {
425c243e490SMarcel Moolenaar         path entryp = p / dep->d_name;
426c243e490SMarcel Moolenaar         insert(value_type(dep->d_name, file_info(entryp)));
427c243e490SMarcel Moolenaar     }
428c243e490SMarcel Moolenaar 
429c243e490SMarcel Moolenaar     if (::closedir(dp) == -1)
430c243e490SMarcel Moolenaar         throw system_error(IMPL_NAME "::directory::directory(" +
431c243e490SMarcel Moolenaar                            p.str() + ")", "closedir(3) failed", errno);
432c243e490SMarcel Moolenaar }
433c243e490SMarcel Moolenaar 
434c243e490SMarcel Moolenaar std::set< std::string >
names(void) const435c243e490SMarcel Moolenaar impl::directory::names(void)
436c243e490SMarcel Moolenaar     const
437c243e490SMarcel Moolenaar {
438c243e490SMarcel Moolenaar     std::set< std::string > ns;
439c243e490SMarcel Moolenaar 
440c243e490SMarcel Moolenaar     for (const_iterator iter = begin(); iter != end(); iter++)
441c243e490SMarcel Moolenaar         ns.insert((*iter).first);
442c243e490SMarcel Moolenaar 
443c243e490SMarcel Moolenaar     return ns;
444c243e490SMarcel Moolenaar }
445c243e490SMarcel Moolenaar 
446c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
447c243e490SMarcel Moolenaar // Free functions.
448c243e490SMarcel Moolenaar // ------------------------------------------------------------------------
449c243e490SMarcel Moolenaar 
450c243e490SMarcel Moolenaar bool
exists(const path & p)451c243e490SMarcel Moolenaar impl::exists(const path& p)
452c243e490SMarcel Moolenaar {
453c243e490SMarcel Moolenaar     atf_error_t err;
454c243e490SMarcel Moolenaar     bool b;
455c243e490SMarcel Moolenaar 
456c243e490SMarcel Moolenaar     err = atf_fs_exists(p.c_path(), &b);
457c243e490SMarcel Moolenaar     if (atf_is_error(err))
458c243e490SMarcel Moolenaar         throw_atf_error(err);
459c243e490SMarcel Moolenaar 
460c243e490SMarcel Moolenaar     return b;
461c243e490SMarcel Moolenaar }
462c243e490SMarcel Moolenaar 
463c243e490SMarcel Moolenaar bool
have_prog_in_path(const std::string & prog)464c243e490SMarcel Moolenaar impl::have_prog_in_path(const std::string& prog)
465c243e490SMarcel Moolenaar {
466c243e490SMarcel Moolenaar     PRE(prog.find('/') == std::string::npos);
467c243e490SMarcel Moolenaar 
468c243e490SMarcel Moolenaar     // Do not bother to provide a default value for PATH.  If it is not
469c243e490SMarcel Moolenaar     // there something is broken in the user's environment.
470c243e490SMarcel Moolenaar     if (!atf::env::has("PATH"))
471c243e490SMarcel Moolenaar         throw std::runtime_error("PATH not defined in the environment");
472c243e490SMarcel Moolenaar     std::vector< std::string > dirs =
473c243e490SMarcel Moolenaar         atf::text::split(atf::env::get("PATH"), ":");
474c243e490SMarcel Moolenaar 
475c243e490SMarcel Moolenaar     bool found = false;
476c243e490SMarcel Moolenaar     for (std::vector< std::string >::const_iterator iter = dirs.begin();
477c243e490SMarcel Moolenaar          !found && iter != dirs.end(); iter++) {
478c243e490SMarcel Moolenaar         const path& dir = path(*iter);
479c243e490SMarcel Moolenaar 
480c243e490SMarcel Moolenaar         if (is_executable(dir / prog))
481c243e490SMarcel Moolenaar             found = true;
482c243e490SMarcel Moolenaar     }
483c243e490SMarcel Moolenaar     return found;
484c243e490SMarcel Moolenaar }
485c243e490SMarcel Moolenaar 
486c243e490SMarcel Moolenaar bool
is_executable(const path & p)487c243e490SMarcel Moolenaar impl::is_executable(const path& p)
488c243e490SMarcel Moolenaar {
489c243e490SMarcel Moolenaar     if (!exists(p))
490c243e490SMarcel Moolenaar         return false;
491c243e490SMarcel Moolenaar     return safe_access(p, atf_fs_access_x, EACCES);
492c243e490SMarcel Moolenaar }
493c243e490SMarcel Moolenaar 
494c243e490SMarcel Moolenaar void
remove(const path & p)495c243e490SMarcel Moolenaar impl::remove(const path& p)
496c243e490SMarcel Moolenaar {
497c243e490SMarcel Moolenaar     if (file_info(p).get_type() == file_info::dir_type)
498c243e490SMarcel Moolenaar         throw atf::system_error(IMPL_NAME "::remove(" + p.str() + ")",
499c243e490SMarcel Moolenaar                                 "Is a directory",
500c243e490SMarcel Moolenaar                                 EPERM);
501c243e490SMarcel Moolenaar     if (::unlink(p.c_str()) == -1)
502c243e490SMarcel Moolenaar         throw atf::system_error(IMPL_NAME "::remove(" + p.str() + ")",
503c243e490SMarcel Moolenaar                                 "unlink(" + p.str() + ") failed",
504c243e490SMarcel Moolenaar                                 errno);
505c243e490SMarcel Moolenaar }
506c243e490SMarcel Moolenaar 
507c243e490SMarcel Moolenaar void
rmdir(const path & p)508c243e490SMarcel Moolenaar impl::rmdir(const path& p)
509c243e490SMarcel Moolenaar {
510c243e490SMarcel Moolenaar     atf_error_t err = atf_fs_rmdir(p.c_path());
511c243e490SMarcel Moolenaar     if (atf_is_error(err))
512c243e490SMarcel Moolenaar         throw_atf_error(err);
513c243e490SMarcel Moolenaar }
514