Module: wine Branch: refs/heads/master Commit: 471782ae29ff1191661fb4a5bdb92ed4d77d757f URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=471782ae29ff1191661fb4a5...
Author: Alexandre Julliard julliard@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;