Commit 63411dbd authored by Alexandre Julliard's avatar Alexandre Julliard

Avoid dup'ing file descriptors when not necessary.

Do not send fd to the client if ops->get_fd() fails.
parent 2930b9c4
...@@ -117,7 +117,7 @@ static int async_get_fd( struct object *obj ) ...@@ -117,7 +117,7 @@ static int async_get_fd( struct object *obj )
{ {
struct async *async = (struct async *)obj; struct async *async = (struct async *)obj;
assert( obj->ops == &async_ops ); assert( obj->ops == &async_ops );
return dup( async->obj.fd ); return async->obj.fd;
} }
static int async_get_info( struct object *obj, struct get_file_info_request *req ) { static int async_get_info( struct object *obj, struct get_file_info_request *req ) {
......
...@@ -354,7 +354,7 @@ static int console_input_get_fd( struct object *obj ) ...@@ -354,7 +354,7 @@ static int console_input_get_fd( struct object *obj )
{ {
struct console_input *console = (struct console_input *)obj; struct console_input *console = (struct console_input *)obj;
assert( obj->ops == &console_input_ops ); assert( obj->ops == &console_input_ops );
return dup( console->obj.fd ); return console->obj.fd;
} }
static int console_get_info( struct object *obj, struct get_file_info_request *req ) static int console_get_info( struct object *obj, struct get_file_info_request *req )
...@@ -395,7 +395,7 @@ static int screen_buffer_get_fd( struct object *obj ) ...@@ -395,7 +395,7 @@ static int screen_buffer_get_fd( struct object *obj )
{ {
struct screen_buffer *console = (struct screen_buffer *)obj; struct screen_buffer *console = (struct screen_buffer *)obj;
assert( obj->ops == &screen_buffer_ops ); assert( obj->ops == &screen_buffer_ops );
return dup( console->obj.fd ); return console->obj.fd;
} }
static void screen_buffer_destroy( struct object *obj ) static void screen_buffer_destroy( struct object *obj )
...@@ -481,7 +481,7 @@ DECL_HANDLER(set_console_fd) ...@@ -481,7 +481,7 @@ DECL_HANDLER(set_console_fd)
if (!(obj = get_handle_obj( current->process, req->file_handle, if (!(obj = get_handle_obj( current->process, req->file_handle,
GENERIC_READ | GENERIC_WRITE, NULL ))) return; GENERIC_READ | GENERIC_WRITE, NULL ))) return;
if ((fd_in = obj->ops->get_fd( obj )) == -1) if ((fd_in = dup(obj->ops->get_fd( obj ))) == -1)
{ {
release_object( obj ); release_object( obj );
return; return;
......
...@@ -235,7 +235,7 @@ static int file_get_fd( struct object *obj ) ...@@ -235,7 +235,7 @@ static int file_get_fd( struct object *obj )
{ {
struct file *file = (struct file *)obj; struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops ); assert( obj->ops == &file_ops );
return dup( file->obj.fd ); return file->obj.fd;
} }
static int file_flush( struct object *obj ) static int file_flush( struct object *obj )
...@@ -474,8 +474,13 @@ DECL_HANDLER(get_handle_fd) ...@@ -474,8 +474,13 @@ DECL_HANDLER(get_handle_fd)
req->fd = -1; req->fd = -1;
if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL ))) if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL )))
{ {
if ((req->fd = get_handle_fd( current->process, req->handle, req->access )) == -1) int fd = get_handle_fd( current->process, req->handle, req->access );
send_client_fd( current, obj->ops->get_fd( obj ), req->handle ); if (fd != -1) req->fd = fd;
else if (!get_error())
{
if ((fd = obj->ops->get_fd( obj )) != -1)
send_client_fd( current, fd, req->handle );
}
release_object( obj ); release_object( obj );
} }
} }
......
...@@ -362,7 +362,6 @@ int get_handle_fd( struct process *process, int handle, unsigned int access ) ...@@ -362,7 +362,6 @@ int get_handle_fd( struct process *process, int handle, unsigned int access )
{ {
struct handle_entry *entry; struct handle_entry *entry;
if (HANDLE_IS_GLOBAL(handle)) return -1; /* no fd cache for global handles */
if (!(entry = get_handle( process, handle ))) return -1; if (!(entry = get_handle( process, handle ))) return -1;
if ((entry->access & access) != access) if ((entry->access & access) != access)
{ {
......
...@@ -91,7 +91,11 @@ static void init_page_size(void) ...@@ -91,7 +91,11 @@ static void init_page_size(void)
inline static int get_mmap_fd( struct file *file ) inline static int get_mmap_fd( struct file *file )
{ {
struct object *obj; struct object *obj;
if (!(obj = (struct object *)file)) return -1; if (!(obj = (struct object *)file))
{
set_error( STATUS_INVALID_HANDLE );
return -1;
}
return obj->ops->get_fd( obj ); return obj->ops->get_fd( obj );
} }
...@@ -100,8 +104,8 @@ static int build_shared_mapping( struct mapping *mapping, int fd, ...@@ -100,8 +104,8 @@ static int build_shared_mapping( struct mapping *mapping, int fd,
IMAGE_SECTION_HEADER *sec, int nb_sec ) IMAGE_SECTION_HEADER *sec, int nb_sec )
{ {
int i, max_size, total_size, pos; int i, max_size, total_size, pos;
char *buffer = NULL; char *buffer = NULL;
int shared_fd = -1; int shared_fd;
long toread; long toread;
/* compute the total size of the shared mapping */ /* compute the total size of the shared mapping */
...@@ -147,12 +151,10 @@ static int build_shared_mapping( struct mapping *mapping, int fd, ...@@ -147,12 +151,10 @@ static int build_shared_mapping( struct mapping *mapping, int fd,
} }
if (write( shared_fd, buffer, sec[i].SizeOfRawData ) != sec[i].SizeOfRawData) goto error; if (write( shared_fd, buffer, sec[i].SizeOfRawData ) != sec[i].SizeOfRawData) goto error;
} }
close( shared_fd );
free( buffer ); free( buffer );
return 1; return 1;
error: error:
if (shared_fd != -1) close( shared_fd );
if (buffer) free( buffer ); if (buffer) free( buffer );
return 0; return 0;
} }
...@@ -193,13 +195,11 @@ static int get_image_params( struct mapping *mapping ) ...@@ -193,13 +195,11 @@ static int get_image_params( struct mapping *mapping )
if (mapping->header_size > mapping->size_low) goto error; if (mapping->header_size > mapping->size_low) goto error;
lseek( fd, filepos, SEEK_SET ); lseek( fd, filepos, SEEK_SET );
close( fd );
free( sec ); free( sec );
return 1; return 1;
error: error:
lseek( fd, filepos, SEEK_SET ); lseek( fd, filepos, SEEK_SET );
close( fd );
if (sec) free( sec ); if (sec) free( sec );
set_error( STATUS_INVALID_FILE_FOR_SECTION ); set_error( STATUS_INVALID_FILE_FOR_SECTION );
return 0; return 0;
......
...@@ -122,7 +122,7 @@ static int pipe_get_fd( struct object *obj ) ...@@ -122,7 +122,7 @@ static int pipe_get_fd( struct object *obj )
set_error( STATUS_PIPE_BROKEN ); set_error( STATUS_PIPE_BROKEN );
return -1; return -1;
} }
return dup( pipe->obj.fd ); return pipe->obj.fd;
} }
static int pipe_get_info( struct object *obj, struct get_file_info_request *req ) static int pipe_get_info( struct object *obj, struct get_file_info_request *req )
......
...@@ -1340,7 +1340,7 @@ static void load_registry( struct key *key, int handle ) ...@@ -1340,7 +1340,7 @@ static void load_registry( struct key *key, int handle )
int fd; int fd;
if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) return; if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) return;
fd = obj->ops->get_fd( obj ); fd = dup(obj->ops->get_fd( obj ));
release_object( obj ); release_object( obj );
if (fd != -1) if (fd != -1)
{ {
...@@ -1435,7 +1435,7 @@ static void save_registry( struct key *key, int handle ) ...@@ -1435,7 +1435,7 @@ static void save_registry( struct key *key, int handle )
return; return;
} }
if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL ))) return; if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL ))) return;
fd = obj->ops->get_fd( obj ); fd = dup(obj->ops->get_fd( obj ));
release_object( obj ); release_object( obj );
if (fd != -1) if (fd != -1)
{ {
......
...@@ -259,6 +259,9 @@ int send_client_fd( struct thread *thread, int fd, int handle ) ...@@ -259,6 +259,9 @@ int send_client_fd( struct thread *thread, int fd, int handle )
{ {
int ret; int ret;
if (debug_level)
fprintf( stderr, "%08x: *fd* %d = %d\n", (unsigned int)thread, handle, fd );
#ifdef HAVE_MSGHDR_ACCRIGHTS #ifdef HAVE_MSGHDR_ACCRIGHTS
msghdr.msg_accrightslen = sizeof(fd); msghdr.msg_accrightslen = sizeof(fd);
msghdr.msg_accrights = (void *)&fd; msghdr.msg_accrights = (void *)&fd;
...@@ -272,7 +275,6 @@ int send_client_fd( struct thread *thread, int fd, int handle ) ...@@ -272,7 +275,6 @@ int send_client_fd( struct thread *thread, int fd, int handle )
myiovec.iov_len = sizeof(handle); myiovec.iov_len = sizeof(handle);
ret = sendmsg( thread->obj.fd, &msghdr, 0 ); ret = sendmsg( thread->obj.fd, &msghdr, 0 );
close( fd );
if (ret > 0) return 0; if (ret > 0) return 0;
if (errno == EPIPE) if (errno == EPIPE)
...@@ -381,6 +383,7 @@ struct object *create_request_socket( struct thread *thread ) ...@@ -381,6 +383,7 @@ struct object *create_request_socket( struct thread *thread )
} }
sock->thread = thread; sock->thread = thread;
send_client_fd( thread, fd[1], -1 ); send_client_fd( thread, fd[1], -1 );
close( fd[1] );
set_select_events( &sock->obj, POLLIN ); set_select_events( &sock->obj, POLLIN );
return &sock->obj; return &sock->obj;
} }
......
...@@ -154,7 +154,7 @@ static int serial_get_fd( struct object *obj ) ...@@ -154,7 +154,7 @@ static int serial_get_fd( struct object *obj )
{ {
struct serial *serial = (struct serial *)obj; struct serial *serial = (struct serial *)obj;
assert( obj->ops == &serial_ops ); assert( obj->ops == &serial_ops );
return dup( serial->obj.fd ); return serial->obj.fd;
} }
static int serial_get_info( struct object *obj, struct get_file_info_request *req ) static int serial_get_info( struct object *obj, struct get_file_info_request *req )
......
...@@ -255,12 +255,8 @@ static int sock_get_poll_events( struct object *obj ) ...@@ -255,12 +255,8 @@ static int sock_get_poll_events( struct object *obj )
static int sock_get_fd( struct object *obj ) static int sock_get_fd( struct object *obj )
{ {
struct sock *sock = (struct sock *)obj; struct sock *sock = (struct sock *)obj;
int fd;
assert( obj->ops == &sock_ops ); assert( obj->ops == &sock_ops );
fd = dup( sock->obj.fd ); return sock->obj.fd;
if (fd==-1)
sock_set_error();
return fd;
} }
static void sock_destroy( struct object *obj ) static void sock_destroy( struct object *obj )
......
...@@ -109,6 +109,8 @@ static int alloc_client_buffer( struct thread *thread ) ...@@ -109,6 +109,8 @@ static int alloc_client_buffer( struct thread *thread )
send_client_fd( thread, fd_pipe[0], -1 ); send_client_fd( thread, fd_pipe[0], -1 );
send_client_fd( thread, fd, -1 ); send_client_fd( thread, fd, -1 );
send_reply( thread ); send_reply( thread );
close( fd_pipe[0] );
close( fd );
return 1; return 1;
error: error:
...@@ -691,6 +693,7 @@ DECL_HANDLER(new_thread) ...@@ -691,6 +693,7 @@ DECL_HANDLER(new_thread)
THREAD_ALL_ACCESS, req->inherit )) != -1) THREAD_ALL_ACCESS, req->inherit )) != -1)
{ {
send_client_fd( current, sock[1], req->handle ); send_client_fd( current, sock[1], req->handle );
close( sock[1] );
/* thread object will be released when the thread gets killed */ /* thread object will be released when the thread gets killed */
add_process_thread( current->process, thread ); add_process_thread( current->process, thread );
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment