kernel32: Overhaul the handling of argv in set_process_name().

Ken Thomases ken at codeweavers.com
Mon Jul 11 23:44:20 CDT 2016


This fixes several problems with the code:

* The code had been assuming that the argument strings pointed to by the argv
  array are contiguous iff certain process-name-setting functions are available.
  This doesn't seem reliable.  Instead, test if it's true and shift the strings
  if so.

  However, setproctitle() is specifically documented as a preferred alternative
  to the technique of overwriting the arg strings, so don't shift the strings
  if that's available.

* Use the last path component, recognizing backslash as a path separator, for
  setprogname() in addition to prctl().  First, setprogname() is documented as
  searching for the last component itself, but it doesn't understand Windows-
  style paths, so we need to help it.  Second, on some platforms (e.g. macOS),
  setprogname(), like prctl(), has a fairly small internal length limit (e.g.
  32 characters).  So, concentrate on the most meaningful part of the path.

* Remove argv[0] from argv whether or not there are any process-name-setting
  functions available.  This is necessary for the proper functioning of Wine,
  so it must be done on all platforms.  This part of the logic was lost with
  commit 5a4576ee0.

* Call all available process-name-setting functions instead of treating them
  as mutually exclusive alternatives.  This is also logic that was lost with
  commit 5a4576ee0.

Signed-off-by: Ken Thomases <ken at codeweavers.com>
---
 dlls/kernel32/process.c | 63 +++++++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 26 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 4771108..5b584ac 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1116,39 +1116,36 @@ static DWORD WINAPI start_process( PEB *peb )
  */
 static void set_process_name( int argc, char *argv[] )
 {
+    BOOL shift_strings;
+    char *p, *name;
+    int i;
+
 #ifdef HAVE_SETPROCTITLE
     setproctitle("-%s", argv[1]);
-    /* remove argv[0] */
-    memmove( argv, argv + 1, argc * sizeof(argv[0]) );
-#elif defined(HAVE_SETPROGNAME)
-    int i, offset;
-    char *end = argv[argc-1] + strlen(argv[argc-1]) + 1;
+    shift_strings = FALSE;
+#else
+    p = argv[0];
 
-    offset = argv[1] - argv[0];
-    memmove( argv[1] - offset, argv[1], end - argv[1] );
-    memset( end - offset, 0, offset );
-    for (i = 1; i < argc; i++) argv[i-1] = argv[i] - offset;
-    argv[i-1] = NULL;
-
-    setprogname( argv[0] );
-#elif defined(HAVE_PRCTL)
-    int i, offset;
-    char *p, *prctl_name = argv[1];
-    char *end = argv[argc-1] + strlen(argv[argc-1]) + 1;
-
-#ifndef PR_SET_NAME
-# define PR_SET_NAME 15
+    shift_strings = (argc >= 2);
+    for (i = 1; i < argc; i++)
+    {
+        p += strlen(p) + 1;
+        if (p != argv[i])
+        {
+            shift_strings = FALSE;
+            break;
+        }
+    }
 #endif
 
-    if ((p = strrchr( prctl_name, '\\' ))) prctl_name = p + 1;
-    if ((p = strrchr( prctl_name, '/' ))) prctl_name = p + 1;
-
-    if (prctl( PR_SET_NAME, prctl_name ) != -1)
+    if (shift_strings)
     {
-        offset = argv[1] - argv[0];
-        memmove( argv[1] - offset, argv[1], end - argv[1] );
+        int offset = argv[1] - argv[0];
+        char *end = argv[argc-1] + strlen(argv[argc-1]) + 1;
+        memmove( argv[0], argv[1], end - argv[1] );
         memset( end - offset, 0, offset );
-        for (i = 1; i < argc; i++) argv[i-1] = argv[i] - offset;
+        for (i = 1; i < argc; i++)
+            argv[i-1] = argv[i] - offset;
         argv[i-1] = NULL;
     }
     else
@@ -1156,6 +1153,20 @@ static void set_process_name( int argc, char *argv[] )
         /* remove argv[0] */
         memmove( argv, argv + 1, argc * sizeof(argv[0]) );
     }
+
+    name = argv[0];
+    if ((p = strrchr( name, '\\' ))) name = p + 1;
+    if ((p = strrchr( name, '/' ))) name = p + 1;
+
+#if defined(HAVE_SETPROGNAME)
+    setprogname( name );
+#endif
+
+#ifdef HAVE_PRCTL
+#ifndef PR_SET_NAME
+# define PR_SET_NAME 15
+#endif
+    prctl( PR_SET_NAME, name );
 #endif  /* HAVE_PRCTL */
 }
 
-- 
2.8.2




More information about the wine-patches mailing list