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