You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by wr...@apache.org on 2007/10/14 03:12:39 UTC

svn commit: r584465 - in /apr/apr/trunk: file_io/win32/open.c include/apr.hw include/apr_file_io.h

Author: wrowe
Date: Sat Oct 13 18:12:38 2007
New Revision: 584465

URL: http://svn.apache.org/viewvc?rev=584465&view=rev
Log:
With the tests committed, introduce Win32 APR_FOPEN_SPARSE handling
and document the new flag.

Modified:
    apr/apr/trunk/file_io/win32/open.c
    apr/apr/trunk/include/apr.hw
    apr/apr/trunk/include/apr_file_io.h

Modified: apr/apr/trunk/file_io/win32/open.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/win32/open.c?rev=584465&r1=584464&r2=584465&view=diff
==============================================================================
--- apr/apr/trunk/file_io/win32/open.c (original)
+++ apr/apr/trunk/file_io/win32/open.c Sat Oct 13 18:12:38 2007
@@ -32,6 +32,7 @@
 #include "apr_arch_misc.h"
 #include "apr_arch_inherit.h"
 #include <io.h>
+#include <WinIoCtl.h>
 
 #if APR_HAS_UNICODE_FS
 apr_status_t utf8_to_unicode_path(apr_wchar_t* retstr, apr_size_t retlen, 
@@ -220,6 +221,55 @@
 #endif
 }
 
+static apr_status_t make_sparse_file(apr_file_t *file)
+{
+    BY_HANDLE_FILE_INFORMATION info;
+    apr_status_t rv;
+    DWORD bytesread = 0;
+    DWORD res;
+
+    /* test */
+
+    if (GetFileInformationByHandle(file->filehand, &info)
+            && (info.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE))
+        return APR_SUCCESS;
+
+    if (file->pOverlapped) {
+        file->pOverlapped->Offset     = 0;
+        file->pOverlapped->OffsetHigh = 0;
+    }
+
+    if (DeviceIoControl(file->filehand, FSCTL_SET_SPARSE, NULL, 0, NULL, 0,
+                        &bytesread, file->pOverlapped)) {
+        rv = APR_SUCCESS;
+    }
+    else 
+    {
+        rv = apr_get_os_error();
+
+        if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING))
+        {
+            do {
+                res = WaitForSingleObject(file->pOverlapped->hEvent, 
+                                          (file->timeout > 0)
+                                            ? (DWORD)(file->timeout/1000)
+                                            : ((file->timeout == -1) 
+                                                 ? INFINITE : 0));
+            } while (res == WAIT_ABANDONED);
+
+            if (res != WAIT_OBJECT_0) {
+                CancelIo(file->filehand);
+            }
+
+            if (GetOverlappedResult(file->filehand, file->pOverlapped, 
+                                    &bytesread, TRUE))
+                rv = APR_SUCCESS;
+            else
+                rv = apr_get_os_error();
+        }
+    }
+    return rv;
+}
 
 apr_status_t file_cleanup(void *thefile)
 {
@@ -371,12 +421,8 @@
     ELSE_WIN_OS_IS_ANSI {
         handle = CreateFileA(fname, oflags, sharemode,
                              NULL, createflags, attributes, 0);
-        if (flag & APR_SENDFILE_ENABLED) {    
-            /* This feature is not supported on this platform.
-             */
-            flag &= ~APR_SENDFILE_ENABLED;
-        }
-
+        /* These features are not supported on this platform. */
+        flag &= ~(APR_SENDFILE_ENABLED | APR_FOPEN_SPARSE);
     }
 #endif
     if (handle == INVALID_HANDLE_VALUE) {
@@ -410,6 +456,15 @@
             }
             return rv;
         }
+    }
+
+    if ((*new)->flags & APR_FOPEN_SPARSE) {
+        if ((rv = make_sparse_file(*new)) != APR_SUCCESS)
+            /* The great mystery; do we close the file and return an error?
+             * Do we add a new APR_INCOMPLETE style error saying opened, but
+             * NOTSPARSE?  For now let's simply mark the file as not-sparse.
+             */
+            (*new)->flags &= ~APR_FOPEN_SPARSE;
     }
 
     /* Create a pollset with room for one descriptor. */

Modified: apr/apr/trunk/include/apr.hw
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr.hw?rev=584465&r1=584464&r2=584465&view=diff
==============================================================================
--- apr/apr/trunk/include/apr.hw (original)
+++ apr/apr/trunk/include/apr.hw Sat Oct 13 18:12:38 2007
@@ -76,9 +76,9 @@
 #endif
 #ifndef _WIN32_WINNT
 
-/* Restrict the server to a subset of Windows NT 4.0 header files by default
+/* Restrict the server to a subset of Windows 2000 header files by default
  */
-#define _WIN32_WINNT 0x0400
+#define _WIN32_WINNT 0x0500
 #endif
 #ifndef NOUSER
 #define NOUSER

Modified: apr/apr/trunk/include/apr_file_io.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_file_io.h?rev=584465&r1=584464&r2=584465&view=diff
==============================================================================
--- apr/apr/trunk/include/apr_file_io.h (original)
+++ apr/apr/trunk/include/apr_file_io.h Sat Oct 13 18:12:38 2007
@@ -75,8 +75,12 @@
                                              file should support
                                              apr_socket_sendfile operation */
 #define APR_FOPEN_LARGEFILE   0x04000 /**< Platform dependent flag to enable
-                                         large file support; WARNING see
-                                         below. */
+                                       * large file support, see WARNING below
+                                       */
+#define APR_FOPEN_SPARSE      0x08000 /**< Platform dependent flag to enable
+                                       * sparse file support, see WARNING below
+                                       */
+
 /* backcompat */
 #define APR_READ             APR_FOPEN_READ       /**< @deprecated @see APR_FOPEN_READ */
 #define APR_WRITE            APR_FOPEN_WRITE      /**< @deprecated @see APR_FOPEN_WRITE */   
@@ -93,7 +97,7 @@
 #define APR_SENDFILE_ENABLED APR_FOPEN_SENDFILE_ENABLED /**< @deprecated @see APR_FOPEN_SENDFILE_ENABLED */   
 #define APR_LARGEFILE        APR_FOPEN_LARGEFILE  /**< @deprecated @see APR_FOPEN_LARGEFILE */   
 
-/** @warning The APR_FOPEN_LARGEFILE flag only has effect on some
+/** @warning APR_FOPEN_LARGEFILE flag only has effect on some
  * platforms where sizeof(apr_off_t) == 4.  Where implemented, it
  * allows opening and writing to a file which exceeds the size which
  * can be represented by apr_off_t (2 gigabytes).  When a file's size
@@ -102,7 +106,18 @@
  * filename.  apr_dir_read() will fail with APR_INCOMPLETE on a
  * directory entry for a large file depending on the particular
  * APR_FINFO_* flags.  Generally, it is not recommended to use this
- * flag. */
+ * flag.
+ *
+ * @warning APR_FOPEN_SPARSE may, depending on platform, convert a
+ * normal file to a sparse file.  Some applications may be unable
+ * to decipher a sparse file, so it's critical that the sparse file
+ * flag should only be used for files accessed only by APR or other
+ * applications known to be able to decipher them.  APR does not
+ * guarentee that it will compress the file into sparse segments
+ * if it was previously created and written without the sparse flag.
+ * On platforms which do not understand, or on file systems which
+ * cannot handle sparse files, the flag is ignored by apr_file_open().
+ */
 
 /** @} */