Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r76528 - in branches/release: boost boost/filesystem boost/filesystem/v3 libs/filesystem libs/filesystem/v2/src libs/filesystem/v3/doc libs/filesystem/v3/doc/src libs/filesystem/v3/src libs/filesystem/v3/test libs/filesystem/v3/test/msvc10
From: bdawes_at_[hidden]
Date: 2012-01-15 14:22:29


Author: bemandawes
Date: 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
New Revision: 76528
URL: http://svn.boost.org/trac/boost/changeset/76528

Log:
Merge from trunk
Added:
   branches/release/libs/filesystem/v3/doc/src/
      - copied from r76527, /trunk/libs/filesystem/v3/doc/src/
Properties modified:
   branches/release/boost/filesystem/ (props changed)
   branches/release/boost/filesystem.hpp (props changed)
   branches/release/libs/filesystem/ (props changed)
Text files modified:
   branches/release/boost/filesystem/v3/operations.hpp | 140 ++++++++-
   branches/release/libs/filesystem/v2/src/v2_operations.cpp | 6
   branches/release/libs/filesystem/v3/doc/reference.html | 595 ++++++++++++++++++++++++++++++---------
   branches/release/libs/filesystem/v3/src/operations.cpp | 238 ++++++++++++---
   branches/release/libs/filesystem/v3/src/path.cpp | 119 ++++---
   branches/release/libs/filesystem/v3/src/windows_file_codecvt.cpp | 4
   branches/release/libs/filesystem/v3/test/msvc10/filesystem-v3.sln | 10
   branches/release/libs/filesystem/v3/test/operations_test.cpp | 84 ++++
   branches/release/libs/filesystem/v3/test/operations_unit_test.cpp | 58 ++-
   branches/release/libs/filesystem/v3/test/path_test.cpp | 2
   10 files changed, 952 insertions(+), 304 deletions(-)

Modified: branches/release/boost/filesystem/v3/operations.hpp
==============================================================================
--- branches/release/boost/filesystem/v3/operations.hpp (original)
+++ branches/release/boost/filesystem/v3/operations.hpp 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -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: branches/release/libs/filesystem/v2/src/v2_operations.cpp
==============================================================================
--- branches/release/libs/filesystem/v2/src/v2_operations.cpp (original)
+++ branches/release/libs/filesystem/v2/src/v2_operations.cpp 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -24,6 +24,7 @@
       !defined(_STATVFS_ACPP_PROBLEMS_FIXED))
 #define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
 #endif
+#if !defined(__PGI)
 #define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX
       // 64-bit systems or on 32-bit systems which don't have files larger
       // than can be represented by a traditional POSIX/UNIX off_t type.
@@ -40,6 +41,7 @@
 #if !defined(_WIN32_WINNT)
 #define _WIN32_WINNT 0x0500 // Default to Windows 2K or later
 #endif
+#endif
 
 
 #include <boost/filesystem/v2/operations.hpp>
@@ -1308,6 +1310,10 @@
         return error_code( ::closedir( h ) == 0 ? 0 : errno, system_category() );
       }
 
+#if defined(__PGI) && defined(__USE_FILE_OFFSET64)
+#define dirent dirent64
+#endif
+
       // warning: the only dirent member updated is d_name
       inline int readdir_r_simulator( DIR * dirp, struct dirent * entry,
         struct dirent ** result ) // *result set to 0 on end of directory

Modified: branches/release/libs/filesystem/v3/doc/reference.html
==============================================================================
--- branches/release/libs/filesystem/v3/doc/reference.html (original)
+++ branches/release/libs/filesystem/v3/doc/reference.html 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -59,45 +59,60 @@
     <a href="#Definitions">Definitions</a><br>
     <a href="#Conformance">Conformance</a><br>
     <a href="#Header-filesystem-synopsis">
- Header &lt;boost/filesystem.hpp&gt; synopsis</a><br>
+ Header <code>&lt;boost/filesystem.hpp&gt;</code> synopsis</a><br>
     <a href="#Error-reporting">Error reporting</a><br>
- Class path<br>
- &nbsp;&nbsp;&nbsp; path constructors<br>
-&nbsp;&nbsp;&nbsp; path assignments<br>
-&nbsp;&nbsp;&nbsp;&nbsp;path appends<br>
-&nbsp;&nbsp;&nbsp;&nbsp;path modifiers<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#path-native-format-observers">path native
+ Class path<br>
+&nbsp;&nbsp;&nbsp; path conversions<br>
+&nbsp;&nbsp;&nbsp; <a href="#path-Conversions-to-native-format"><code>path</code>
+ conversions to native format</a><br>
+&nbsp;&nbsp;&nbsp; <a href="#path-Conversions-to-generic-format"><code>path</code>
+ conversions to generic format</a><br>
+&nbsp;&nbsp;&nbsp; <a href="#path-Encoding-conversions"><code>path</code>
+ encoding conversions</a><br>
+&nbsp;&nbsp;&nbsp; path requirements<br>
+ &nbsp;&nbsp;&nbsp; path constructors<br>
+&nbsp;&nbsp;&nbsp; path assignments<br>
+&nbsp;&nbsp;&nbsp;&nbsp;path appends<br>
+&nbsp;&nbsp;&nbsp;&nbsp;path modifiers<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#path-native-format-observers"><code>path</code> native
     format observers</a><br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#path-generic-format-observers">path generic
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#path-generic-format-observers"><code>path</code> generic
     format observers</a><br>
-&nbsp;&nbsp;&nbsp; path decomposition<br>
-&nbsp;&nbsp;&nbsp; path query<br>
-&nbsp;&nbsp;&nbsp;&nbsp;path iterators<br>
-&nbsp;&nbsp;&nbsp;&nbsp;path deprecated functions<br>
-&nbsp;&nbsp;&nbsp;&nbsp;path non-member functions<br>
-&nbsp;&nbsp;&nbsp;&nbsp;path inserters and extractors<br>
- &nbsp;Class filesystem_error<br>
-&nbsp;&nbsp;&nbsp; <a href="#filesystem_error-members">filesystem_error
+&nbsp;&nbsp;&nbsp; path decomposition<br>
+&nbsp;&nbsp;&nbsp; path query<br>
+&nbsp;&nbsp;&nbsp;&nbsp;path iterators<br>
+&nbsp;&nbsp;&nbsp;&nbsp;path deprecated functions<br>
+&nbsp;&nbsp;&nbsp;&nbsp;path non-member functions<br>
+&nbsp;&nbsp;&nbsp;&nbsp;path inserters and extractors<br>
+ &nbsp;Class filesystem_error<br>
+&nbsp;&nbsp;&nbsp; <a href="#filesystem_error-members"><code>filesystem_error</code>
     constructors</a><br>
-&nbsp;&nbsp;&nbsp; filesystem_error path1<br>
-&nbsp;&nbsp;&nbsp; filesystem_error path2<br>
-&nbsp;&nbsp;&nbsp; filesystem_error what<br>
-Class directory_entry<br>
+&nbsp;&nbsp;&nbsp; <code>f</code>ilesystem_error path1<br>
+&nbsp;&nbsp;&nbsp; filesystem_error path2<br>
+&nbsp;&nbsp;&nbsp; <a href="#filesystem_error-what"><code>filesystem_error</code><code>
+ </code>what</a></td>
+ <td width="33%" valign="top">
+ Enum file_type<br>
+ Enum perms<br>
+ <a href="#file_status">Class
+ <code>file_status</code></a><br>
 &nbsp;&nbsp;&nbsp;
-directory_entry constructors<br>
-&nbsp;&nbsp;&nbsp;&nbsp;directory_entry modifiers<br>
-&nbsp;&nbsp;&nbsp;&nbsp;directory_entry observers<br>
-Class directory_iterator<br>
-&nbsp;&nbsp;&nbsp; <a href="#directory_iterator-members">directory_iterator
+ <a href="#file_status">
+ <code>file_status</code></a> constructors<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<code>file_status-modifiers</code> observers<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<code>file_status-observers</code> modifiers<br>
+Class directory_entry<br>
+&nbsp;&nbsp;&nbsp;
+directory_entry constructors<br>
+&nbsp;&nbsp;&nbsp;&nbsp;directory_entry observers<br>
+&nbsp;&nbsp;&nbsp;&nbsp;directory_entry modifiers<br>
+Class directory_iterator<br>
+&nbsp;&nbsp;&nbsp; <a href="#directory_iterator-members"><code>directory_iterator</code>
     members</a><br>
-Class recursive_directory_iterator<br>
- <a href="#file_status">Class
- file_status</a><br>
- &nbsp;</td>
- <td width="33%" valign="top">
+Class recursive_directory_iterator<br>
     <a href="#Operational-functions">
     Operational functions</a><br>
-&nbsp;&nbsp;&nbsp;&nbsp absolute<br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp absolute<br>
 &nbsp;&nbsp;&nbsp;&nbsp; canonical<br>
 &nbsp;&nbsp;&nbsp;&nbsp; copy<br>
 &nbsp;&nbsp;&nbsp;&nbsp; copy_directory<br>
@@ -112,13 +127,15 @@
 &nbsp;&nbsp;&nbsp;&nbsp equivalent<br>
 &nbsp;&nbsp;&nbsp;&nbsp file_size<br>
 &nbsp;&nbsp;&nbsp;&nbsp; hard_link_count<br>
-&nbsp;&nbsp;&nbsp;&nbsp; initial_path<br>
+ &nbsp;&nbsp;&nbsp;&nbsp; initial_path<br>
 &nbsp;&nbsp;&nbsp;&nbsp is_directory<br>
-&nbsp;&nbsp;&nbsp;&nbsp is_empty<br>
-&nbsp;&nbsp;&nbsp;&nbsp is_other<br>
+&nbsp;&nbsp;&nbsp;&nbsp is_empty</code></td>
+ <td width="34%" valign="top">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp is_other<br>
 &nbsp;&nbsp;&nbsp;&nbsp is_regular_file<br>
 &nbsp;&nbsp;&nbsp;&nbsp is_symlink<br>
 &nbsp;&nbsp;&nbsp;&nbsp last_write_time<br>
+&nbsp;&nbsp;&nbsp;&nbsp; permissions<br>
 &nbsp;&nbsp;&nbsp;&nbsp; read_symlink<br>
 &nbsp;&nbsp;&nbsp;&nbsp remove<br>
 &nbsp;&nbsp;&nbsp;&nbsp remove_all<br>
@@ -130,8 +147,7 @@
 &nbsp;&nbsp;&nbsp;&nbsp symlink_status<br>
 &nbsp;&nbsp;&nbsp;&nbsp system_complete<br>
 &nbsp;&nbsp;&nbsp;&nbsp temp_directory_path<br>
-&nbsp;&nbsp;&nbsp;&nbsp; unique_path</td>
- <td width="34%" valign="top">
+&nbsp;&nbsp;&nbsp;&nbsp; </code> <code> unique_path</code><br>
     <a href="#File-streams">File streams</a><br>
 <a href="#Path-decomposition-table">Path decomposition table</a><br>
     <a href="#long-path-warning">Warning: Long paths on Windows and the
@@ -194,6 +210,7 @@
 no elements which are symbolic links, and no dot or dot dot elements.</p>
 <p><i><b><a name="Pathname">Pathname</a>:</b> </i>A character string that represents a
 path. Pathnames are formatted according to the generic pathname format or the
+implementation defined
 native pathname format.</p>
 <p><b><i><a name="generic-pathname-format">Generic pathname format:</a></i></b></p>
 <blockquote>
@@ -287,11 +304,21 @@
 static_assert</code>, a <code>filesystem_error</code> exception, a special
 return value, or some other manner. <i>--end note</i>]</p>
 </blockquote>
+<p>Implementations are not required to provide behavior that is not supported by
+a particular file system.</p>
+<blockquote>
+<p>[<i>Example:</i> The <a href="http://en.wikipedia.org/wiki/FAT_filesystem">
+FAT file system</a> used by some memory cards, camera memory, and floppy discs
+does not support hard links, symlinks, and many other features of more capable
+file systems. Implementations are only required to support the FAT features
+supported by the host operating system. <i>-- end example</i>]</p>
+</blockquote>
 <p>Specific operating systems such as <i>OpenMVS</i>,
 <i>UNIX</i>, and <i>Windows</i> are mentioned only for purposes of illustration or to
-give guidance to implementers. No slight to other operating systems is implied
-or intended.</p>
-<p>The <i>Effects</i> and <i>Postconditions</i> of functions described in this
+give guidance to users and implementers. No slight to other operating systems is implied
+or intended. When unlikely to cause confusion, the term <i>POSIX</i> is
+sometimes used to refer to &quot;POSIX-compliant operating systems&quot;.</p>
+<p>The behavior of functions described in this
 reference
 may not be achieved in
 the presence of race conditions. No diagnostic is required.</p>
@@ -337,10 +364,23 @@
 
       class recursive_directory_iterator;
 
- enum <a name="file_type">file_type</a> { status_error, file_not_found, regular_file, directory_file,
- symlink_file, block_file, character_file, fifo_file, socket_file,
- type_unknown
- };
+ enum <a name="file_type" href="#Enum-file_type">file_type</a>
+ {
+ status_error, file_not_found, regular_file, directory_file,
+ symlink_file, block_file, character_file, fifo_file, socket_file,
+ type_unknown
+ };
+
+ enum perms
+ {
+ no_perms,
+ owner_read, owner_write, owner_exe, owner_all,
+ group_read, group_write, group_exe, group_all,
+ others_read, others_write, others_exe, others_all, all_all,
+ set_uid_on_exe, set_gid_on_exe, sticky_bit,
+ perms_mask, perms_not_known,
+ add_perms, remove_perms, symlink_perms
+ };
 
       class file_status;
 
@@ -537,8 +577,14 @@
 <h2><a name="class-path">Class <code>path</code></a></h2>
 <p>An object of class <code>path</code> represents a path,
 and contains a pathname Such an object is concerned only with the lexical and syntactic aspects
-of a path. The path may not actually exist in external storage, and may contain pathnames which are not even valid for the current operating
-system. </p>
+of a path. The path does not necessarily exist in external storage, and the
+pathname is not necessarily valid for the current operating
+system or for a particular file system.</p>
+<blockquote>
+<p>[<i>Example:</i> A long path name on Windows
+is an example of an innocuous appearing path that is not actually valid. <i>--
+end example</i>]</p>
+</blockquote>
 <pre> namespace boost
   {
     namespace filesystem
@@ -657,9 +703,96 @@
   } // namespace boost</pre>
 <p><code><a name="value_type">value_type</a></code> is an implementation-defined
 <code>typedef</code> for the
-character type used by the implementation to represent pathnames.</p>
-<p>If the value type of&nbsp; [<code>begin</code>,<code>end</code>)
- or <code>source</code> arguments for member functions is not <code>value_type</code>,
+character type used by the operating system to represent pathnames.</p>
+<p>Member functions described as returning <code>const string</code>, <code>
+const wstring</code>, <code>const u16string</code>, or <code>const u32string</code> are permitted to return <code>const string&amp;</code>, <code>const
+wstring&amp;</code>, <code>const u16string&amp;</code>, or <code>const u32string&amp;</code>,
+respectively.</p>
+<blockquote>
+<p>[<i>Note:</i> This allows implementations to avoid unnecessary copies when no
+conversion is required.
+Return-by-value is specified as
+<code>const</code> to ensure programs won't break if moved to a return-by-reference
+implementation. <i>--
+end note</i>]</p>
+</blockquote>
+<h3><a name="path-Conversions"><code>path</code> Conversions</a></h3>
+<h4><a name="path-Conversions-to-native-format"><code>path</code> Conversions to
+native format</a></h4>
+<p>Member function arguments that take character sequences representing paths
+may use the generic pathname format or
+the native pathname format. If such an
+argument uses the generic format, an implementation defined conversion to native format is performed
+during the processing of the argument. </p>
+<blockquote>
+<p>[<i>Note:</i> No conversion occurs on POSIX and Windows since they have
+native formats that conform to the generic format. <i>--end note</i>]</p>
+<p>[<i>Rationale:</i> There is no unambiguous way for an implementation to
+always be able distinguish between native format and generic format arguments.
+This is by design as it simplifies use. Should an implementation encounter an
+operating system where disambiguation is required, an implementation defined
+native format prefix can be introduced to identify the native format. <i>-- end
+rationale</i>]</p>
+</blockquote>
+
+<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%">
+ <tr>
+ <td style="font-size: 10pt">
+ Class <code>path</code> does not currently map invalid characters in
+ filenames to valid characters. In the future we might add something like
+ this:<blockquote>
+<p>When converting filenames to the native operating system format,
+implementations are encouraged, but not required, to convert otherwise invalid
+characters or character sequences to valid characters or character sequences.
+Such conversions are implementation-defined.</p>
+<blockquote>
+<p>[<i>Note:</i> Filename conversion allows much wider portability of both
+programs and filenames that would otherwise be possible.</p>
+<p>Implementations are encouraged to base conversion on existing standards or
+practice. Examples include the Uniform Resource Locator escape syntax of a percent sign (<code>'%'</code>)
+followed by two hex digits representing the character value. On
+<i>OpenVMS</i>, which does not allow percent signs in filenames, a dollar sign (<code>'$'</code>)
+followed by two hex digits is the existing practice, as is converting lowercase
+letters to uppercase.<i> -- end note.</i>]</p>
+</blockquote>
+ </blockquote>
+ </td>
+ </tr>
+</table>
+
+<p>If the native format requires
+paths for regular files to be formatted differently from paths for directories, the
+path shall be treated as a directory path if last element is a separator,
+otherwise it shall be treated as a regular file path.</p>
+
+<blockquote>
+
+<p>[<i>Note</i>: The above paragraph does not apply to POSIX and Windows since
+they use the same format
+for both regular file and directory pathnames. <i>--end note</i>]</p>
+
+<p>[<i>Example:</i>
+On OpenVMS, a path
+constructed from <code>&quot;/cats/jane&quot;</code> would considered a regular file
+path, and have a native format of <code>&quot;[CATS]JANE&quot;</code>, while a
+path constructed from <code>&quot;/cats/jane/&quot;</code> would be considered a
+directory path, and have a native format of <code>&quot;[CATS.JANE]&quot;</code>.
+<i>--end example</i>]</p>
+
+</blockquote>
+<h4><a name="path-Conversions-to-generic-format"><code>path</code> Conversions
+to generic format</a></h4>
+<p>Generic format observer
+functions return strings formatted according to the
+generic pathname format. The conversion
+from generic to native formats is implementation defined.</p>
+<blockquote>
+<p>[<i>Note:</i> For POSIX, no conversion is performed. For Windows, backslashes are converted to
+forward slashes. <i>-- end note</i>]</p>
+</blockquote>
+<h4><a name="path-Encoding-conversions"><code>path</code> Encoding conversions</a></h4>
+<p>If the value type of member function arguments that are character sequences
+representing paths is not <code>value_type</code>,
 and no <code>cvt</code> argument is supplied, conversion to <code>value_type</code>
 occurs using an imbued locale. This imbued locale is initialized with a <code>
 codecvt</code> facet appropriate for the operating system.</p>
@@ -670,12 +803,11 @@
 parameters to be in UTF-8 encoding and nothing else.&quot; See
 <a href="http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html">
 Apple docs</a>. <i>-- end rationale</i>]</p>
-<p>For Windows-like implementations, including
- Cygwin and
+<p>For Windows-like implementations, including
 <a href="http://www.mingw.org/">MinGW</a>, <code>path::value_type</code> is <code>
 wchar_t</code>. The default imbued locale provides a <code>codecvt</code> facet
 that invokes Windows <code>MultiByteToWideChar</code> or <code>
-WideCharToMultiByte</code> API's with a codepage of <code>CP_THREAD_ACP</code>
+WideCharToMultiByte</code> API with a codepage of <code>CP_THREAD_ACP</code>
 if Windows <code>AreFileApisANSI()</code>is true, otherwise codepage <code>
 CP_OEMCP</code>. [<i>Rationale:</i> this is the current behavior of C and C++
 programs that perform file operations using narrow character string to identify
@@ -685,26 +817,15 @@
 is <code>char</code>. The default imbued locale is <code>std::locale(&quot;&quot;)</code>.
 [<i>Rationale:</i> ISO C specifies this as &quot;the locale-specific native
 environment&quot;, while POSIX says it &quot;Specifies an implementation-defined native
-environment.&quot; <i>-- end rationale</i></p>
+environment.&quot; <i>-- end rationale</i>]</p>
 </blockquote>
-<p>For member functions described as returning <code>const string</code>, <code>
-const wstring</code>, <code>const u16string</code>, or <code>const u32string</code>,
-implementations are permitted to return <code>const string&amp;</code>, <code>const
-wstring&amp;</code>, <code>const u16string&amp;</code>, or <code>const u32string&amp;</code>,
-respectively.</p>
-<blockquote>
-<p>[<i>Note:</i> This allows implementations to avoid unnecessary copies when no
-conversion is required.
-Return-by-value is specified as
-<code>const</code> to ensure programs won't break if moved to a return-by-reference
-implementation. <i>--
-end note</i>]</p>
-</blockquote>
-<p><code><a name="InputIterator">InputIterator</a></code> is required meet the
+<h3><a name="path-Requirements"><code>path</code> Requirements</a></h3>
+<p>Template parameters named <code><a name="InputIterator">InputIterator</a></code>
+are required meet the
 requirements for a C++ standard library <code>RandomIterator</code>
 compliant iterator. The iterator's value type is required to be <code>char</code>, <code>
   wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</p>
-<p><code><a name="Source">Source</a></code> is required to be one of:</p>
+<p>Template parameters named <code><a name="Source">Source</a></code> are required to be one of:</p>
 <ul>
   <li>A container with a value type of <code>char</code>, <code>
   wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</li>
@@ -715,45 +836,6 @@
   wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</li>
   <li>A <code>boost::filesystem::directory_entry</code>.</li>
 </ul>
-<p>The specifications for <code>path</code> functions require that
-arguments in the generic pathname format be converted to native pathname format
-as they are stored in <code>pathname</code>. If the native format requires
-regular file paths and directory paths to be formatted differently, the
-implementation shall determine which format to use according to whether or not
-the last element of the generic format string is a separator. [<i>Example:</i>
-On OpenVMS, a path
-constructed from <code>&quot;/cats/jane&quot;</code> would considered a regular file
-path, and have a native format of <code>&quot;[CATS]JANE&quot;</code>, while a
-path constructed from <code>&quot;/cats/jane/&quot;</code> would be considered a
-directory path, and have a native format of <code>&quot;[CATS.JANE]&quot;</code>.
-<i>--end example</i>] [<i>Note</i>: POSIX and Windows use the same native format
-for both regular file and directory pathnames, so this paragraph does not apply to
-them. <i>--end note</i>]</p>
-
-<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%">
- <tr>
- <td style="font-size: 10pt">
- Class <code>path</code> does not currently map invalid characters in
- filenames to valid characters. In the future we might add something like
- this:<blockquote>
-<p>When converting filenames to the native operating system format,
-implementations are encouraged, but not required, to convert otherwise invalid
-characters or character sequences to valid characters or character sequences.
-Such conversions are implementation-defined.</p>
-<blockquote>
-<p>[<i>Note:</i> Filename conversion allows much wider portability of both
-programs and filenames that would otherwise be possible.</p>
-<p>Implementations are encouraged to base conversion on existing standards or
-practice. Examples include the Uniform Resource Locator escape syntax of a percent sign (<code>'%'</code>)
-followed by two hex digits representing the character value. On
-<i>OpenVMS</i>, which does not allow percent signs in filenames, a dollar sign (<code>'$'</code>)
-followed by two hex digits is the existing practice, as is converting lowercase
-letters to uppercase.<i> -- end note.</i>]</p>
-</blockquote>
- </blockquote>
- </td>
- </tr>
-</table>
 
 <h3> <a name="path-constructors"> <code>
 <font size="4">path</font></code> constructors</a></h3>
@@ -1418,6 +1500,228 @@
   not empty, and <code>system_error::what()</code> strings in the returned
   string.</p>
 </blockquote>
+<h3><a name="Enum-file_type">Enum file_type</a></h3>
+<p>This enum specifies constants uses to identify file types.</p>
+<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
+ <tr>
+ <td><b>Constant Name</b></td>
+ <td><b>Meaning</b></td>
+ </tr>
+ <tr>
+ <td><code>status_error</code></td>
+ <td>An error occurred while trying to obtain the status of the file. The
+ file simply not being found is <b><u>not</u></b> considered a status error.
+ </td>
+ </tr>
+ <tr>
+ <td><code>file_not_found</code></td>
+ <td>The file could not be found</td>
+ </tr>
+ <tr>
+ <td><code>regular_file</code></td>
+ <td>Regular file</td>
+ </tr>
+ <tr>
+ <td><code>directory_file</code></td>
+ <td>Directory file</td>
+ </tr>
+ <tr>
+ <td><code>symlink_file</code></td>
+ <td>Symbolic link file</td>
+ </tr>
+ <tr>
+ <td><code>block_file</code></td>
+ <td>Block special file</td>
+ </tr>
+ <tr>
+ <td><code>character_file</code></td>
+ <td>Character special file</td>
+ </tr>
+ <tr>
+ <td><code>fifo_file</code></td>
+ <td>FIFO or pipe file</td>
+ </tr>
+ <tr>
+ <td><code>socket_file</code></td>
+ <td>Socket file</td>
+ </tr>
+ <tr>
+ <td><code>type_unknown</code></td>
+ <td>The file exists, but it is of a system specific type not covered by any
+ of the above cases.</td>
+ </tr>
+</table>
+<h3><a name="Enum-perms">Enum perms</a></h3>
+<p>This enum specifies bitmask constants uses to identify file
+permissions. The POSIX standard specifies actual values, and those values have
+been adopted here because they are very familiar and ingrained for many POSIX
+users.</p>
+<blockquote>
+<p>Caution: Operating systems do not always support permissions as described in
+the table.</p>
+<p>There is much variation in the meaning of <code><a href="#sticky_bit">
+sticky_bit</a></code>; do not use it unless you understand what it means for
+your operating system.</p>
+<p>There is much variation in how operating systems treat symlinks. See <code>
+symlink_perms</code>.</p>
+<p>Windows: All permissions except write are currently ignored. There is only a
+single write permission; setting write permission for owner, group, or others
+sets write permission for all, and removing write permission for owner, group,
+or others removes write permission for all. </p>
+</blockquote>
+<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
+ <tr>
+ <td><b>Name</b></td>
+ <td align="center"><b>Value<br>
+ (octal)</b></td>
+ <td align="center"><b>POSIX<br>
+ macro</b></td>
+ <td><b>Definition or notes</b></td>
+ </tr>
+
+<tr><td>
+ <p dir="ltr"><code>no_perms</code></td><td><code>0</code></td><td></td>
+ <td>There are no permissions set for the file. Note: <code>file_not_found</code> is
+ <code>no_perms</code> rather than <code>perms_not_known</code></td>
+</tr>
+<tr><td><code>owner_read</code></td><td><code>0400</code></td><td> <code>S_IRUSR</code></td>
+ <td> Read permission, owner</td>
+</tr>
+<tr><td><code>owner_write</code></td><td><code>0200</code></td><td> <code>S_IWUSR</code></td>
+ <td> Write permission, owner</td>
+</tr>
+<tr><td><code>owner_exe</code></td><td><code>0100</code></td><td> <code>S_IXUSR</code></td>
+ <td> Execute/search permission, owner</td>
+</tr>
+<tr><td><code>owner_all</code></td><td><code>0700</code></td><td> <code>S_IRWXU</code></td>
+ <td> Read, write, execute/search by owner; <code>owner_read | owner_write | owner_exe</code></td>
+</tr>
+<tr><td><code>group_read</code></td><td><code>040</code></td><td> <code>S_IRGRP</code></td>
+ <td> Read permission, group</td>
+</tr>
+<tr><td><code>group_write</code></td><td><code>020</code></td><td> <code>S_IWGRP</code></td>
+ <td> Write permission, group</td>
+</tr>
+<tr><td><code>group_exe</code></td><td><code>010</code></td><td> <code>S_IXGRP</code></td>
+ <td> Execute/search permission, group</td>
+</tr>
+<tr><td><code>group_all</code></td><td><code>070</code></td><td> <code>S_IRWXG</code></td>
+ <td> Read, write, execute/search by group; <code>group_read | group_write |
+ group_exe</code></td>
+</tr>
+<tr><td><code>others_read</code></td><td><code>04</code></td><td> <code>S_IROTH</code></td>
+ <td> Read permission, others</td>
+</tr>
+<tr><td><code>others_write</code></td><td><code>02</code></td><td> <code>S_IWOTH</code></td>
+ <td> Write permission, others</td>
+</tr>
+<tr><td><code>others_exe</code></td><td><code>01</code></td><td> <code>S_IXOTH</code></td>
+ <td> Execute/search permission, others</td>
+</tr>
+<tr><td><code>others_all</code></td><td><code>07</code></td><td> <code>S_IRWXO</code></td>
+ <td>Read, write, execute/search by others; <code>others_read | others_write | others_exe</code></td>
+</tr>
+<tr><td><code>all_all</code></td><td><code>0777</code></td><td> </td><td><code>owner_all | group_all | others_all</code></td>
+</tr>
+<tr><td><code>set_uid_on_exe</code></td><td><code>04000</code></td><td> <code>S_ISUID</code></td>
+ <td> Set-user-ID on execution</td>
+</tr>
+<tr><td><code>set_gid_on_exe</code></td><td><code>02000</code></td><td> <code>S_ISGID</code></td>
+ <td> Set-group-ID on execution</td>
+</tr>
+<tr><td><code><a name="sticky_bit">sticky_bit</a> </code> </td><td><code>01000</code></td><td> <code>S_ISVTX</code></td>
+ <td> Meaning varies; see http:en.wikipedia.org/wiki/Sticky_bit</td>
+</tr>
+<tr><td><code>perms_mask</code></td><td><code>07777</code></td><td> &nbsp;</td>
+ <td><code>all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit</code></td>
+</tr>
+<tr><td><code>perms_not_known</code></td><td><code>0xFFFF</code></td><td></td><td>
+ The permissions are not known, such as when a <code>file_status</code> object
+ is created without specifying the permissions</td>
+</tr>
+<tr><td>
+ <p dir="ltr"><code>add_perms</code></td><td><code>0x1000</code></td><td></td><td>
+ <p dir="ltr"><code>permissions()</code> adds the argument permission bits to the
+ file's current bits</td>
+</tr>
+<tr><td><code>remove_perms</code></td><td><code>0x2000</code></td><td></td><td>
+ <code>permissions()</code> removes the argument permission bits from the
+ file's current bits</td>
+</tr>
+<tr><td><code><a name="symlink_perms">symlink_perms</a></code></td><td><code>0x4000</code></td><td></td><td>
+ On POSIX <code>permissions()</code> resolves symlinks unless <code>symlink_perms</code>
+ is specified.
+ Meaningless on Windows as <code>permissions()</code> never resolves symlinks.
+ Meaningless on Mac OS X and some other BSD systems as <code>permissions()</code>
+ always resolves symlinks. Get over it.</td>
+</tr>
+
+</table>
+<h3><a name="file_status">Class file_status</a></h3>
+<pre> namespace boost
+ {
+ namespace filesystem
+ {
+ class file_status
+ {
+ public:
+
+ // constructors
+ file_status() noexcept;
+ explicit file_status(file_type ft, perms prms = perms_not_known) noexcept;
+
+ // compiler generated
+ file_status(const file_status&amp;) noexcept;
+ file_status&amp; operator=(const file_status&amp;) noexcept;
+ ~file_status() noexcept;
+
+ // observers
+ file_type type() const noexcept;
+ perms permissions() const noexcept;
+
+ // modifiers
+ void type(file_type ft) noexcept;
+ void permissions(perms prms) noexcept;
+ };
+ } // namespace filesystem
+ } // namespace boost</pre>
+<p>An object of type <code>file_status</code> stores information about the type
+and permissions of a file.</p>
+<h4 dir="ltr"><a name="file_status-constructors"><code>file_status</code>
+constructors</a></h4>
+<pre>explicit file_status() noexcept;</pre>
+<blockquote>
+ <p><i>Postconditions:</i> <code>type() == status_error</code>, <code>
+ permissions() == perms_not_known</code>.</p>
+</blockquote>
+<pre>explicit file_status(file_type ft, perms prms = perms_not_known) noexcept;</pre>
+<blockquote>
+ <p><i>Postconditions:</i> <code>type() == ft</code>, <code>permissions() ==
+ prms</code>.</p>
+</blockquote>
+ <h4 dir="ltr"><a name="file_status-observers"><code>file_status</code>
+ observers</a></h4>
+<pre>file_type type() const noexcept;</pre>
+<blockquote>
+ <p><i>Returns: </i>The value of <code>type()</code> specified by the <i>
+ postconditions</i> of the most recent call to a constructor, operator=, or
+ <code>type(file_type)</code> function.</p>
+</blockquote>
+<pre>perms permissions() const noexcept;</pre>
+<blockquote>
+ <p><i>Returns: </i>The value of <code>permissions()</code> specified by the <i>
+ postconditions</i> of the most recent call to a constructor, operator=, or
+ <code>permissions(perms)</code> function.</p>
+</blockquote>
+<h4 dir="ltr"><a name="file_status-modifiers"><code>file_status</code> modifiers</a></h4>
+<pre>void type(file_type ft) noexcept;</pre>
+<blockquote>
+ <p dir="ltr"><i>Postconditions:</i> <code>type() == ft</code>.</p>
+</blockquote>
+<pre>void permissions(perms prms) noexcept;</pre>
+<blockquote>
+ <p dir="ltr"><i>Postconditions:</i> <code>permissions() == prms</code>.</p>
+</blockquote>
 <h3><a name="Class-directory_entry">Class <code>directory_entry</code></a></h3>
 <div dir="ltr">
 <pre> namespace boost
@@ -1927,45 +2231,6 @@
   <p>[<i>Note:</i> <code>no_push()</code> is used to prevent
   unwanted recursion into a directory. <i>--end note</i>]</p>
 </blockquote>
-<h3><a name="file_status">Class file_status</a></h3>
-<pre> namespace boost
- {
- namespace filesystem
- {
- class file_status
- {
- public:
- file_status();
- file_status(const file_status&amp;);
- explicit file_status(file_type v=status_error);
- ~file_status();
-
- file_type type() const;
- void type(file_type v);
- };
- } // namespace filesystem
- } // namespace boost</pre>
-<p>An object of type <code>file_status</code> stores information about the status of a
-file. The internal form of the stored information is unspecified.</p>
-<blockquote>
- <p><i>[Note: </i>The class may be extended in the future to store
- additional status information. <i>--end note]</i></p>
-</blockquote>
-<h4>Members</h4>
-<pre>explicit file_status(file_type v=status_error);</pre>
-<blockquote>
- <p><i>Effects:</i> Stores <code>v</code>.</p>
- <p><i>Throws:</i> Nothing.</p>
-</blockquote>
-<pre>file_type type() const;</pre>
-<blockquote>
- <p><i>Returns: </i>The stored file_type.</p>
-</blockquote>
-<pre>void type(file_type v);</pre>
-<blockquote>
- <p><i>Effects:</i> Stores <code>v</code>, replacing the previously stored
- value.</p>
-</blockquote>
 <h3><a name="Operational-functions">Operational functions</a></h3>
 <p>Operational functions query or modify files, including directories, in external
 storage.</p>
@@ -2436,6 +2701,42 @@
   new_time</code> is not specified since it might not hold for file systems
   with coarse time granularity. <i>-- end note</i>]</p>
 </blockquote>
+<pre>void permissions(const path&amp; p, perms prms);
+void permissions(const path&amp; p, perms prms, system::error_code&amp; ec);</pre>
+<blockquote>
+ <p dir="ltr">Applies an operating system set of permissions to a file. See
+ perms for specifics.<br>
+ <i><br>
+ Requires:</i> <code>!((prms &amp; add_perms) &amp;&amp; (prms &amp; remove_perms))</code>.</p>
+ <p dir="ltr"><i>Effects:</i> Applies the effective permissions bits from <code>
+ prms</code> to the file <code>p</code> resolves to, as if by <i>POSIX</i>
+ <code>
+ <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html">
+ fchmodat()</a></code>. The effective permission bits are determined as
+ specified by the following table. </p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
+ <tr>
+ <td><b>bits present in <code>prms</code></b></td>
+ <td><b>Effective bits applied</b></td>
+ </tr>
+ <tr>
+ <td>Neither <code>add_perms</code> nor <code>remove_perms</code></td>
+ <td><code>prms &amp; perms_mask</code></td>
+ </tr>
+ <tr>
+ <td><code>add_perms</code></td>
+ <td>
+ <p dir="ltr">current_status.permissions() | (<code>prms &amp; perms_mask</code>)
+ </td>
+ </tr>
+ <tr>
+ <td><code>remove_perms</code></td>
+ <td>current_status.permissions() &amp; ~(<code>prms &amp; perms_mask</code>) </td>
+ </tr>
+ </table>
+ <p>[<i>Note:</i> Conceptually permissions are viewed as bits, but the actual
+ implementation by a file system may use some other mechanism. -- <i>end note</i>]</p>
+</blockquote>
 <pre>path <a name="read_symlink">read_symlink</a>(const path&amp; p);
 path read_symlink(const path&amp; p, system::error_code&amp; ec);</pre>
 <blockquote>
@@ -3295,7 +3596,7 @@
 <p>The Windows API has many functions that also have Unicode versions to permit
 an extended-length path for a maximum total path length of 32,767 characters.
 ... To specify an extended-length path, use the <b>&quot;\\?\&quot; prefix</b>. For
-example, &quot;\\?\D:\very long path&quot;.&nbsp;
+example, &quot;\\?\D:\<em>very long path</em>&quot;.&nbsp;
 <i>[C++ string literals require backslashes be doubled, of course.]</i></p>
 </blockquote>
 <p>Because most Boost.Filesystem operational functions just pass the contents of
@@ -3364,7 +3665,7 @@
 </font>
 <a href="http://www.boost.org/LICENSE_1_0.txt"><font size="2">www.boost.org/LICENSE_1_0.txt</font></a></p>
 <p><font size="2">Revised
-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->06 October 2011<!--webbot bot="Timestamp" endspan i-checksum="32189" --></font></p>
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->31 October 2011<!--webbot bot="Timestamp" endspan i-checksum="32182" --></font></p>
 
 </body>
 

Modified: branches/release/libs/filesystem/v3/src/operations.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/src/operations.cpp (original)
+++ branches/release/libs/filesystem/v3/src/operations.cpp 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -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,25 @@
       || errval == ERROR_BAD_NETPATH; // "//nosuch" on Win32
   }
 
+#if defined(_MSC_VER) || (defined(__GLIBCXX__) && __GLIBCXX__ >= 20110325)
+# define BOOST_FILESYSTEM_STRICMP _stricmp
+#else
+# define BOOST_FILESYSTEM_STRICMP strcmp
+#endif
+
+ 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 (BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".exe") == 0
+ || BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".com") == 0
+ || BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".bat") == 0
+ || BOOST_FILESYSTEM_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 +609,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))
     {
@@ -1329,6 +1348,83 @@
 # 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; }
+# endif
+
+ 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;
+
+# ifdef BOOST_POSIX_API
+ 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)
+ prms = current_status.permissions() & ~prms;
+
+ // Mac OS X Lion and some other platforms don't support fchmodat()
+# if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) \
+ && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5100)
+ 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
+ {
+ 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());
+ }
+
+# else // Windows
+
+ // if not going to alter FILE_ATTRIBUTE_READONLY, just return
+ if (!(!((prms & (add_perms | remove_perms)))
+ || (prms & (owner_write|group_write|others_write))))
+ return;
+
+ DWORD attr = ::GetFileAttributesW(p.c_str());
+
+ if (error(attr == 0, p, ec, "boost::filesystem::permissions"))
+ return;
+
+ if (prms & add_perms)
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else if (prms & remove_perms)
+ attr |= FILE_ATTRIBUTE_READONLY;
+ else if (prms & (owner_write|group_write|others_write))
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else
+ attr |= FILE_ATTRIBUTE_READONLY;
+
+ error(::SetFileAttributesW(p.c_str(), attr) == 0,
+ p, ec, "boost::filesystem::permissions");
+# endif
+ }
+
   BOOST_FILESYSTEM_DECL
   path read_symlink(const path& p, system::error_code* ec)
   {
@@ -1492,7 +1588,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 +1597,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 +1624,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 +1644,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 +1668,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 +1677,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 +1711,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 +1949,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 +1997,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 +2005,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 +2042,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 +2118,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 +2137,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: branches/release/libs/filesystem/v3/src/path.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/src/path.cpp (original)
+++ branches/release/libs/filesystem/v3/src/path.cpp 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -727,56 +727,55 @@
   // locale helpers //
   //------------------------------------------------------------------------------------//
 
- std::locale default_locale()
- {
-# ifdef BOOST_WINDOWS_API
- std::locale global_loc = std::locale();
- std::locale loc(global_loc, new windows_file_codecvt);
- return loc;
-
-# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
- // "All BSD system functions expect their string parameters to be in UTF-8 encoding
- // and nothing else." See
- // http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html
- //
- // "The kernel will reject any filename that is not a valid UTF-8 string, and it will
- // even be normalized (to Unicode NFD) before stored on disk, at least when using HFS.
- // The right way to deal with it would be to always convert the filename to UTF-8
- // before trying to open/create a file." See
- // http://lists.apple.com/archives/unix-porting/2007/Sep/msg00023.html
- //
- // "How a file name looks at the API level depends on the API. Current Carbon APIs
- // handle file names as an array of UTF-16 characters; POSIX ones handle them as an
- // array of UTF-8, which is why UTF-8 works well in Terminal. How it's stored on disk
- // depends on the disk format; HFS+ uses UTF-16, but that's not important in most
- // cases." See
- // http://lists.apple.com/archives/applescript-users/2002/Sep/msg00319.html
- //
- // Many thanks to Peter Dimov for digging out the above references!
-
- std::locale global_loc = std::locale();
- std::locale loc(global_loc, new boost::filesystem::detail::utf8_codecvt_facet);
- return loc;
-
-# else // Other POSIX
-
- // ISO C calls std::locale("") "the locale-specific native environment", and this
- // locale is the default for many POSIX-based operating systems such as Linux.
-
- // std::locale("") construction can throw (if environmental variables LC_MESSAGES or
- // or LANG are wrong, for example), so dynamic initialization is used to ensure
- // that exceptions can be caught.
+#ifdef BOOST_WINDOWS_API
 
- return std::locale("");
+ std::locale path_locale(std::locale(), new windows_file_codecvt);
 
-# endif
- }
+ const std::codecvt<wchar_t, char, std::mbstate_t>*
+ codecvt_facet(&std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
+ (path_locale));
+
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+
+ // "All BSD system functions expect their string parameters to be in UTF-8 encoding
+ // and nothing else." See
+ // http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html
+ //
+ // "The kernel will reject any filename that is not a valid UTF-8 string, and it will
+ // even be normalized (to Unicode NFD) before stored on disk, at least when using HFS.
+ // The right way to deal with it would be to always convert the filename to UTF-8
+ // before trying to open/create a file." See
+ // http://lists.apple.com/archives/unix-porting/2007/Sep/msg00023.html
+ //
+ // "How a file name looks at the API level depends on the API. Current Carbon APIs
+ // handle file names as an array of UTF-16 characters; POSIX ones handle them as an
+ // array of UTF-8, which is why UTF-8 works well in Terminal. How it's stored on disk
+ // depends on the disk format; HFS+ uses UTF-16, but that's not important in most
+ // cases." See
+ // http://lists.apple.com/archives/applescript-users/2002/Sep/msg00319.html
+ //
+ // Many thanks to Peter Dimov for digging out the above references!
+
+ std::locale path_locale(std::locale(),
+ new boost::filesystem::detail::utf8_codecvt_facet);
+
+ const std::codecvt<wchar_t, char, std::mbstate_t>*
+ codecvt_facet(&std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
+ (path_locale));
+
+#else // Other POSIX
+
+ // ISO C calls std::locale("") "the locale-specific native environment", and this
+ // locale is the default for many POSIX-based operating systems such as Linux.
+
+ // std::locale("") construction can throw (if environmental variables LC_MESSAGES or
+ // or LANG are wrong, for example), so lazy initialization is used to ensure
+ // that exceptions occur after main() starts and so can be caught.
 
- std::locale& path_locale()
- {
- static std::locale loc(default_locale());
- return loc;
- }
+ std::locale path_locale; // initialized by path::wchar_t_codecvt_facet() below
+ const std::codecvt<wchar_t, char, std::mbstate_t>* codecvt_facet; // ditto
+
+# endif
 
 } // unnamed namespace
 
@@ -789,21 +788,25 @@
 namespace filesystem3
 {
 
- const path::codecvt_type *& path::wchar_t_codecvt_facet()
+ const path::codecvt_type*& path::wchar_t_codecvt_facet()
   {
- static const std::codecvt<wchar_t, char, std::mbstate_t> *
- facet(
- &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
- (path_locale()));
- return facet;
+# if defined(BOOST_POSIX_API) && \
+ !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+ // A local static initialized by calling path::imbue ensures that std::locale(""),
+ // which may throw, is called only if path_locale and condecvt_facet will actually
+ // be used. Thus misconfigured environmental variables will only cause an
+ // exception if a valid std::locale("") is actually needed.
+ static std::locale posix_lazy_initialization(path::imbue(std::locale("")));
+# endif
+ return codecvt_facet;
   }
 
- std::locale path::imbue(const std::locale & loc)
+ std::locale path::imbue(const std::locale& loc)
   {
- std::locale temp(path_locale());
- path_locale() = loc;
- wchar_t_codecvt_facet() =
- &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale());
+ std::locale temp(path_locale);
+ path_locale = loc;
+ codecvt_facet =
+ &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale);
     return temp;
   }
 

Modified: branches/release/libs/filesystem/v3/src/windows_file_codecvt.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/src/windows_file_codecvt.cpp (original)
+++ branches/release/libs/filesystem/v3/src/windows_file_codecvt.cpp 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -43,7 +43,7 @@
     const char* from, const char* from_end, const char*& from_next,
     wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const
   {
- UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP;
+ UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
 
     int count;
     if ((count = ::MultiByteToWideChar(codepage, MB_PRECOMPOSED, from,
@@ -63,7 +63,7 @@
     const wchar_t* from, const wchar_t* from_end, const wchar_t* & from_next,
     char* to, char* to_end, char* & to_next) const
   {
- UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP;
+ UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
 
     int count;
     if ((count = ::WideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, from,

Modified: branches/release/libs/filesystem/v3/test/msvc10/filesystem-v3.sln
==============================================================================
--- branches/release/libs/filesystem/v3/test/msvc10/filesystem-v3.sln (original)
+++ branches/release/libs/filesystem/v3/test/msvc10/filesystem-v3.sln 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -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: branches/release/libs/filesystem/v3/test/operations_test.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/test/operations_test.cpp (original)
+++ branches/release/libs/filesystem/v3/test/operations_test.cpp 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -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,46 @@
     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() & 0600) == 0600); // 0644, 0664 sometimes returned
+
+ 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 +959,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 +968,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 +1105,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 +1139,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 +1575,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 +1865,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 +1873,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 +1916,7 @@
   initial_tests();
   predicate_and_status_tests();
   exception_tests();
+ platform_specific_tests();
   create_directory_tests();
   current_directory_tests();
   space_tests();
@@ -1894,6 +1952,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 +1971,6 @@
   write_time_tests(dir);
   
   temp_directory_path_tests();
- platform_specific_tests();
   
   cout << "testing complete" << endl;
 

Modified: branches/release/libs/filesystem/v3/test/operations_unit_test.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/test/operations_unit_test.cpp (original)
+++ branches/release/libs/filesystem/v3/test/operations_unit_test.cpp 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -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: branches/release/libs/filesystem/v3/test/path_test.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/test/path_test.cpp (original)
+++ branches/release/libs/filesystem/v3/test/path_test.cpp 2012-01-15 14:22:27 EST (Sun, 15 Jan 2012)
@@ -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