[Wine-patches] [eterhack] Fix eterbug #4125.

Alexander Morozov amorozov на etersoft.ru
Вт Июл 21 18:46:44 MSD 2009


----------- следующая часть -----------
From ec5f94ad01f7abaf0ab1263612c0b9cb846b7d5b Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 21 Jul 2009 18:34:22 +0400
Subject: [eterhack] 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, 68 insertions(+), 3 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 65295fc..484a07c 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1490,7 +1490,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 fca90e7..50537fc 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4613,6 +4613,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,
@@ -4855,6 +4867,7 @@ enum request
     REQ_set_window_layered_info,
     REQ_get_device_name,
     REQ_get_device,
+    REQ_close_lock_fd,
     REQ_NB_REQUESTS
 };
 
@@ -5102,6 +5115,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
 {
@@ -5347,8 +5361,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 10387
+#define SERVER_PROTOCOL_VERSION 10388
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/fd.c b/server/fd.c
index 8126a74..bc6a4e1 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2261,3 +2261,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 806e6a8..25eddc7 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3212,3 +3212,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 f536fcd..bf748a3 100644
--- a/server/request.h
+++ b/server/request.h
@@ -351,6 +351,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
 
@@ -597,6 +598,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 );
@@ -1907,6 +1909,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 f5dce77..d1ec1b4 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3836,6 +3836,11 @@ static void dump_get_device_reply( const struct get_device_reply *req )
     dump_uint64( " user_ptr=", &req->user_ptr );
 }
 
+static void dump_close_lock_fd_request( const struct close_lock_fd_request *req )
+{
+    dump_varargs_string( " filename=", 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,
@@ -4077,6 +4082,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] = {
@@ -4320,6 +4326,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] = {
@@ -4563,6 +4570,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
@@ -4613,7 +4621,6 @@ static const struct
     { "IO_TIMEOUT",                  STATUS_IO_TIMEOUT },
     { "KEY_DELETED",                 STATUS_KEY_DELETED },
     { "MAPPED_FILE_SIZE_ZERO",       STATUS_MAPPED_FILE_SIZE_ZERO },
-    { "MEDIA_WRITE_PROTECTED",       STATUS_MEDIA_WRITE_PROTECTED },
     { "MUTANT_NOT_OWNED",            STATUS_MUTANT_NOT_OWNED },
     { "NAME_TOO_LONG",               STATUS_NAME_TOO_LONG },
     { "NOTIFY_ENUM_DIR",             STATUS_NOTIFY_ENUM_DIR },
-- 
1.6.3.3



Подробная информация о списке рассылки Wine-patches