summaryrefslogtreecommitdiffstats
path: root/contrib/atf/atf-run/fs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/atf/atf-run/fs.cpp')
-rw-r--r--contrib/atf/atf-run/fs.cpp264
1 files changed, 0 insertions, 264 deletions
diff --git a/contrib/atf/atf-run/fs.cpp b/contrib/atf/atf-run/fs.cpp
deleted file mode 100644
index b8931e5..0000000
--- a/contrib/atf/atf-run/fs.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-//
-// Automated Testing Framework (atf)
-//
-// Copyright (c) 2007 The NetBSD Foundation, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
-// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-
-#if defined(HAVE_CONFIG_H)
-#include "bconfig.h"
-#endif
-
-extern "C" {
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-
-#include <unistd.h>
-}
-
-#include <cerrno>
-#include <cstdlib>
-#include <cstring>
-
-#include "atf-c++/detail/process.hpp"
-#include "atf-c++/detail/sanity.hpp"
-
-#include "fs.hpp"
-#include "user.hpp"
-
-namespace impl = atf::atf_run;
-#define IMPL_NAME "atf::atf_run"
-
-// ------------------------------------------------------------------------
-// Auxiliary functions.
-// ------------------------------------------------------------------------
-
-static void cleanup_aux(const atf::fs::path&, dev_t, bool);
-static void cleanup_aux_dir(const atf::fs::path&, const atf::fs::file_info&,
- bool);
-static void do_unmount(const atf::fs::path&);
-
-// The cleanup routines below are tricky: they are executed immediately after
-// a test case's death, and after we have forcibly killed any stale processes.
-// However, even if the processes are dead, this does not mean that the file
-// system we are scanning is stable. In particular, if the test case has
-// mounted file systems through fuse/puffs, the fact that the processes died
-// does not mean that the file system is truly unmounted.
-//
-// The code below attempts to cope with this by catching errors and either
-// ignoring them or retrying the actions on the same file/directory a few times
-// before giving up.
-static const int max_retries = 5;
-static const int retry_delay_in_seconds = 1;
-
-// The erase parameter in this routine is to control nested mount points.
-// We want to descend into a mount point to unmount anything that is
-// mounted under it, but we do not want to delete any files while doing
-// this traversal. In other words, we erase files until we cross the
-// first mount point, and after that point we only scan and unmount.
-static
-void
-cleanup_aux(const atf::fs::path& p, dev_t parent_device, bool erase)
-{
- try {
- atf::fs::file_info fi(p);
-
- if (fi.get_type() == atf::fs::file_info::dir_type)
- cleanup_aux_dir(p, fi, fi.get_device() == parent_device);
-
- if (fi.get_device() != parent_device)
- do_unmount(p);
-
- if (erase) {
- if (fi.get_type() == atf::fs::file_info::dir_type)
- atf::fs::rmdir(p);
- else
- atf::fs::remove(p);
- }
- } catch (const atf::system_error& e) {
- if (e.code() != ENOENT && e.code() != ENOTDIR)
- throw e;
- }
-}
-
-static
-void
-cleanup_aux_dir(const atf::fs::path& p, const atf::fs::file_info& fi,
- bool erase)
-{
- if (erase && ((fi.get_mode() & S_IRWXU) != S_IRWXU)) {
- int retries = max_retries;
-retry_chmod:
- if (chmod(p.c_str(), fi.get_mode() | S_IRWXU) == -1) {
- if (retries > 0) {
- retries--;
- ::sleep(retry_delay_in_seconds);
- goto retry_chmod;
- } else {
- throw atf::system_error(IMPL_NAME "::cleanup(" +
- p.str() + ")", "chmod(2) failed",
- errno);
- }
- }
- }
-
- std::set< std::string > subdirs;
- {
- bool ok = false;
- int retries = max_retries;
- while (!ok) {
- INV(retries > 0);
- try {
- const atf::fs::directory d(p);
- subdirs = d.names();
- ok = true;
- } catch (const atf::system_error& e) {
- retries--;
- if (retries == 0)
- throw e;
- ::sleep(retry_delay_in_seconds);
- }
- }
- INV(ok);
- }
-
- for (std::set< std::string >::const_iterator iter = subdirs.begin();
- iter != subdirs.end(); iter++) {
- const std::string& name = *iter;
- if (name != "." && name != "..")
- cleanup_aux(p / name, fi.get_device(), erase);
- }
-}
-
-static
-void
-do_unmount(const atf::fs::path& in_path)
-{
- // At least, FreeBSD's unmount(2) requires the path to be absolute.
- // Let's make it absolute in all cases just to be safe that this does
- // not affect other systems.
- const atf::fs::path& abs_path = in_path.is_absolute() ?
- in_path : in_path.to_absolute();
-
-#if defined(HAVE_UNMOUNT)
- int retries = max_retries;
-retry_unmount:
- if (unmount(abs_path.c_str(), 0) == -1) {
- if (errno == EBUSY && retries > 0) {
- retries--;
- ::sleep(retry_delay_in_seconds);
- goto retry_unmount;
- } else {
- throw atf::system_error(IMPL_NAME "::cleanup(" + in_path.str() +
- ")", "unmount(2) failed", errno);
- }
- }
-#else
- // We could use umount(2) instead if it was available... but
- // trying to do so under, e.g. Linux, is a nightmare because we
- // also have to update /etc/mtab to match what we did. It is
- // satf::fser to just leave the system-specific umount(8) tool deal
- // with it, at least for now.
-
- const atf::fs::path prog("umount");
- atf::process::argv_array argv("umount", abs_path.c_str(), NULL);
-
- atf::process::status s = atf::process::exec(prog, argv,
- atf::process::stream_inherit(), atf::process::stream_inherit());
- if (!s.exited() || s.exitstatus() != EXIT_SUCCESS)
- throw std::runtime_error("Call to unmount failed");
-#endif
-}
-
-// ------------------------------------------------------------------------
-// The "temp_dir" class.
-// ------------------------------------------------------------------------
-
-impl::temp_dir::temp_dir(const atf::fs::path& p)
-{
- atf::utils::auto_array< char > buf(new char[p.str().length() + 1]);
- std::strcpy(buf.get(), p.c_str());
- if (::mkdtemp(buf.get()) == NULL)
- throw system_error(IMPL_NAME "::temp_dir::temp_dir(" +
- p.str() + ")", "mkdtemp(3) failed",
- errno);
-
- m_path.reset(new atf::fs::path(buf.get()));
-}
-
-impl::temp_dir::~temp_dir(void)
-{
- cleanup(*m_path);
-}
-
-const atf::fs::path&
-impl::temp_dir::get_path(void)
- const
-{
- return *m_path;
-}
-
-// ------------------------------------------------------------------------
-// Free functions.
-// ------------------------------------------------------------------------
-
-atf::fs::path
-impl::change_directory(const atf::fs::path& dir)
-{
- atf::fs::path olddir = get_current_dir();
-
- if (olddir != dir) {
- if (::chdir(dir.c_str()) == -1)
- throw system_error(IMPL_NAME "::chdir(" + dir.str() + ")",
- "chdir(2) failed", errno);
- }
-
- return olddir;
-}
-
-void
-impl::cleanup(const atf::fs::path& p)
-{
- atf::fs::file_info fi(p);
- cleanup_aux(p, fi.get_device(), true);
-}
-
-atf::fs::path
-impl::get_current_dir(void)
-{
- std::auto_ptr< char > cwd;
-#if defined(HAVE_GETCWD_DYN)
- cwd.reset(getcwd(NULL, 0));
-#else
- cwd.reset(getcwd(NULL, MAXPATHLEN));
-#endif
- if (cwd.get() == NULL)
- throw atf::system_error(IMPL_NAME "::get_current_dir()",
- "getcwd() failed", errno);
-
- return atf::fs::path(cwd.get());
-}
OpenPOWER on IntegriCloud