Alexandre Julliard : server: Allow specifying the status code to return on file descriptors that don' t have a Unix fd.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Apr 19 05:24:20 CDT 2007


Module: wine
Branch: master
Commit: f3fbae4546597916cb4ebacc54597766f5894b08
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f3fbae4546597916cb4ebacc54597766f5894b08

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Apr 18 16:05:59 2007 +0200

server: Allow specifying the status code to return on file descriptors that don't have a Unix fd.

---

 server/fd.c   |   50 +++++++++++++++++++++-----------------------------
 server/file.h |    1 +
 2 files changed, 22 insertions(+), 29 deletions(-)

diff --git a/server/fd.c b/server/fd.c
index d24eedc..6372f43 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -170,9 +170,9 @@ struct fd
     unsigned int         options;     /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
     unsigned int         sharing;     /* file sharing mode */
     int                  unix_fd;     /* unix file descriptor */
+    unsigned int         no_fd_status;/* status to return when unix_fd is -1 */
     int                  signaled :1; /* is the fd signaled? */
     int                  fs_locks :1; /* can we use filesystem locks for this fd? */
-    int                  unmounted :1;/* has the device been unmounted? */
     int                  poll_index;  /* index of fd in poll array */
     struct async_queue  *read_q;      /* async readers of this fd */
     struct async_queue  *write_q;     /* async writers of this fd */
@@ -1368,7 +1368,7 @@ static inline void unmount_fd( struct fd *fd )
     if (fd->unix_fd != -1) close( fd->unix_fd );
 
     fd->unix_fd = -1;
-    fd->unmounted = 1;
+    fd->no_fd_status = STATUS_VOLUME_DISMOUNTED;
     fd->closed->unix_fd = -1;
     fd->closed->unlink[0] = 0;
 
@@ -1393,7 +1393,6 @@ static struct fd *alloc_fd_object(void)
     fd->unix_fd    = -1;
     fd->signaled   = 1;
     fd->fs_locks   = 1;
-    fd->unmounted  = 0;
     fd->poll_index = -1;
     fd->read_q     = NULL;
     fd->write_q    = NULL;
@@ -1425,16 +1424,22 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
     fd->unix_fd    = -1;
     fd->signaled   = 0;
     fd->fs_locks   = 0;
-    fd->unmounted  = 0;
     fd->poll_index = -1;
     fd->read_q     = NULL;
     fd->write_q    = NULL;
     fd->wait_q     = NULL;
+    fd->no_fd_status = STATUS_BAD_DEVICE_TYPE;
     list_init( &fd->inode_entry );
     list_init( &fd->locks );
     return fd;
 }
 
+/* set the status to return when the fd has no associated unix fd */
+void set_no_fd_status( struct fd *fd, unsigned int status )
+{
+    fd->no_fd_status = status;
+}
+
 /* check if the desired access is possible without violating */
 /* the sharing mode of other opens of the same file */
 static int check_sharing( struct fd *fd, unsigned int access, unsigned int sharing )
@@ -1632,11 +1637,7 @@ unsigned int get_fd_options( struct fd *fd )
 /* retrieve the unix fd for an object */
 int get_unix_fd( struct fd *fd )
 {
-    if (fd->unix_fd == -1)
-    {
-        if (fd->unmounted) set_error( STATUS_VOLUME_DISMOUNTED );
-        else set_error( STATUS_BAD_DEVICE_TYPE );
-    }
+    if (fd->unix_fd == -1) set_error( fd->no_fd_status );
     return fd->unix_fd;
 }
 
@@ -1932,19 +1933,15 @@ DECL_HANDLER(get_handle_fd)
 
     if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
     {
-        reply->type = fd->fd_ops->get_fd_type( fd );
-        if (reply->type != FD_TYPE_INVALID)
+        int unix_fd = get_unix_fd( fd );
+        if (unix_fd != -1)
         {
-            int unix_fd = get_unix_fd( fd );
-            if (unix_fd != -1)
-            {
-                send_client_fd( current->process, unix_fd, req->handle );
-                reply->removable = is_fd_removable(fd);
-                reply->options = fd->options;
-                reply->access = get_handle_access( current->process, req->handle );
-            }
+            send_client_fd( current->process, unix_fd, req->handle );
+            reply->type = fd->fd_ops->get_fd_type( fd );
+            reply->removable = is_fd_removable(fd);
+            reply->options = fd->options;
+            reply->access = get_handle_access( current->process, req->handle );
         }
-        else set_error( STATUS_OBJECT_TYPE_MISMATCH );
         release_object( fd );
     }
 }
@@ -1983,7 +1980,7 @@ DECL_HANDLER(register_async)
 
     if ((fd = get_handle_fd_obj( current->process, req->handle, access )))
     {
-        fd->fd_ops->queue_async( fd, &req->async, req->type, req->count );
+        if (get_unix_fd( fd ) != -1) fd->fd_ops->queue_async( fd, &req->async, req->type, req->count );
         release_object( fd );
     }
 }
@@ -1992,15 +1989,10 @@ DECL_HANDLER(register_async)
 DECL_HANDLER(cancel_async)
 {
     struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
+
     if (fd)
     {
-        /* Note: we don't kill the queued APC_ASYNC_IO on this thread because
-         * NtCancelIoFile() will force the pending APC to be run. Since, 
-         * Windows only guarantees that the current thread will have no async 
-         * operation on the current fd when NtCancelIoFile returns, this shall
-         * do the work.
-         */
-        fd->fd_ops->cancel_async( fd );
+        if (get_unix_fd( fd ) != -1) fd->fd_ops->cancel_async( fd );
         release_object( fd );
-    }        
+    }
 }
diff --git a/server/file.h b/server/file.h
index 262a011..09c90c3 100644
--- a/server/file.h
+++ b/server/file.h
@@ -53,6 +53,7 @@ struct fd_ops
 /* file descriptor functions */
 
 extern struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *user );
+extern void set_no_fd_status( struct fd *fd, unsigned int status );
 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,




More information about the wine-cvs mailing list