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