[Wine-patches] [eter-1.0.10] Fix eterbug #4125.
Alexander Morozov
amorozov на etersoft.ru
Вт Июл 21 18:46:58 MSD 2009
----------- следующая часть -----------
From 6cb3a133aa40e25339ef1600004732f598719346 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 21 Jul 2009 18:37:36 +0400
Subject: [eter-1.0.10] Fix eterbug #4125.
---
dlls/kernel32/process.c | 13 ++++++++++++-
include/wine/server_protocol.h | 17 ++++++++++++++++-
server/fd.c | 24 ++++++++++++++++++++++++
server/protocol.def | 5 +++++
server/request.h | 3 +++
server/trace.c | 9 +++++++++
6 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index d412453..f8b627f 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1441,7 +1441,18 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHA
if (newdir) chdir(newdir);
- if (argv && envp) execve( filename, argv, envp );
+ if (argv && envp)
+ {
+ /* Close file descriptor for locks to prevent ETXTBSY error */
+ SERVER_START_REQ( close_lock_fd )
+ {
+ wine_server_add_data( req, filename, strlen(filename) + 1 );
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+
+ execve( filename, argv, envp );
+ }
err = errno;
write( fd[1], &err, sizeof(err) );
_exit(1);
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 43d7658..d6301ef 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4522,6 +4522,18 @@ struct get_device_reply
};
+struct close_lock_fd_request
+{
+ struct request_header __header;
+ /* VARARG(filename,string); */
+ char __pad_12[4];
+};
+struct close_lock_fd_reply
+{
+ struct reply_header __header;
+};
+
+
enum request
{
REQ_new_process,
@@ -4762,6 +4774,7 @@ enum request
REQ_set_window_layered_info,
REQ_get_device_name,
REQ_get_device,
+ REQ_close_lock_fd,
REQ_NB_REQUESTS
};
@@ -5007,6 +5020,7 @@ union generic_request
struct set_window_layered_info_request set_window_layered_info_request;
struct get_device_name_request get_device_name_request;
struct get_device_request get_device_request;
+ struct close_lock_fd_request close_lock_fd_request;
};
union generic_reply
{
@@ -5250,8 +5264,9 @@ union generic_reply
struct set_window_layered_info_reply set_window_layered_info_reply;
struct get_device_name_reply get_device_name_reply;
struct get_device_reply get_device_reply;
+ struct close_lock_fd_reply close_lock_fd_reply;
};
-#define SERVER_PROTOCOL_VERSION 10384
+#define SERVER_PROTOCOL_VERSION 10385
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/fd.c b/server/fd.c
index a0c799b..445965b 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2255,3 +2255,27 @@ DECL_HANDLER(add_fd_completion)
release_object( fd );
}
}
+
+/* close file descriptor used for locks */
+DECL_HANDLER(close_lock_fd)
+{
+ int fd;
+ struct stat st;
+ struct inode *inode;
+ const char *name = get_req_data();
+
+ if (name[get_req_data_size() - 1] != 0) return;
+ fd = open( name, O_RDONLY );
+ if (fd < 0) return;
+ fstat( fd, &st );
+ if ((inode = get_inode( st.st_dev, st.st_ino, fd )))
+ {
+ if (inode->lock_fd != -1)
+ {
+ close( inode->lock_fd );
+ inode->lock_fd = -1;
+ }
+ release_object( inode );
+ }
+ close( fd );
+}
diff --git a/server/protocol.def b/server/protocol.def
index 2bdb13e..b91a9c5 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3135,3 +3135,8 @@ enum message_type
@REPLY
client_ptr_t user_ptr; /* opaque ptr for client side */
@END
+
+/* Close file descriptor used for locks */
+ на REQ(close_lock_fd)
+ VARARG(filename,string); /* file name */
+ на END
diff --git a/server/request.h b/server/request.h
index 4a9044f..ec56d06 100644
--- a/server/request.h
+++ b/server/request.h
@@ -349,6 +349,7 @@ DECL_HANDLER(get_window_layered_info);
DECL_HANDLER(set_window_layered_info);
DECL_HANDLER(get_device_name);
DECL_HANDLER(get_device);
+DECL_HANDLER(close_lock_fd);
#ifdef WANT_REQUEST_HANDLERS
@@ -593,6 +594,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_set_window_layered_info,
(req_handler)req_get_device_name,
(req_handler)req_get_device,
+ (req_handler)req_close_lock_fd,
};
C_ASSERT( sizeof(affinity_t) == 8 );
@@ -1896,6 +1898,7 @@ C_ASSERT( FIELD_OFFSET(struct get_device_request, rootdir) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_device_request, manager) == 20 );
C_ASSERT( FIELD_OFFSET(struct get_device_reply, user_ptr) == 8 );
C_ASSERT( sizeof(struct get_device_reply) == 16 );
+C_ASSERT( sizeof(struct close_lock_fd_request) == 16 );
#endif /* WANT_REQUEST_HANDLERS */
diff --git a/server/trace.c b/server/trace.c
index 33a4467..d7031da 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -4040,6 +4040,12 @@ static void dump_get_device_reply( const struct get_device_reply *req )
dump_uint64( &req->user_ptr );
}
+static void dump_close_lock_fd_request( const struct close_lock_fd_request *req )
+{
+ fprintf( stderr, " filename=" );
+ dump_varargs_string( cur_size );
+}
+
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
@@ -4279,6 +4285,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_window_layered_info_request,
(dump_func)dump_get_device_name_request,
(dump_func)dump_get_device_request,
+ (dump_func)dump_close_lock_fd_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -4520,6 +4527,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL,
(dump_func)dump_get_device_name_reply,
(dump_func)dump_get_device_reply,
+ NULL,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4761,6 +4769,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_window_layered_info",
"get_device_name",
"get_device",
+ "close_lock_fd",
};
static const struct
--
1.6.3.3
Подробная информация о списке рассылки Wine-patches