Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58308 - in sandbox/filesystem-v3/libs/filesystem: build doc src test
From: bdawes_at_[hidden]
Date: 2009-12-11 21:18:13


Author: bemandawes
Date: 2009-12-11 21:18:11 EST (Fri, 11 Dec 2009)
New Revision: 58308
URL: http://svn.boost.org/trac/boost/changeset/58308

Log:
Add Windows support for read_symlink
Text files modified:
   sandbox/filesystem-v3/libs/filesystem/build/Jamfile.v2 | 2
   sandbox/filesystem-v3/libs/filesystem/doc/reference.html | 50 ++++++++++++++-------
   sandbox/filesystem-v3/libs/filesystem/src/operations.cpp | 90 +++++++++++++++++++++++++++++++++++----
   sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp | 5 --
   sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp | 12 +++++
   5 files changed, 126 insertions(+), 33 deletions(-)

Modified: sandbox/filesystem-v3/libs/filesystem/build/Jamfile.v2
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/build/Jamfile.v2 (original)
+++ sandbox/filesystem-v3/libs/filesystem/build/Jamfile.v2 2009-12-11 21:18:11 EST (Fri, 11 Dec 2009)
@@ -15,7 +15,7 @@
     ;
 
 SOURCES =
- operations path path_traits portability utf8_codecvt_facet windows_file_codecvt ;
+ operations path path_traits portability utf8_codecvt_facet windows_file_codecvt codecvt_error_category ;
 
 lib boost_filesystem
     :

Modified: sandbox/filesystem-v3/libs/filesystem/doc/reference.html
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/doc/reference.html (original)
+++ sandbox/filesystem-v3/libs/filesystem/doc/reference.html 2009-12-11 21:18:11 EST (Fri, 11 Dec 2009)
@@ -100,6 +100,7 @@
 &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; read_symlink<br>
 &nbsp;&nbsp;&nbsp;&nbsp remove<br>
 &nbsp;&nbsp;&nbsp;&nbsp remove_all<br>
 &nbsp;&nbsp;&nbsp;&nbsp rename<br>
@@ -271,11 +272,11 @@
       bool create_directory(const path&amp; p);
       bool create_directory(const path&amp; p, system::error_code&amp; ec);
 
- void create_hard_link(const path&amp; p, const path&amp; new_link);
- void create_hard_link(const path&amp; p, const path&amp; new_link, system::error_code&amp; ec);
+ void create_hard_link(const path&amp; to, const path&amp; from);
+ void create_hard_link(const path&amp; to, const path&amp; from, system::error_code&amp; ec);
 
-<span style="background-color: #FFFFFF"> void create_symlink(const path&amp; p, const path&amp; new_link);
- void create_symlink(const path&amp; p, const path&amp; new_link</span>, system::error_code&amp; ec<span style="background-color: #FFFFFF">);
+<span style="background-color: #FFFFFF"> void create_symlink(const path&amp; to, const path&amp; from);
+ void create_symlink(const path&amp; to, const path&amp; from</span>, system::error_code&amp; ec<span style="background-color: #FFFFFF">);
 
 </span> path current_path();
       path current_path(system::error_code&amp; ec);
@@ -319,6 +320,9 @@
       void last_write_time(const path&amp; p, const std::time_t new_time);
       void last_write_time(const path&amp; p, const std::time_t new_time, system::error_code&amp; ec);
 
+ path read_symlink(const path&amp; p);
+ path read_symlink(const path&amp; p, system::error_code&amp; ec);
+
       bool remove(const path&amp; p);
       bool remove(const path&amp; p, system::error_code&amp; ec);
 
@@ -2006,21 +2010,21 @@
   <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
   Error reporting</a>.</p>
 </blockquote>
-<pre><span style="background-color: #FFFFFF">void <a name="create_hard_link">create_hard_link</a>(const path&amp; p, const path&amp; new_link);
-void <a name="create_hard_link">create_hard_link</a>(const path&amp; p, const path&amp; new_link, system::error_code&amp; ec);</span></pre>
+<pre><span style="background-color: #FFFFFF">void <a name="create_hard_link">create_hard_link</a>(const path&amp; to, const path&amp; from);
+void <a name="create_hard_link">create_hard_link</a>(const path&amp; to, const path&amp; from, system::error_code&amp; ec);</span></pre>
 <blockquote>
   <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF"> Establishes the postcondition, as if by
   </span> <i><span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF">
   </span> <code>
   <a href="http://www.opengroup.org/onlinepubs/000095399/functions/link.html">
   <span style="background-color: #FFFFFF">link()</span></a></code><span style="background-color: #FFFFFF">.</span></p>
- <p><i><span style="background-color: #FFFFFF">Postcondition:</span></i></p>
+ <p><i><span style="background-color: #FFFFFF">Postconditions:</span></i></p>
   <ul>
- <li><span style="background-color: #FFFFFF">&nbsp;</span><code><span style="background-color: #FFFFFF">exists(p) &amp;&amp;
- exists(new_link) &amp;&amp; equivalent(p,
- new_link)</span></code></li>
+ <li><span style="background-color: #FFFFFF">&nbsp;</span><code><span style="background-color: #FFFFFF">exists(to) &amp;&amp;
+ exists(from) &amp;&amp; equivalent(to,
+ from)</span></code></li>
     <li><span style="background-color: #FFFFFF">The contents of the file or directory
- </span> <code><span style="background-color: #FFFFFF">p</span></code><span style="background-color: #FFFFFF"> resolves to are unchanged.</span></li>
+ <code>to</code> resolves to are unchanged.</span></li>
   </ul>
   <p><i>Throws:</i> As specified in
   <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
@@ -2033,8 +2037,8 @@
   number of links per file. Thus hard links should only be used if these
   situations are not concerns, or if workarounds are provided. </span> <i><span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
   </blockquote>
-<pre><span style="background-color: #FFFFFF">void <a name="create_symlink">create_symlink</a>(const path&amp; p, const path&amp; new_link);
-void <a name="create_symlink">create_symlink</a>(const path&amp; p, const path&amp; new_link, system::error_code&amp; ec);</span></pre>
+<pre><span style="background-color: #FFFFFF">void <a name="create_symlink">create_symlink</a>(const path&amp; to, const path&amp; from);
+void <a name="create_symlink">create_symlink</a>(const path&amp; to, const path&amp; from, system::error_code&amp; ec);</span></pre>
 <blockquote style="font-size: 10pt">
   <p style="font-size: 10pt"><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
   Establishes the postcondition, as if by </span><i>
@@ -2043,14 +2047,15 @@
   <a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">
   symlink()</a></span></code><span style="background-color: #FFFFFF">.</span></p>
   <p style="font-size: 10pt"><span style="background-color: #FFFFFF"><i>
- Postconditions:</i> <code>new_link</code> resolves to a symbolic link file that
- contains an unspecified representation of <code>p</code>.</span></p>
+ Postconditions:</i> <code>from</code> resolves to a symbolic link file that
+ contains an unspecified representation of <code>to</code>.</span></p>
   <p style="font-size: 10pt"><i>Throws:</i> As specified in
   <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
   Error reporting</a>.</p>
   <p><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
   Some <b>operating systems</b> do not support symbolic links at all or support
- them only for regular files.
+ them only for regular files. Windows prior to Vista, for example, did not
+ support symbolic links.
   Some <b>file systems</b> do not
   support
   symbolic links regardless of the operating system - the FAT system used on floppy discs, memory cards and flash
@@ -2282,6 +2287,17 @@
   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>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>
+ <p dir="ltr"><i>Returns:</i>&nbsp; If <code>p</code> resolves to a symbolic
+ link, a <code>path</code> object containing the contents of that symbolic
+ link. Otherwise an empty <code>path</code> object.</p>
+ <p><i>Throws:</i> As specified in
+ <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
+ Error reporting</a>. [<i>Note:</i> It is an error if <code>p</code> does not
+ resolve to a symbolic link. <i>-- end note</i>]</p>
+</blockquote>
 <pre>bool <a name="remove">remove</a>(const path&amp; p);
 bool <a name="remove">remove</a>(const path&amp; p, system::error_code&amp; ec);</pre>
 <blockquote>
@@ -3294,7 +3310,7 @@
 <p>Distributed under the Boost Software License, Version 1.0. See
 <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
 <p>Revised
-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->06 December 2009<!--webbot bot="Timestamp" endspan i-checksum="39744" --></p>
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->11 December 2009<!--webbot bot="Timestamp" endspan i-checksum="39735" --></p>
 
 </body>
 

Modified: sandbox/filesystem-v3/libs/filesystem/src/operations.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/src/operations.cpp (original)
+++ sandbox/filesystem-v3/libs/filesystem/src/operations.cpp 2009-12-11 21:18:11 EST (Fri, 11 Dec 2009)
@@ -70,6 +70,50 @@
 # include <sys/utime.h>
 # endif
 
+// REPARSE_DATA_BUFFER related definitions are found in ntifs.h, which is part of the
+// Windows Device Driver Kit. Since that's inconvient, the needed definitions are
+// provided here.
+// See http://msdn.microsoft.com/en-us/library/ms791514.aspx
+
+#define SYMLINK_FLAG_RELATIVE 1
+
+typedef struct _REPARSE_DATA_BUFFER {
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union {
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ /* Example of distinction between substitute and print names:
+ mklink /d ldrive c:\
+ SubstituteName: c:\\??\
+ PrintName: c:\
+ */
+ } SymbolicLinkReparseBuffer;
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+
+#define REPARSE_DATA_BUFFER_HEADER_SIZE \
+ FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
+
+#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
+
+
 # else // BOOST_POSIX_API
 # include <sys/types.h>
 # if !defined(__APPLE__) && !defined(__OpenBSD__)
@@ -1069,17 +1113,43 @@
   BOOST_FILESYSTEM_DECL
   path read_symlink(const path& p, system::error_code* ec)
   {
-# ifdef BOOST_WINDOWS_API
+ path symlink_path;
 
- if (ec == 0)
- throw_exception(filesystem_error("boost::filesystem::read_symlink",
- p, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category)));
- else ec->assign(BOOST_ERROR_NOT_SUPPORTED, system_category);
- return path();
+# if defined(BOOST_WINDOWS_API)
+
+# if _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008
+ error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category), p, ec,
+ "boost::filesystem::read_symlink");
+# else // Vista and Server 2008 SDK, or later
 
-# else
+ union info_t
+ {
+ char buf[REPARSE_DATA_BUFFER_HEADER_SIZE+MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ REPARSE_DATA_BUFFER rdb;
+ } info;
+
+ handle_wrapper h(
+ create_file_handle(p.c_str(),GENERIC_READ, 0, 0, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0));
+
+ if (error(h.handle == INVALID_HANDLE_VALUE, p, ec, "boost::filesystem::read_symlink"))
+ return symlink_path;
+
+ DWORD sz;
+
+ if (!error(::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT,
+ 0, 0, info.buf, sizeof(info), &sz, 0) == 0, p, ec,
+ "boost::filesystem::read_symlink" ))
+ symlink_path.assign(
+ static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer)
+ + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t),
+ static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer)
+ + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t)
+ + info.rdb.SymbolicLinkReparseBuffer.PrintNameLength/sizeof(wchar_t));
+# endif
+
+# else
 
- path symlink_path;
     for (std::size_t path_max = 64;; path_max *= 2)// loop 'til buffer large enough
     {
       boost::scoped_array<char> buf(new char[path_max]);
@@ -1102,9 +1172,9 @@
         }
       }
     }
- return symlink_path;
 
-# endif
+# endif
+ return symlink_path;
   }
   
   BOOST_FILESYSTEM_DECL

Modified: sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp (original)
+++ sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp 2009-12-11 21:18:11 EST (Fri, 11 Dec 2009)
@@ -505,12 +505,7 @@
       BOOST_TEST(fs::is_symlink(from_ph));
       BOOST_TEST(fs::exists(file_ph));
       BOOST_TEST(fs::equivalent(from_ph, file_ph));
-
- if (platform == "POSIX")
- {
- //std::cout << fs::read_symlink(from_ph).string() << ", " << file_ph.string() << "\n";
                   BOOST_TEST(fs::read_symlink(from_ph) == file_ph);
- }
 
       fs::file_status stat = fs::symlink_status(from_ph);
       BOOST_TEST(fs::exists(stat));

Modified: sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp (original)
+++ sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp 2009-12-11 21:18:11 EST (Fri, 11 Dec 2009)
@@ -646,6 +646,10 @@
         exception_thrown = true;
         BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::partial, fs::codecvt_error_category()));
       }
+ catch (...)
+ {
+ std::cout << "exception thrown, but of an unexpected type" << std::endl;
+ }
       BOOST_TEST(exception_thrown);
     }
 
@@ -657,6 +661,10 @@
         exception_thrown = true;
         BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::error, fs::codecvt_error_category()));
       }
+ catch (...)
+ {
+ std::cout << "exception thrown, but of an unexpected type" << std::endl;
+ }
       BOOST_TEST(exception_thrown);
     }
 
@@ -668,6 +676,10 @@
         exception_thrown = true;
         BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::noconv, fs::codecvt_error_category()));
       }
+ catch (...)
+ {
+ std::cout << "exception thrown, but of an unexpected type" << std::endl;
+ }
       BOOST_TEST(exception_thrown);
     }
 


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