Mike McCormack : server: Modify open_fd to create an fd without a user.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jan 24 06:45:37 CST 2006


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

Author: Mike McCormack <mike at codeweavers.com>
Date:   Tue Jan 24 13:30:55 2006 +0100

server: Modify open_fd to create an fd without a user.
Create a set_fd_user function.
Update create_file() to use the above functions.

---

 server/fd.c   |   36 ++++++++++++++++++---------------
 server/file.c |   63 ++++++++++++++++++++++++++++++++-------------------------
 server/file.h |    6 +++--
 3 files changed, 58 insertions(+), 47 deletions(-)

diff --git a/server/fd.c b/server/fd.c
index 37e0ef2..ba182f4 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1224,14 +1224,14 @@ static inline void unmount_fd( struct fd
 }
 
 /* allocate an fd object, without setting the unix fd yet */
-struct fd *alloc_fd( const struct fd_ops *fd_user_ops, struct object *user )
+static struct fd *alloc_fd_object(void)
 {
     struct fd *fd = alloc_object( &fd_ops );
 
     if (!fd) return NULL;
 
-    fd->fd_ops     = fd_user_ops;
-    fd->user       = user;
+    fd->fd_ops     = NULL;
+    fd->user       = NULL;
     fd->inode      = NULL;
     fd->closed     = NULL;
     fd->access     = 0;
@@ -1311,17 +1311,24 @@ static int check_sharing( struct fd *fd,
     return 1;
 }
 
-/* open() wrapper using a struct fd */
-/* the fd must have been created with alloc_fd */
-/* on error the fd object is released */
-struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
-                    unsigned int access, unsigned int sharing, unsigned int options )
+/* sets the user of an fd that previously had no user */
+void set_fd_user( struct fd *fd, const struct fd_ops *user_ops, struct object *user )
+{
+    assert( fd->fd_ops == NULL );
+    fd->fd_ops = user_ops;
+    fd->user   = user;
+}
+
+/* open() wrapper that returns a struct fd with no fd user set */
+struct fd *open_fd( const char *name, int flags, mode_t *mode, unsigned int access,
+                    unsigned int sharing, unsigned int options )
 {
     struct stat st;
     struct closed_fd *closed_fd;
+    struct fd *fd;
     const char *unlink_name = "";
 
-    assert( fd->unix_fd == -1 );
+    if (!(fd = alloc_fd_object())) return NULL;
 
     if (options & FILE_DELETE_ON_CLOSE) unlink_name = name;
     if (!(closed_fd = mem_alloc( sizeof(*closed_fd) + strlen(unlink_name) )))
@@ -1337,9 +1344,7 @@ struct fd *open_fd( struct fd *fd, const
             if (errno != EEXIST || (flags & O_EXCL))
             {
                 file_set_error();
-                release_object( fd );
-                free( closed_fd );
-                return NULL;
+                goto error;
             }
         }
         flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
@@ -1347,9 +1352,7 @@ struct fd *open_fd( struct fd *fd, const
     if ((fd->unix_fd = open( name, flags & ~O_TRUNC, *mode )) == -1)
     {
         file_set_error();
-        release_object( fd );
-        free( closed_fd );
-        return NULL;
+        goto error;
     }
     closed_fd->unix_fd = fd->unix_fd;
     closed_fd->unlink[0] = 0;
@@ -1420,10 +1423,11 @@ error:
 /* if the function fails the unix fd is closed */
 struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops, int unix_fd, struct object *user )
 {
-    struct fd *fd = alloc_fd( fd_user_ops, user );
+    struct fd *fd = alloc_fd_object();
 
     if (fd)
     {
+        set_fd_user( fd, fd_user_ops, user );
         fd->unix_fd = unix_fd;
         return fd;
     }
diff --git a/server/file.c b/server/file.c
index 84215c5..bc8f63d 100644
--- a/server/file.c
+++ b/server/file.c
@@ -61,6 +61,8 @@ struct file
     unsigned int        options;    /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
 };
 
+static unsigned int generic_file_map_access( unsigned int access );
+
 static void file_dump( struct object *obj, int verbose );
 static struct fd *file_get_fd( struct object *obj );
 static unsigned int file_map_access( struct object *obj, unsigned int access );
@@ -120,12 +122,25 @@ static struct file *create_file_for_fd( 
     return file;
 }
 
+static struct object *create_file_obj( struct fd *fd, unsigned int access, unsigned int options )
+{
+    struct file *file = alloc_object( &file_ops );
+
+    if (!file) return NULL;
+    file->access  = access;
+    file->options = options;
+    file->fd      = fd;
+    grab_object( fd );
+    set_fd_user( fd, &file_fd_ops, &file->obj );
+    return &file->obj;
+}
 
 static struct object *create_file( const char *nameptr, size_t len, unsigned int access,
                                    unsigned int sharing, int create, unsigned int options,
                                    unsigned int attrs )
 {
-    struct file *file;
+    struct object *obj = NULL;
+    struct fd *fd;
     int flags, rw_mode;
     char *name;
     mode_t mode;
@@ -142,7 +157,7 @@ static struct object *create_file( const
     case FILE_OPEN:         flags = 0; break;
     case FILE_OPEN_IF:      flags = O_CREAT; break;
     case FILE_OVERWRITE:    flags = O_TRUNC; break;
-    default:                set_error( STATUS_INVALID_PARAMETER ); goto error;
+    default:                set_error( STATUS_INVALID_PARAMETER ); goto done;
     }
 
     mode = (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666;
@@ -151,14 +166,11 @@ static struct object *create_file( const
         (!strcasecmp( name + len - 4, ".exe" ) || !strcasecmp( name + len - 4, ".com" )))
         mode |= 0111;
 
-    if (!(file = alloc_object( &file_ops ))) goto error;
-
-    file->access     = file_map_access( &file->obj, access );
-    file->options    = options;
+    access = generic_file_map_access( access );
 
     rw_mode = 0;
-    if (file->access & FILE_UNIX_READ_ACCESS) rw_mode |= FILE_READ_DATA;
-    if (file->access & FILE_UNIX_WRITE_ACCESS) rw_mode |= FILE_WRITE_DATA;
+    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;
@@ -168,29 +180,19 @@ static struct object *create_file( const
     }
 
     /* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
-    if (!(file->fd = alloc_fd( &file_fd_ops, &file->obj )) ||
-        !(file->fd = open_fd( file->fd, name, flags | O_NONBLOCK | O_LARGEFILE,
-                              &mode, file->access, sharing, options )))
-    {
-        free( name );
-        release_object( file );
-        return NULL;
-    }
-    free( name );
+    fd = open_fd( name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
+    if (!fd) goto done;
 
-    /* check for serial port */
-    if (S_ISCHR(mode) && is_serial_fd( file->fd ))
-    {
-        struct object *obj = create_serial( file->fd, file->options );
-        release_object( file );
-        return obj;
-    }
+    if (S_ISCHR(mode) && is_serial_fd( fd ))
+        obj = create_serial( fd, options );
+    else
+        obj = create_file_obj( fd, access, options );
 
-    return &file->obj;
+    release_object( fd );
 
- error:
+done:
     free( name );
-    return NULL;
+    return obj;
 }
 
 /* check if two file objects point to the same file */
@@ -260,7 +262,7 @@ static struct fd *file_get_fd( struct ob
     return (struct fd *)grab_object( file->fd );
 }
 
-static unsigned int file_map_access( struct object *obj, unsigned int access )
+static unsigned int generic_file_map_access( unsigned int access )
 {
     if (access & GENERIC_READ)    access |= FILE_GENERIC_READ;
     if (access & GENERIC_WRITE)   access |= FILE_GENERIC_WRITE;
@@ -269,6 +271,11 @@ static unsigned int file_map_access( str
     return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
 }
 
+static unsigned int file_map_access( struct object *obj, unsigned int access )
+{
+    return generic_file_map_access( access );
+}
+
 static void file_destroy( struct object *obj )
 {
     struct file *file = (struct file *)obj;
diff --git a/server/file.h b/server/file.h
index a4e8c7a..5b139af 100644
--- a/server/file.h
+++ b/server/file.h
@@ -46,13 +46,13 @@ struct fd_ops
 
 /* file descriptor functions */
 
-extern struct fd *alloc_fd( const struct fd_ops *fd_user_ops, struct object *user );
 extern struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *user );
-extern struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
-                           unsigned int access, unsigned int sharing, unsigned int options );
+extern struct fd *open_fd( const char *name, int flags, mode_t *mode, unsigned int access,
+                           unsigned int sharing, unsigned int options );
 extern struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops,
                                        int unix_fd, struct object *user );
 extern void *get_fd_user( struct fd *fd );
+extern void set_fd_user( struct fd *fd, const struct fd_ops *ops, struct object *user );
 extern int get_unix_fd( struct fd *fd );
 extern int is_same_file_fd( struct fd *fd1, struct fd *fd2 );
 extern void fd_poll_event( struct fd *fd, int event );




More information about the wine-cvs mailing list