Alexandre Julliard : server: Allow opening a directory with write access (based on a patch

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jan 25 09:04:29 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 471782ae29ff1191661fb4a5bdb92ed4d77d757f
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=471782ae29ff1191661fb4a5bdb92ed4d77d757f

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jan 25 15:06:48 2006 +0100

server: Allow opening a directory with write access (based on a patch
by Mike McCormack).

---

 server/fd.c   |   23 ++++++++++++++++++++---
 server/file.c |   13 +------------
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/server/fd.c b/server/fd.c
index ba182f4..a142acd 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1327,6 +1327,7 @@ struct fd *open_fd( const char *name, in
     struct closed_fd *closed_fd;
     struct fd *fd;
     const char *unlink_name = "";
+    int rw_mode;
 
     if (!(fd = alloc_fd_object())) return NULL;
 
@@ -1336,6 +1337,7 @@ struct fd *open_fd( const char *name, in
         release_object( fd );
         return NULL;
     }
+
     /* create the directory if needed */
     if ((options & FILE_DIRECTORY_FILE) && (flags & O_CREAT))
     {
@@ -1349,11 +1351,26 @@ struct fd *open_fd( const char *name, in
         }
         flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
     }
-    if ((fd->unix_fd = open( name, flags & ~O_TRUNC, *mode )) == -1)
+
+    if ((access & FILE_UNIX_WRITE_ACCESS) && !(options & FILE_DIRECTORY_FILE))
     {
-        file_set_error();
-        goto error;
+        if (access & FILE_UNIX_READ_ACCESS) rw_mode = O_RDWR;
+        else rw_mode = O_WRONLY;
     }
+    else rw_mode = O_RDONLY;
+
+    if ((fd->unix_fd = open( name, rw_mode | (flags & ~O_TRUNC), *mode )) == -1)
+    {
+        /* if we tried to open a directory for write access, retry read-only */
+        if (errno != EISDIR ||
+            !(access & FILE_UNIX_WRITE_ACCESS) ||
+            (fd->unix_fd = open( name, O_RDONLY | (flags & ~O_TRUNC), *mode )) == -1)
+        {
+            file_set_error();
+            goto error;
+        }
+    }
+
     closed_fd->unix_fd = fd->unix_fd;
     closed_fd->unlink[0] = 0;
     fstat( fd->unix_fd, &st );
diff --git a/server/file.c b/server/file.c
index bc8f63d..f488c55 100644
--- a/server/file.c
+++ b/server/file.c
@@ -141,7 +141,7 @@ static struct object *create_file( const
 {
     struct object *obj = NULL;
     struct fd *fd;
-    int flags, rw_mode;
+    int flags;
     char *name;
     mode_t mode;
 
@@ -168,17 +168,6 @@ static struct object *create_file( const
 
     access = generic_file_map_access( access );
 
-    rw_mode = 0;
-    if (access & FILE_UNIX_READ_ACCESS) rw_mode |= FILE_READ_DATA;
-    if (access & FILE_UNIX_WRITE_ACCESS) rw_mode |= FILE_WRITE_DATA;
-    switch(rw_mode)
-    {
-    case 0: break;
-    case FILE_READ_DATA:  flags |= O_RDONLY; break;
-    case FILE_WRITE_DATA: flags |= O_WRONLY; break;
-    case FILE_READ_DATA|FILE_WRITE_DATA: flags |= O_RDWR; break;
-    }
-
     /* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
     fd = open_fd( name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
     if (!fd) goto done;




More information about the wine-cvs mailing list