Index: subversion/bindings/swig/swigutil_py.c
===================================================================
--- subversion/bindings/swig/swigutil_py.c	(revision 4907)
+++ subversion/bindings/swig/swigutil_py.c	(working copy)
@@ -835,41 +835,98 @@
   *edit_baton = make_baton(pool, py_editor, NULL);
 }
 
-/* This is very hacky and gross.  And did I mention broken? */
+apr_os_file_t svn_swig_py_get_osfhandle(int fdesc)
+{
+#ifdef WIN32
+  return (apr_os_file_t)_get_osfhandle(fdesc);
+#else
+  return fdesc;
+#endif
+}
+
+int svn_swig_py_valid_fhandle(apr_os_file_t os_file)
+{
+#ifdef WIN32
+  return ((os_file == INVALID_HANDLE_VALUE) ? 0 : 1);
+#else
+  return ((os_file >= 0) ? 1 : 0);
+#endif
+}
+
 apr_file_t *svn_swig_py_make_file (PyObject *py_file,
                                    apr_pool_t *pool)
 {
-  apr_file_t *apr_file;
+  apr_file_t *apr_file = NULL;
+  apr_os_file_t apr_os_file;
   apr_status_t status;
-  FILE *file;
+  FILE *file = NULL;
   int fd = -1;
+  char buf[200];
 
   if (py_file == NULL || py_file == Py_None)
     return NULL;
 
   if (PyString_Check (py_file))
     {
-      fd = open (PyString_AS_STRING (py_file),
-                 O_CREAT | O_RDWR,
-                 S_IRUSR | S_IWUSR);
-    }
-  else if (PyFile_Check (py_file))
-    {
-      file = PyFile_AsFile (py_file);
-      fd = fileno (file);
+      // A string is a string, no matter the source
+      status = apr_file_open(&apr_file,
+                             PyString_AS_STRING (py_file), 
+                             (APR_READ | APR_WRITE | APR_CREATE),
+                             (APR_UREAD | APR_UWRITE),
+                             pool);
+      
+      if(!APR_STATUS_IS_SUCCESS(status))
+        {
+          apr_strerror(status, buf, 200);
+          PyErr_Format(PyExc_IOError,"apr_file_open returned error (%s).", buf);
+          return NULL;
+        }
     }
-  else if (PyInt_Check (py_file))
+  else
     {
-      fd = PyInt_AsLong (py_file);
-    }
+      if (PyFile_Check (py_file))
+        {
+          // A FILE* is a FILE*, no matter the source.
+          file = PyFile_AsFile (py_file);
+          apr_os_file = svn_swig_py_get_osfhandle( fileno (file) );
+        }
+      else if (PyInt_Check (py_file))
+        {
+          fd = PyInt_AsLong (py_file);
+#ifdef WIN32
+          // For windows, we assume that if it's an int, it's actually
+          // a HANDLE.  Is that so wrong?  Can't I assume anything?
+          apr_os_file = (apr_os_file_t)fd;
+#else
+          // So far, all others should be an int, therefore just a direct assignment.
+          apr_os_file = fd;
+#endif // WIN32
+        }
+      else
+        {
+          PyErr_SetString(PyExc_TypeError, "argument must be a file descriptor, handle, or string containing the file name.");
+          return NULL;
+        }
 
-  if (fd >= 0) 
-    {  
-      status = apr_os_file_put (&apr_file, &fd, O_CREAT | O_WRONLY, pool);
+      if (svn_swig_py_valid_fhandle(apr_os_file)) 
+        {
+          status = apr_os_file_put (&apr_file, &apr_os_file, O_CREAT | O_WRONLY, pool);
+          if(!APR_STATUS_IS_SUCCESS(status))
+            {
+              char buf[200];
+              apr_strerror(status, buf, 200);
+              PyErr_Format(PyExc_IOError,"apr_os_file_put returned an error: %s", buf);
+              return NULL;
+            }
+        }
+      else
+        {
+          PyErr_Format(PyExc_ValueError,
+            "invalid file descriptor (%i)", apr_os_file);
+          return NULL;
+        }
     }
-
-  /* FIXME: We shouldn't just silently fail. */
-
+  
   return apr_file;
 }
 


