Avoid dup'ing file descriptors when not necessary.
Do not send fd to the client if ops->get_fd() fails.
diff --git a/server/async.c b/server/async.c
index 7978a90..fb722bc 100644
--- a/server/async.c
+++ b/server/async.c
@@ -117,7 +117,7 @@
{
struct async *async = (struct async *)obj;
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 ) {
diff --git a/server/console.c b/server/console.c
index dcdc287..7454c9a 100644
--- a/server/console.c
+++ b/server/console.c
@@ -354,7 +354,7 @@
{
struct console_input *console = (struct console_input *)obj;
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 )
@@ -395,7 +395,7 @@
{
struct screen_buffer *console = (struct screen_buffer *)obj;
assert( obj->ops == &screen_buffer_ops );
- return dup( console->obj.fd );
+ return console->obj.fd;
}
static void screen_buffer_destroy( struct object *obj )
@@ -481,7 +481,7 @@
if (!(obj = get_handle_obj( current->process, req->file_handle,
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 );
return;
diff --git a/server/file.c b/server/file.c
index e0ce8a7..0c8aaae 100644
--- a/server/file.c
+++ b/server/file.c
@@ -235,7 +235,7 @@
{
struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops );
- return dup( file->obj.fd );
+ return file->obj.fd;
}
static int file_flush( struct object *obj )
@@ -474,8 +474,13 @@
req->fd = -1;
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)
- send_client_fd( current, obj->ops->get_fd( obj ), req->handle );
+ int fd = get_handle_fd( current->process, req->handle, req->access );
+ 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 );
}
}
diff --git a/server/handle.c b/server/handle.c
index 6a3e1f6..c3b8a05 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -362,7 +362,6 @@
{
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->access & access) != access)
{
diff --git a/server/mapping.c b/server/mapping.c
index 38d1d89..43a67d8 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -91,7 +91,11 @@
inline static int get_mmap_fd( struct file *file )
{
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 );
}
@@ -100,8 +104,8 @@
IMAGE_SECTION_HEADER *sec, int nb_sec )
{
int i, max_size, total_size, pos;
- char *buffer = NULL;
- int shared_fd = -1;
+ char *buffer = NULL;
+ int shared_fd;
long toread;
/* compute the total size of the shared mapping */
@@ -147,12 +151,10 @@
}
if (write( shared_fd, buffer, sec[i].SizeOfRawData ) != sec[i].SizeOfRawData) goto error;
}
- close( shared_fd );
free( buffer );
return 1;
error:
- if (shared_fd != -1) close( shared_fd );
if (buffer) free( buffer );
return 0;
}
@@ -193,13 +195,11 @@
if (mapping->header_size > mapping->size_low) goto error;
lseek( fd, filepos, SEEK_SET );
- close( fd );
free( sec );
return 1;
error:
lseek( fd, filepos, SEEK_SET );
- close( fd );
if (sec) free( sec );
set_error( STATUS_INVALID_FILE_FOR_SECTION );
return 0;
diff --git a/server/pipe.c b/server/pipe.c
index 7838c12..47dfb61 100644
--- a/server/pipe.c
+++ b/server/pipe.c
@@ -122,7 +122,7 @@
set_error( STATUS_PIPE_BROKEN );
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 )
diff --git a/server/registry.c b/server/registry.c
index af7ba8a..4fa5a4e 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -1340,7 +1340,7 @@
int fd;
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 );
if (fd != -1)
{
@@ -1435,7 +1435,7 @@
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 );
if (fd != -1)
{
diff --git a/server/request.c b/server/request.c
index fff02dd4..7a8498b 100644
--- a/server/request.c
+++ b/server/request.c
@@ -259,6 +259,9 @@
{
int ret;
+ if (debug_level)
+ fprintf( stderr, "%08x: *fd* %d = %d\n", (unsigned int)thread, handle, fd );
+
#ifdef HAVE_MSGHDR_ACCRIGHTS
msghdr.msg_accrightslen = sizeof(fd);
msghdr.msg_accrights = (void *)&fd;
@@ -272,7 +275,6 @@
myiovec.iov_len = sizeof(handle);
ret = sendmsg( thread->obj.fd, &msghdr, 0 );
- close( fd );
if (ret > 0) return 0;
if (errno == EPIPE)
@@ -381,6 +383,7 @@
}
sock->thread = thread;
send_client_fd( thread, fd[1], -1 );
+ close( fd[1] );
set_select_events( &sock->obj, POLLIN );
return &sock->obj;
}
diff --git a/server/serial.c b/server/serial.c
index 7d30d4d..f32f8a3 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -154,7 +154,7 @@
{
struct serial *serial = (struct serial *)obj;
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 )
diff --git a/server/sock.c b/server/sock.c
index c5f41e4..ec7a067 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -255,12 +255,8 @@
static int sock_get_fd( struct object *obj )
{
struct sock *sock = (struct sock *)obj;
- int fd;
assert( obj->ops == &sock_ops );
- fd = dup( sock->obj.fd );
- if (fd==-1)
- sock_set_error();
- return fd;
+ return sock->obj.fd;
}
static void sock_destroy( struct object *obj )
diff --git a/server/thread.c b/server/thread.c
index 12e9377..2726140 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -109,6 +109,8 @@
send_client_fd( thread, fd_pipe[0], -1 );
send_client_fd( thread, fd, -1 );
send_reply( thread );
+ close( fd_pipe[0] );
+ close( fd );
return 1;
error:
@@ -691,6 +693,7 @@
THREAD_ALL_ACCESS, req->inherit )) != -1)
{
send_client_fd( current, sock[1], req->handle );
+ close( sock[1] );
/* thread object will be released when the thread gets killed */
add_process_thread( current->process, thread );
return;