Small improvements for simgear::Dir

- Add method simgear::Dir::isNull(), analogous to SGPath::isNull().

- Make sure that simgear::Dir::tempDir() returns a null simgear::Dir
  instance when creation of the directory failed (so far, this was only
  the case on systems where HAVE_MKDTEMP is defined).

- Use simgear::strutils::error_string() instead of strerror() (the
  latter is not guaranteed to be thread-safe).

- Make sure <cerrno> is #included, regardless of the platform.

- Add automated tests for isNull(), setRemoveOnDestroy() and tempDir().
This commit is contained in:
Florent Rougon
2017-01-26 09:38:41 +01:00
parent 6c64e9b36c
commit 6a2d86c526
4 changed files with 72 additions and 7 deletions

View File

@@ -71,6 +71,10 @@ add_executable(test_path path_test.cxx )
add_test(path ${EXECUTABLE_OUTPUT_PATH}/test_path)
target_link_libraries(test_path ${TEST_LIBS})
add_executable(test_sg_dir sg_dir_test.cxx)
target_link_libraries(test_sg_dir ${TEST_LIBS})
add_test(sg_dir ${EXECUTABLE_OUTPUT_PATH}/test_sg_dir)
endif(ENABLE_TESTS)
add_boost_test(SimpleMarkdown

View File

@@ -37,7 +37,6 @@
# include <dirent.h>
# include <sys/stat.h>
# include <unistd.h>
# include <errno.h>
#endif
#include <simgear/misc/strutils.hxx>
@@ -46,6 +45,7 @@
#include <cstring>
#include <cstdlib>
#include <cerrno>
#include <iostream>
#include <algorithm> // for std::sort
@@ -94,7 +94,7 @@ Dir Dir::current()
#endif
if (!buf) {
if (errno == 2) throw sg_exception("The current directory is invalid");
else throw sg_exception(strerror(errno));
else throw sg_exception(simgear::strutils::error_string(errno));
}
SGPath p(buf);
@@ -118,7 +118,8 @@ Dir Dir::tempDir(const std::string& templ)
std::string s = p.local8BitStr();
::snprintf(buf, 1024, "%s", s.c_str());
if (!mkdtemp(buf)) {
SG_LOG(SG_IO, SG_WARN, "mkdtemp failed:" << strerror(errno));
SG_LOG(SG_IO, SG_WARN,
"mkdtemp failed: " << simgear::strutils::error_string(errno));
return Dir();
}
@@ -135,6 +136,7 @@ Dir Dir::tempDir(const std::string& templ)
Dir t(p);
if (!t.create(0700)) {
SG_LOG(SG_IO, SG_WARN, "failed to create temporary directory at " << p);
return Dir();
}
return t;
@@ -277,6 +279,11 @@ PathList Dir::children(int types, const std::string& nameFilter) const
return result;
}
bool Dir::isNull() const
{
return _path.isNull();
}
bool Dir::isEmpty() const
{
#if defined(SG_WINDOWS)
@@ -333,7 +340,9 @@ bool Dir::create(mode_t mode)
int err = mkdir(ps.c_str(), mode);
#endif
if (err) {
SG_LOG(SG_IO, SG_WARN, "directory creation failed: (" << _path << ") " << strerror(errno) );
SG_LOG(SG_IO, SG_WARN,
"directory creation failed for '" << _path.utf8Str() << "': " <<
simgear::strutils::error_string(errno));
}
return (err == 0);
@@ -386,7 +395,9 @@ bool Dir::remove(bool recursive)
int err = rmdir(ps.c_str());
#endif
if (err) {
SG_LOG(SG_IO, SG_WARN, "rmdir failed:" << _path << ":" << strerror(errno));
SG_LOG(SG_IO, SG_WARN,
"rmdir failed for '" << _path.utf8Str() << "': " <<
simgear::strutils::error_string(errno));
}
return (err == 0);
}

View File

@@ -55,7 +55,8 @@ namespace simgear
static Dir current();
/**
* create a temporary directory, using the supplied name
* Create a temporary directory, using the supplied name.
* The return value 'd' is such that d.isNull() in case this failed.
*/
static Dir tempDir(const std::string& templ);
@@ -71,7 +72,14 @@ namespace simgear
};
PathList children(int types = 0, const std::string& nameGlob = "") const;
/**
* Check if the underlying SGPath is null.
*
* Note: this is the case for a default-constructed Dir instance.
*/
bool isNull() const;
/**
* test if the directory contains no children (except '.' and '..')
*/

View File

@@ -0,0 +1,42 @@
#include <cstdlib>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/test_macros.hxx>
#include "sg_dir.hxx"
void test_isNull()
{
SG_VERIFY(simgear::Dir().isNull());
}
void test_setRemoveOnDestroy()
{
SGPath path;
{
simgear::Dir d = simgear::Dir::tempDir("FlightGear");
SG_VERIFY(!d.isNull() && d.exists() && d.isEmpty());
d.setRemoveOnDestroy();
path = d.path(); // keep a copy of the path
SG_VERIFY(path.exists() && path.isDir());
}
SG_VERIFY(!path.exists());
}
void test_tempDir()
{
simgear::Dir d = simgear::Dir::tempDir("FlightGear");
SG_VERIFY(!d.isNull() && d.exists() && d.isEmpty());
d.remove();
}
int main(int argc, char **argv)
{
test_isNull();
test_setRemoveOnDestroy();
test_tempDir();
return EXIT_SUCCESS;
}