|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r74950 - in trunk: boost/filesystem/v3 libs/filesystem/v3/src libs/filesystem/v3/test libs/filesystem/v3/test/msvc10
From: bdawes_at_[hidden]
Date: 2011-10-15 12:02:23
Author: bemandawes
Date: 2011-10-15 12:02:20 EDT (Sat, 15 Oct 2011)
New Revision: 74950
URL: http://svn.boost.org/trac/boost/changeset/74950
Log:
Add support for permissions. Docs to follow.
Text files modified:
trunk/boost/filesystem/v3/operations.hpp | 140 +++++++++++++++++++++---
trunk/libs/filesystem/v3/src/operations.cpp | 226 +++++++++++++++++++++++++++++++--------
trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln | 10 +
trunk/libs/filesystem/v3/test/operations_test.cpp | 83 ++++++++++++--
trunk/libs/filesystem/v3/test/operations_unit_test.cpp | 58 +++++++---
trunk/libs/filesystem/v3/test/path_test.cpp | 2
6 files changed, 422 insertions(+), 97 deletions(-)
Modified: trunk/boost/filesystem/v3/operations.hpp
==============================================================================
--- trunk/boost/filesystem/v3/operations.hpp (original)
+++ trunk/boost/filesystem/v3/operations.hpp 2011-10-15 12:02:20 EDT (Sat, 15 Oct 2011)
@@ -55,9 +55,7 @@
{
//--------------------------------------------------------------------------------------//
-// //
-// support classes and enums //
-// //
+// file_type //
//--------------------------------------------------------------------------------------//
enum file_type
@@ -82,27 +80,96 @@
_detail_directory_symlink // internal use only; never exposed to users
};
+//--------------------------------------------------------------------------------------//
+// perms //
+//--------------------------------------------------------------------------------------//
+
+ enum perms
+ {
+ no_perms = 0, // file_not_found is no_perms rather than perms_not_known
+
+ // POSIX equivalent macros given in comments.
+ // Values are from POSIX and are given in octal per the POSIX standard.
+
+ // permission bits
+
+ owner_read = 0400, // S_IRUSR, Read permission, owner
+ owner_write = 0200, // S_IWUSR, Write permission, owner
+ owner_exe = 0100, // S_IXUSR, Execute/search permission, owner
+ owner_all = 0700, // S_IRWXU, Read, write, execute/search by owner
+
+ group_read = 040, // S_IRGRP, Read permission, group
+ group_write = 020, // S_IWGRP, Write permission, group
+ group_exe = 010, // S_IXGRP, Execute/search permission, group
+ group_all = 070, // S_IRWXG, Read, write, execute/search by group
+
+ others_read = 04, // S_IROTH, Read permission, others
+ others_write = 02, // S_IWOTH, Write permission, others
+ others_exe = 01, // S_IXOTH, Execute/search permission, others
+ others_all = 07, // S_IRWXO, Read, write, execute/search by others
+
+ all_all = owner_all|group_all|others_all, // 0777
+
+ // other POSIX bits
+
+ set_uid_on_exe = 04000, // S_ISUID, Set-user-ID on execution
+ set_gid_on_exe = 02000, // S_ISGID, Set-group-ID on execution
+ sticky_bit = 01000, // S_ISVTX,
+ // (POSIX XSI) On directories, restricted deletion flag
+ // (V7) 'sticky bit': save swapped text even after use
+ // (SunOS) On non-directories: don't cache this file
+ // (SVID-v4.2) On directories: restricted deletion flag
+ // Also see http://en.wikipedia.org/wiki/Sticky_bit
+
+ perms_mask = all_all|set_uid_on_exe|set_gid_on_exe|sticky_bit, // 07777
+
+ perms_not_known = 0xFFFF, // present when directory_entry cache not loaded
+
+ // options for permissions() function
+
+ add_perms = 0x1000, // adds the given permission bits to the current bits
+ remove_perms = 0x2000, // removes the given permission bits from the current bits;
+ // choose add_perms or remove_perms, not both; if neither add_perms
+ // nor remove_perms is given, replace the current bits with
+ // the given bits.
+
+ symlink_perms = 0x4000 // on POSIX, don't resolve symlinks; implied on Windows
+ };
+
+ BOOST_BITMASK(perms);
+
+//--------------------------------------------------------------------------------------//
+// file_status //
+//--------------------------------------------------------------------------------------//
+
class BOOST_FILESYSTEM_DECL file_status
{
public:
- file_status() : m_value(status_error) {}
- explicit file_status(file_type v) : m_value(v) {}
-
- void type(file_type v) { m_value = v; }
- file_type type() const { return m_value; }
+ file_status() : m_value(status_error), m_perms(perms_not_known) {}
+ explicit file_status(file_type v, perms prms = perms_not_known)
+ : m_value(v), m_perms(prms) {}
+
+ // observers
+ file_type type() const { return m_value; }
+ perms permissions() const { return m_perms; }
+
+ // modifiers
+ void type(file_type v) { m_value = v; }
+ void permissions(perms prms) { m_perms = prms; }
- bool operator==(const file_status& rhs) const { return type() == rhs.type(); }
+ bool operator==(const file_status& rhs) const { return type() == rhs.type() &&
+ permissions() == rhs.permissions(); }
bool operator!=(const file_status& rhs) const { return !(*this == rhs); }
private:
- // the internal representation is unspecified so that additional state
- // information such as permissions can be added in the future; this
- // implementation just uses file_type as the internal representation
-
- file_type m_value;
+ file_type m_value;
+ enum perms m_perms;
};
- inline bool status_known(file_status f) { return f.type() != status_error; }
+ inline bool type_present(file_status f) { return f.type() != status_error; }
+ inline bool permissions_present(file_status f)
+ {return f.permissions() != perms_not_known;}
+ inline bool status_known(file_status f) { return type_present(f) && permissions_present(f); }
inline bool exists(file_status f) { return f.type() != status_error
&& f.type() != file_not_found; }
inline bool is_regular_file(file_status f){ return f.type() == regular_file; }
@@ -159,7 +226,7 @@
bool create_directory(const path& p, system::error_code* ec=0);
BOOST_FILESYSTEM_DECL
void create_directory_symlink(const path& to, const path& from,
- system::error_code* ec=0);
+ system::error_code* ec=0);
BOOST_FILESYSTEM_DECL
void create_hard_link(const path& to, const path& from, system::error_code* ec=0);
BOOST_FILESYSTEM_DECL
@@ -178,7 +245,9 @@
std::time_t last_write_time(const path& p, system::error_code* ec=0);
BOOST_FILESYSTEM_DECL
void last_write_time(const path& p, const std::time_t new_time,
- system::error_code* ec=0);
+ system::error_code* ec=0);
+ BOOST_FILESYSTEM_DECL
+ void permissions(const path& p, perms prms, system::error_code* ec=0);
BOOST_FILESYSTEM_DECL
path read_symlink(const path& p, system::error_code* ec=0);
BOOST_FILESYSTEM_DECL
@@ -280,7 +349,7 @@
path canonical(const path& p, const path& base, system::error_code& ec)
{return detail::canonical(p, base, &ec);}
- # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
inline
path complete(const path& p)
{
@@ -410,6 +479,13 @@
void last_write_time(const path& p, const std::time_t new_time, system::error_code& ec)
{detail::last_write_time(p, new_time, &ec);}
inline
+ void permissions(const path& p, perms prms)
+ {detail::permissions(p, prms);}
+ inline
+ void permissions(const path& p, perms prms, system::error_code& ec)
+ {detail::permissions(p, prms, &ec);}
+
+ inline
path read_symlink(const path& p) {return detail::read_symlink(p);}
inline
@@ -1000,6 +1076,30 @@
{
namespace filesystem
{
+ // permissions
+ using filesystem3::no_perms;
+ using filesystem3::owner_read;
+ using filesystem3::owner_write;
+ using filesystem3::owner_exe;
+ using filesystem3::owner_all;
+ using filesystem3::group_read;
+ using filesystem3::group_write;
+ using filesystem3::group_exe;
+ using filesystem3::group_all;
+ using filesystem3::others_read;
+ using filesystem3::others_write;
+ using filesystem3::others_exe;
+ using filesystem3::others_all;
+ using filesystem3::all_all;
+ using filesystem3::set_uid_on_exe;
+ using filesystem3::set_gid_on_exe;
+ using filesystem3::sticky_bit;
+ using filesystem3::perms_mask;
+ using filesystem3::perms_not_known;
+ using filesystem3::add_perms;
+ using filesystem3::remove_perms;
+ using filesystem3::symlink_perms;
+
using filesystem3::absolute;
using filesystem3::block_file;
using filesystem3::canonical;
@@ -1034,6 +1134,9 @@
using filesystem3::is_regular_file;
using filesystem3::is_symlink;
using filesystem3::last_write_time;
+ using filesystem3::permissions;
+ using filesystem3::permissions_present;
+ using filesystem3::perms;
using filesystem3::read_symlink;
using filesystem3::recursive_directory_iterator;
using filesystem3::regular_file;
@@ -1053,6 +1156,7 @@
using filesystem3::symlink_status;
using filesystem3::system_complete;
using filesystem3::temp_directory_path;
+ using filesystem3::type_present;
using filesystem3::type_unknown;
using filesystem3::unique_path;
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
Modified: trunk/libs/filesystem/v3/src/operations.cpp
==============================================================================
--- trunk/libs/filesystem/v3/src/operations.cpp (original)
+++ trunk/libs/filesystem/v3/src/operations.cpp 2011-10-15 12:02:20 EDT (Sat, 15 Oct 2011)
@@ -69,6 +69,7 @@
namespace fs = boost::filesystem3;
using boost::filesystem3::path;
using boost::filesystem3::filesystem_error;
+using boost::filesystem3::perms;
using boost::system::error_code;
using boost::system::error_category;
using boost::system::system_category;
@@ -107,6 +108,7 @@
// See MinGW's windef.h
# define WINVER 0x501
# endif
+# include <io.h>
# include <windows.h>
# include <winnt.h>
# if !defined(_WIN32_WINNT)
@@ -247,12 +249,6 @@
namespace
{
-# ifdef BOOST_POSIX_API
- const char dot = '.';
-# else
- const wchar_t dot = L'.';
-# endif
-
fs::file_type query_file_type(const path& p, error_code* ec);
boost::filesystem3::directory_iterator end_dir_itr;
@@ -414,6 +410,8 @@
// //
//--------------------------------------------------------------------------------------//
+ const char dot = '.';
+
bool not_found_error(int errval)
{
return errno == ENOENT || errno == ENOTDIR;
@@ -490,6 +488,8 @@
// //
//--------------------------------------------------------------------------------------//
+ const wchar_t dot = L'.';
+
bool not_found_error(int errval)
{
return errval == ERROR_FILE_NOT_FOUND
@@ -502,6 +502,19 @@
|| errval == ERROR_BAD_NETPATH; // "//nosuch" on Win32
}
+ perms make_permissions(const path& p, DWORD attr)
+ {
+ perms prms = fs::owner_read | fs::group_read | fs::others_read;
+ if ((attr & FILE_ATTRIBUTE_READONLY) == 0)
+ prms |= fs::owner_write | fs::group_write | fs::others_write;
+ if (_stricmp(p.extension().string().c_str(), ".exe") == 0
+ || _stricmp(p.extension().string().c_str(), ".com") == 0
+ || _stricmp(p.extension().string().c_str(), ".bat") == 0
+ || _stricmp(p.extension().string().c_str(), ".cmd") == 0)
+ prms |= fs::owner_exe | fs::group_exe | fs::others_exe;
+ return prms;
+ }
+
// these constants come from inspecting some Microsoft sample code
std::time_t to_time_t(const FILETIME & ft)
{
@@ -590,7 +603,7 @@
if (not_found_error(errval))
{
- return fs::file_status(fs::file_not_found);
+ return fs::file_status(fs::file_not_found, fs::no_perms);
}
else if ((errval == ERROR_SHARING_VIOLATION))
{
@@ -755,6 +768,21 @@
# endif
}
+# ifdef BOOST_POSIX_API
+ const perms active_bits(all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit);
+ inline mode_t mode_cast(perms prms) { return prms & active_bits; }
+# else
+ inline int mode_cast(perms prms)
+ {
+ // Windows _wchmod() can only make a file read-only and there is only one
+ // such attribute bit for the file. Files are always readable. Get over it.
+ return (prms & (owner_write|group_write|others_write)
+ ? _S_IREAD | _S_IWRITE
+ : _S_IREAD
+ );
+ }
+# endif
+
BOOST_FILESYSTEM_DECL
path canonical(const path& p, const path& base, system::error_code* ec)
{
@@ -1330,6 +1358,62 @@
}
BOOST_FILESYSTEM_DECL
+ void permissions(const path& p, perms prms, system::error_code* ec)
+ {
+ BOOST_ASSERT_MSG(!((prms & add_perms) && (prms & remove_perms)),
+ "add_perms and remove_perms are mutually exclusive");
+
+ if ((prms & add_perms) && (prms & remove_perms)) // precondition failed
+ return;
+
+ error_code local_ec;
+ file_status current_status((prms & symlink_perms)
+ ? fs::symlink_status(p, local_ec)
+ : fs::status(p, local_ec));
+ if (local_ec)
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(
+ "boost::filesystem::permissions", p, local_ec));
+ else
+ *ec = local_ec;
+ return;
+ }
+
+ if (prms & add_perms)
+ prms |= current_status.permissions();
+ else if (prms & remove_perms)
+ {
+# ifdef BOOST_WINDOWS_API
+ if (prms & (owner_write|group_write|others_write))
+ prms |= owner_write|group_write|others_write;
+# endif
+ prms = current_status.permissions() & ~prms;
+ }
+
+# ifdef BOOST_POSIX_API
+ // Mac OS X Lion and some other platforms don't support fchmodat()
+# if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW)
+ if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms),
+ !(prms & symlink_perms) ? 0 : AT_SYMLINK_NOFOLLOW))
+# else // fallback if fchmodat() not supported
+ if (::chmod(p.c_str(), mode_cast(prms)))
+# endif
+# else
+ if (::_wchmod(p.c_str(), mode_cast(prms))) // if error
+# endif
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(
+ "boost::filesystem::permissions", p,
+ error_code(errno, system::generic_category())));
+ else
+ ec->assign(errno, system::generic_category());
+ }
+
+ }
+
+ BOOST_FILESYSTEM_DECL
path read_symlink(const path& p, system::error_code* ec)
{
path symlink_path;
@@ -1492,7 +1576,7 @@
if (not_found_error(errno))
{
- return fs::file_status(fs::file_not_found);
+ return fs::file_status(fs::file_not_found, fs::no_perms);
}
if (ec == 0)
BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
@@ -1501,17 +1585,23 @@
}
if (ec != 0) ec->clear();;
if (S_ISDIR(path_stat.st_mode))
- return fs::file_status(fs::directory_file);
+ return fs::file_status(fs::directory_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISREG(path_stat.st_mode))
- return fs::file_status(fs::regular_file);
+ return fs::file_status(fs::regular_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISBLK(path_stat.st_mode))
- return fs::file_status(fs::block_file);
+ return fs::file_status(fs::block_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISCHR(path_stat.st_mode))
- return fs::file_status(fs::character_file);
+ return fs::file_status(fs::character_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISFIFO(path_stat.st_mode))
- return fs::file_status(fs::fifo_file);
+ return fs::file_status(fs::fifo_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISSOCK(path_stat.st_mode))
- return fs::file_status(fs::socket_file);
+ return fs::file_status(fs::socket_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
return fs::file_status(fs::type_unknown);
# else // Windows
@@ -1522,7 +1612,9 @@
return process_status_failure(p, ec);
}
- // reparse point handling
+ // reparse point handling;
+ // since GetFileAttributesW does not resolve symlinks, try to open a file
+ // handle to discover if the file exists
if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
{
handle_wrapper h(
@@ -1540,13 +1632,13 @@
}
if (!is_reparse_point_a_symlink(p))
- return file_status(reparse_file);
+ return file_status(reparse_file, make_permissions(p, attr));
}
if (ec != 0) ec->clear();
return (attr & FILE_ATTRIBUTE_DIRECTORY)
- ? file_status(directory_file)
- : file_status(regular_file);
+ ? file_status(directory_file, make_permissions(p, attr))
+ : file_status(regular_file, make_permissions(p, attr));
# endif
}
@@ -1564,7 +1656,7 @@
if (errno == ENOENT || errno == ENOTDIR) // these are not errors
{
- return fs::file_status(fs::file_not_found);
+ return fs::file_status(fs::file_not_found, fs::no_perms);
}
if (ec == 0)
BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
@@ -1573,19 +1665,26 @@
}
if (ec != 0) ec->clear();
if (S_ISREG(path_stat.st_mode))
- return fs::file_status(fs::regular_file);
+ return fs::file_status(fs::regular_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISDIR(path_stat.st_mode))
- return fs::file_status(fs::directory_file);
+ return fs::file_status(fs::directory_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISLNK(path_stat.st_mode))
- return fs::file_status(fs::symlink_file);
+ return fs::file_status(fs::symlink_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISBLK(path_stat.st_mode))
- return fs::file_status(fs::block_file);
+ return fs::file_status(fs::block_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISCHR(path_stat.st_mode))
- return fs::file_status(fs::character_file);
+ return fs::file_status(fs::character_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISFIFO(path_stat.st_mode))
- return fs::file_status(fs::fifo_file);
+ return fs::file_status(fs::fifo_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
if (S_ISSOCK(path_stat.st_mode))
- return fs::file_status(fs::socket_file);
+ return fs::file_status(fs::socket_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
return fs::file_status(fs::type_unknown);
# else // Windows
@@ -1600,12 +1699,12 @@
if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
return is_reparse_point_a_symlink(p)
- ? file_status(symlink_file)
- : file_status(reparse_file);
+ ? file_status(symlink_file, make_permissions(p, attr))
+ : file_status(reparse_file, make_permissions(p, attr));
return (attr & FILE_ATTRIBUTE_DIRECTORY)
- ? file_status(directory_file)
- : file_status(regular_file);
+ ? file_status(directory_file, make_permissions(p, attr))
+ : file_status(regular_file, make_permissions(p, attr));
# endif
}
@@ -1838,8 +1937,8 @@
dirent * entry(static_cast<dirent *>(buffer));
dirent * result;
int return_code;
- if ((return_code = readdir_r_simulator(static_cast<DIR*>(handle),
- entry, &result))!= 0)return error_code(errno, system_category());
+ if ((return_code = readdir_r_simulator(static_cast<DIR*>(handle), entry, &result))!= 0)
+ return error_code(errno, system_category());
if (result == 0)
return fs::detail::dir_itr_close(handle, buffer);
target = entry->d_name;
@@ -1886,7 +1985,7 @@
if ((handle = ::FindFirstFileW(dirpath.c_str(), &data))
== INVALID_HANDLE_VALUE)
{
- handle = 0;
+ handle = 0; // signal eof
return error_code( (::GetLastError() == ERROR_FILE_NOT_FOUND
// Windows Mobile returns ERROR_NO_MORE_FILES; see ticket #3551
|| ::GetLastError() == ERROR_NO_MORE_FILES)
@@ -1894,12 +1993,28 @@
}
target = data.cFileName;
if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
- // reparse points are complex, so don't try to handle them here
- { sf.type(fs::status_error); symlink_sf.type(fs::status_error); }
- else if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); }
+ // reparse points are complex, so don't try to handle them here; instead just mark
+ // them as status_error which causes directory_entry caching to call status()
+ // and symlink_status() which do handle reparse points fully
+ {
+ sf.type(fs::status_error);
+ symlink_sf.type(fs::status_error);
+ }
else
- { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); }
+ {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ sf.type(fs::directory_file);
+ symlink_sf.type(fs::directory_file);
+ }
+ else
+ {
+ sf.type(fs::regular_file);
+ symlink_sf.type(fs::regular_file);
+ }
+ sf.permissions(make_permissions(data.cFileName, data.dwFileAttributes));
+ symlink_sf.permissions(sf.permissions());
+ }
return error_code();
}
@@ -1915,12 +2030,28 @@
}
target = data.cFileName;
if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
- // reparse points are complex, so don't try to handle them here
- { sf.type(fs::status_error); symlink_sf.type(fs::status_error); }
- else if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); }
+ // reparse points are complex, so don't try to handle them here; instead just mark
+ // them as status_error which causes directory_entry caching to call status()
+ // and symlink_status() which do handle reparse points fully
+ {
+ sf.type(fs::status_error);
+ symlink_sf.type(fs::status_error);
+ }
else
- { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); }
+ {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ sf.type(fs::directory_file);
+ symlink_sf.type(fs::directory_file);
+ }
+ else
+ {
+ sf.type(fs::regular_file);
+ symlink_sf.type(fs::regular_file);
+ }
+ sf.permissions(make_permissions(data.cFileName, data.dwFileAttributes));
+ symlink_sf.permissions(sf.permissions());
+ }
return error_code();
}
#endif
@@ -1975,7 +2106,8 @@
const path& p, system::error_code* ec)
{
if (error(p.empty(), not_found_error_code, p, ec,
- "boost::filesystem::directory_iterator::construct"))return;
+ "boost::filesystem::directory_iterator::construct"))
+ return;
path::string_type filename;
file_status file_stat, symlink_file_stat;
@@ -1993,11 +2125,11 @@
return;
}
- if (it.m_imp->handle == 0)it.m_imp.reset(); // eof, so make end iterator
+ if (it.m_imp->handle == 0)
+ it.m_imp.reset(); // eof, so make end iterator
else // not eof
{
- it.m_imp->dir_entry.assign(p / filename,
- file_stat, symlink_file_stat);
+ it.m_imp->dir_entry.assign(p / filename, file_stat, symlink_file_stat);
if (filename[0] == dot // dot or dot-dot
&& (filename.size()== 1
|| (filename[1] == dot
Modified: trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln
==============================================================================
--- trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln (original)
+++ trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln 2011-10-15 12:02:20 EDT (Sat, 15 Oct 2011)
@@ -73,6 +73,12 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "locale_info", "locale_info\locale_info.vcxproj", "{3667C35E-78D5-43D4-AAC2-349145E4341D}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ticket_5850", "ticket_5850\ticket_5850.vcxproj", "{B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {F94CCADD-A90B-480C-A304-C19D015D36B1} = {F94CCADD-A90B-480C-A304-C19D015D36B1}
+ {FFD738F7-96F0-445C-81EA-551665EF53D1} = {FFD738F7-96F0-445C-81EA-551665EF53D1}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -167,6 +173,10 @@
{3667C35E-78D5-43D4-AAC2-349145E4341D}.Debug|Win32.Build.0 = Debug|Win32
{3667C35E-78D5-43D4-AAC2-349145E4341D}.Release|Win32.ActiveCfg = Release|Win32
{3667C35E-78D5-43D4-AAC2-349145E4341D}.Release|Win32.Build.0 = Release|Win32
+ {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Debug|Win32.Build.0 = Debug|Win32
+ {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Release|Win32.ActiveCfg = Release|Win32
+ {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Modified: trunk/libs/filesystem/v3/test/operations_test.cpp
==============================================================================
--- trunk/libs/filesystem/v3/test/operations_test.cpp (original)
+++ trunk/libs/filesystem/v3/test/operations_test.cpp 2011-10-15 12:02:20 EDT (Sat, 15 Oct 2011)
@@ -95,8 +95,10 @@
{
typedef int errno_t;
std::string platform(BOOST_PLATFORM);
- bool report_throws;
+ bool report_throws = false;
bool cleanup = true;
+ bool skip_long_windows_tests = false;
+
fs::directory_iterator end_itr;
fs::path dir;
fs::path d1;
@@ -113,7 +115,7 @@
const char* temp_dir_name = "v3_operations_test";
- void create_file(const fs::path & ph, const std::string & contents)
+ void create_file(const fs::path & ph, const std::string & contents = std::string())
{
std::ofstream f(ph.BOOST_FILESYSTEM_C_STR);
if (!f)
@@ -800,6 +802,45 @@
fs::create_symlink("doesnotexist", "", ec);
BOOST_TEST(ec);
}
+
+ // permissions_tests ---------------------------------------------------------------//
+
+ void permissions_tests()
+ {
+ cout << "permissions_tests..." << endl;
+
+ fs::path p(dir / "permissions.txt");
+ create_file(p);
+
+ if (platform == "POSIX")
+ {
+ cout << " fs::status(p).permissions() " << std::oct << fs::status(p).permissions()
+ << std::dec << endl;
+ BOOST_TEST(fs::status(p).permissions() == 0644);
+ fs::permissions(p, fs::owner_all);
+ BOOST_TEST(fs::status(p).permissions() == fs::owner_all);
+
+ fs::permissions(p, fs::add_perms | fs::group_all);
+ BOOST_TEST(fs::status(p).permissions() == (fs::owner_all | fs::group_all));
+
+ fs::permissions(p, fs::remove_perms | fs::group_all);
+ BOOST_TEST(fs::status(p).permissions() == fs::owner_all);
+
+ // some POSIX platforms cache permissions during directory iteration, some don't
+ // so test that iteration finds the correct permissions
+ for (fs::directory_iterator itr(dir); itr != fs::directory_iterator(); ++itr)
+ if (itr->path().filename() == fs::path("permissions.txt"))
+ BOOST_TEST(itr->status().permissions() == fs::owner_all);
+ }
+ else // Windows
+ {
+ BOOST_TEST(fs::status(p).permissions() == 0666);
+ fs::permissions(p, fs::remove_perms | fs::group_write);
+ BOOST_TEST(fs::status(p).permissions() == 0444);
+ fs::permissions(p, fs::add_perms | fs::group_write);
+ BOOST_TEST(fs::status(p).permissions() == 0666);
+ }
+ }
// rename_tests --------------------------------------------------------------------//
@@ -917,6 +958,8 @@
BOOST_TEST(!fs::is_regular_file(ng));
BOOST_TEST(!fs::is_symlink(ng));
fs::file_status stat(fs::status(ng));
+ BOOST_TEST(fs::type_present(stat));
+ BOOST_TEST(fs::permissions_present(stat));
BOOST_TEST(fs::status_known(stat));
BOOST_TEST(!fs::exists(stat));
BOOST_TEST(!fs::is_directory(stat));
@@ -924,6 +967,8 @@
BOOST_TEST(!fs::is_other(stat));
BOOST_TEST(!fs::is_symlink(stat));
stat = fs::status("");
+ BOOST_TEST(fs::type_present(stat));
+ BOOST_TEST(fs::permissions_present(stat));
BOOST_TEST(fs::status_known(stat));
BOOST_TEST(!fs::exists(stat));
BOOST_TEST(!fs::is_directory(stat));
@@ -1059,7 +1104,7 @@
fs::file_status s = fs::status(p);
BOOST_TEST(!fs::exists(s));
BOOST_TEST_EQ(s.type(), fs::file_not_found);
- BOOST_TEST(fs::status_known(s));
+ BOOST_TEST(fs::type_present(s));
BOOST_TEST(!fs::is_regular_file(s));
BOOST_TEST(!fs::is_directory(s));
BOOST_TEST(!fs::is_symlink(s));
@@ -1093,7 +1138,7 @@
BOOST_TEST(!fs::exists(s));
BOOST_TEST_EQ(s.type(), fs::file_not_found);
- BOOST_TEST(fs::status_known(s));
+ BOOST_TEST(fs::type_present(s));
BOOST_TEST(!fs::is_regular_file(s));
BOOST_TEST(!fs::is_directory(s));
BOOST_TEST(!fs::is_symlink(s));
@@ -1529,12 +1574,17 @@
// Windows only tests
if (platform == "Windows")
{
- cout << "Window specific tests..."
- "\n (may take several seconds)" << endl;
+ cout << "Window specific tests..." << endl;
+ if (!skip_long_windows_tests)
+ {
+ cout << " (may take several seconds)"<< endl;
+
+ BOOST_TEST(!fs::exists(fs::path("//share-not")));
+ BOOST_TEST(!fs::exists(fs::path("//share-not/")));
+ BOOST_TEST(!fs::exists(fs::path("//share-not/foo")));
+ }
+ cout << endl;
- BOOST_TEST(!fs::exists(fs::path("//share-not")));
- BOOST_TEST(!fs::exists(fs::path("//share-not/")));
- BOOST_TEST(!fs::exists(fs::path("//share-not/foo")));
BOOST_TEST(!fs::exists("tools/jam/src/:sys:stat.h")); // !exists() if ERROR_INVALID_NAME
BOOST_TEST(!fs::exists(":sys:stat.h")); // !exists() if ERROR_INVALID_PARAMETER
BOOST_TEST(dir.string().size() > 1
@@ -1814,7 +1864,6 @@
int cpp_main(int argc, char* argv[])
{
-
// document state of critical macros
#ifdef BOOST_POSIX_API
cout << "BOOST_POSIX_API is defined\n";
@@ -1823,8 +1872,15 @@
cout << "BOOST_WINDOWS_API is defined\n";
#endif
- if (argc > 1 && *argv[1]=='-' && *(argv[1]+1)=='t') report_throws = true;
- if (argc > 1 && *argv[1]=='-' && *(argv[1]+1)=='x') cleanup = false;
+ for (; argc > 1; --argc, ++argv)
+ {
+ if (*argv[1]=='-' && *(argv[1]+1)=='t')
+ report_throws = true;
+ else if (*argv[1]=='-' && *(argv[1]+1)=='x')
+ cleanup = false;
+ else if (*argv[1]=='-' && *(argv[1]+1)=='w')
+ skip_long_windows_tests = true;
+ }
// The choice of platform to test is make at runtime rather than compile-time
// so that compile errors for all platforms will be detected even though
@@ -1859,6 +1915,7 @@
initial_tests();
predicate_and_status_tests();
exception_tests();
+ platform_specific_tests();
create_directory_tests();
current_directory_tests();
space_tests();
@@ -1894,6 +1951,7 @@
resize_file_tests();
absolute_tests();
canonical_basic_tests();
+ permissions_tests();
copy_file_tests(f1, d1);
if (create_symlink_ok) // only if symlinks supported
{
@@ -1912,7 +1970,6 @@
write_time_tests(dir);
temp_directory_path_tests();
- platform_specific_tests();
cout << "testing complete" << endl;
Modified: trunk/libs/filesystem/v3/test/operations_unit_test.cpp
==============================================================================
--- trunk/libs/filesystem/v3/test/operations_unit_test.cpp (original)
+++ trunk/libs/filesystem/v3/test/operations_unit_test.cpp 2011-10-15 12:02:20 EDT (Sat, 15 Oct 2011)
@@ -40,6 +40,7 @@
using namespace boost::filesystem;
using namespace boost::system;
using std::cout;
+using std::endl;
using std::string;
#define CHECK(x) check(x, __FILE__, __LINE__)
@@ -53,21 +54,40 @@
++::boost::detail::test_errors();
- std::cout << file << '(' << line << "): test failed\n";
+ cout << file << '(' << line << "): test failed\n";
+ }
+
+ // file_status_test ----------------------------------------------------------------//
+
+ void file_status_test()
+ {
+ cout << "file_status test..." << endl;
+
+ file_status s = status(".");
+ int v = s.permissions();
+ cout << " status(\".\") permissions are "
+ << std::oct << (v & 0777) << std::dec << endl;
+ CHECK((v & 0400) == 0400);
+
+ s = symlink_status(".");
+ v = s.permissions();
+ cout << " symlink_status(\".\") permissions are "
+ << std::oct << (v & 0777) << std::dec << endl;
+ CHECK((v & 0400) == 0400);
}
// query_test ----------------------------------------------------------------------//
void query_test()
{
- std::cout << "query test..." << std::endl;
+ cout << "query test..." << endl;
error_code ec;
CHECK(file_size("no-such-file", ec) == static_cast<boost::uintmax_t>(-1));
CHECK(ec == errc::no_such_file_or_directory);
- CHECK(status("no-such-file") == file_status(file_not_found));
+ CHECK(status("no-such-file") == file_status(file_not_found, no_perms));
CHECK(exists("/"));
CHECK(is_directory("/"));
@@ -76,8 +96,8 @@
exists("/", ec);
if (ec)
{
- std::cout << "exists(\"/\", ec) resulted in non-zero ec.value()" << std::endl;
- std::cout << "ec value: " << ec.value() << ", message: "<< ec.message() << std::endl;
+ cout << "exists(\"/\", ec) resulted in non-zero ec.value()" << endl;
+ cout << "ec value: " << ec.value() << ", message: "<< ec.message() << endl;
}
CHECK(!ec);
@@ -92,7 +112,7 @@
void directory_iterator_test()
{
- std::cout << "directory_iterator_test..." << std::endl;
+ cout << "directory_iterator_test..." << endl;
directory_iterator end;
@@ -123,14 +143,14 @@
// cout << " " << it->path().string() << "\n";
}
- std::cout << "directory_iterator_test complete" << std::endl;
+ cout << "directory_iterator_test complete" << endl;
}
// operations_test -------------------------------------------------------//
void operations_test()
{
- std::cout << "operations test..." << std::endl;
+ cout << "operations test..." << endl;
error_code ec;
@@ -155,13 +175,14 @@
void directory_entry_test()
{
- std::cout << "directory_entry test..." << std::endl;
+ cout << "directory_entry test..." << endl;
- directory_entry de("foo.bar", file_status(regular_file), file_status(directory_file));
+ directory_entry de("foo.bar",
+ file_status(regular_file, owner_all), file_status(directory_file, group_all));
CHECK(de.path() == "foo.bar");
- CHECK(de.status() == file_status(regular_file));
- CHECK(de.symlink_status() == file_status(directory_file));
+ CHECK(de.status() == file_status(regular_file, owner_all));
+ CHECK(de.symlink_status() == file_status(directory_file, group_all));
CHECK(de < directory_entry("goo.bar"));
CHECK(de == directory_entry("foo.bar"));
CHECK(de != directory_entry("goo.bar"));
@@ -173,7 +194,7 @@
void directory_entry_overload_test()
{
- std::cout << "directory_entry overload test..." << std::endl;
+ cout << "directory_entry overload test..." << endl;
directory_iterator it(".");
path p(*it);
@@ -183,7 +204,7 @@
void error_handling_test()
{
- std::cout << "error handling test..." << std::endl;
+ cout << "error handling test..." << endl;
bool threw(false);
try
@@ -198,7 +219,7 @@
}
catch (...)
{
- cout << "\nunexpected exception type caught" << std::endl;
+ cout << "\nunexpected exception type caught" << endl;
}
CHECK(threw);
@@ -227,8 +248,9 @@
cout << "BOOST_FILESYSTEM_DECL" << BOOST_STRINGIZE(=BOOST_FILESYSTEM_DECL) << "\n";
cout << "BOOST_SYMBOL_VISIBLE" << BOOST_STRINGIZE(=BOOST_SYMBOL_VISIBLE) << "\n";
- cout << "current_path() is " << current_path().string() << std::endl;
+ cout << "current_path() is " << current_path().string() << endl;
+ file_status_test();
query_test();
directory_iterator_test();
operations_test();
@@ -236,8 +258,8 @@
directory_entry_overload_test();
error_handling_test();
- std::cout << unique_path() << std::endl;
- std::cout << unique_path("foo-%%%%%-%%%%%-bar") << std::endl;
+ cout << unique_path() << endl;
+ cout << unique_path("foo-%%%%%-%%%%%-bar") << endl;
return ::boost::report_errors();
}
Modified: trunk/libs/filesystem/v3/test/path_test.cpp
==============================================================================
--- trunk/libs/filesystem/v3/test/path_test.cpp (original)
+++ trunk/libs/filesystem/v3/test/path_test.cpp 2011-10-15 12:02:20 EDT (Sat, 15 Oct 2011)
@@ -1603,7 +1603,7 @@
BOOST_TEST(!fs::portable_file_name(std::string("foo.")));
}
- // replace_extension_tests ---------------------------------------------------//
+ // replace_extension_tests ---------------------------------------------------------//
void replace_extension_tests()
{
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk