$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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 @@
      is_regular_file<br>
      is_symlink<br>
      last_write_time<br>
+     read_symlink<br>
      remove<br>
      remove_all<br>
      rename<br>
@@ -271,11 +272,11 @@
       bool         create_directory(const path& p);
       bool         create_directory(const path& p, system::error_code& ec);
 
-      void         create_hard_link(const path& p, const path& new_link);
-      void         create_hard_link(const path& p, const path& new_link, system::error_code& ec);
+      void         create_hard_link(const path& to, const path& from);
+      void         create_hard_link(const path& to, const path& from, system::error_code& ec);
 
-<span style="background-color: #FFFFFF">      void         create_symlink(const path& p, const path& new_link);
-      void         create_symlink(const path& p, const path& new_link</span>, system::error_code& ec<span style="background-color: #FFFFFF">);
+<span style="background-color: #FFFFFF">      void         create_symlink(const path& to, const path& from);
+      void         create_symlink(const path& to, const path& from</span>, system::error_code& ec<span style="background-color: #FFFFFF">);
 
 </span>      path         current_path();
       path         current_path(system::error_code& ec);
@@ -319,6 +320,9 @@
       void         last_write_time(const path& p, const std::time_t new_time);
       void         last_write_time(const path& p, const std::time_t new_time, system::error_code& ec);
 
+      path         read_symlink(const path& p);
+      path         read_symlink(const path& p, system::error_code& ec);
+
       bool         remove(const path& p);
       bool         remove(const path& p, system::error_code& 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& p, const path& new_link);
-void <a name="create_hard_link">create_hard_link</a>(const path& p, const path& new_link, system::error_code& ec);</span></pre>
+<pre><span style="background-color: #FFFFFF">void <a name="create_hard_link">create_hard_link</a>(const path& to, const path& from);
+void <a name="create_hard_link">create_hard_link</a>(const path& to, const path& from, system::error_code& 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"> </span><code><span style="background-color: #FFFFFF">exists(p) && 
-    exists(new_link) && equivalent(p, 
-    new_link)</span></code></li>
+    <li><span style="background-color: #FFFFFF"> </span><code><span style="background-color: #FFFFFF">exists(to) && 
+    exists(from) && 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& p, const path& new_link);
-void <a name="create_symlink">create_symlink</a>(const path& p, const path& new_link, system::error_code& ec);</span></pre>
+<pre><span style="background-color: #FFFFFF">void <a name="create_symlink">create_symlink</a>(const path& to, const path& from);
+void <a name="create_symlink">create_symlink</a>(const path& to, const path& from, system::error_code& 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& p);
+path read_symlink(const path& p, system::error_code& ec);</pre>
+<blockquote>
+  <p dir="ltr"><i>Returns:</i>  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& p);
 bool <a name="remove">remove</a>(const path& p, system::error_code& 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);
     }