delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2010/05/18/06:41:33

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-0.4 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,RCVD_IN_DNSWL_NONE,TW_CP
X-Spam-Check-By: sourceware.org
Resent-To: cygwin AT cygwin DOT com
Resent-From: Kazuhiro Fujieda <fujieda AT acm DOT org>
Resent-Date: Tue, 18 May 2010 19:41:11 +0900
Resent-Message-ID: <u39xpbigo DOT fsf AT acm DOT org>
To: cygwin AT cygwin DOT com
Subject: Re: vfork always fail problem
References: <AANLkTik_jo0N1YtUTFLzsqAsv5OkkyjCG9epeMq55bWk AT mail DOT gmail DOT com> <op DOT vcop6qoo1e62zd AT merlin DOT emma DOT line DOT org> <AANLkTikoAoUAarNLwuIHe6GypKg62rjKR1VPyQYygT17 AT mail DOT gmail DOT com> <20100514192202 DOT GB8785 AT calimero DOT vinschen DOT de>
From: Kazuhiro Fujieda <fujieda AT acm DOT org>
Date: Tue, 18 May 2010 14:47:57 +0900
In-Reply-To: <20100514192202.GB8785@calimero.vinschen.de> (Corinna Vinschen's message of "Fri\, 14 May 2010 21\:22\:02 +0200")
Message-ID: <u1vd9ahgy.fsf@acm.org>
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.3 (windows-nt)
MIME-Version: 1.0
Lines: 462
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Unsubscribe: <mailto:cygwin-unsubscribe-archive-cygwin=delorie DOT com AT cygwin DOT com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

>>> On Fri, 14 May 2010 21:22:02 +0200
>>> Corinna Vinschen said:

> That sounds a bit weird.  The joke of using the ...W functions is that
> the string parameters are always given in UTF-16.  GBK is a multibyte
> charset and can only be used in conjunction with the ...A functions.
> However, I'm on vacation so I can't test this scenario right now.

GetModuleFileName used in pinfo_basic::pinfo_basic disturbs the
order. This function uses ANSI codepage. 'fork' for a file whose
name contains multibyte characters doesn't work well in UTF-8 locales.

This call should be GetModuleFileNameW and the type of progname
in _pinfo should be wide characters. I attached the patch.
-- 
Kazuhiro Fujieda
fujieda AT acm DOT org

2010-05-18  Kazuhiro Fujida  <fujieda AT acm DOT org>

	* environ.cc (regopt): Change the first argument to wide char string.
	(environ_init): Accommodate change to the first argument of regopt.
	* exception.cc (open_stackdumpfile): Accommodate change to the type
	of progname in _pinfo.
	* external.cc (fillout_pinfo): Ditto.
	* fhandler_process.cc (format_process_winexename): Ditto.
	(format_process_stat): Ditto.
	* fork.cc (fork::parent): Ditto.
	* pinfo.cc (pinfo_basic::pinfo_basic): Call GetModuleFileNameW
	instead of GetModuleFileName.
	(pinfo::thisproc): Accommodate change to the type of progname in
	_pinfo.
	(pinfo_init): Ditto.
	* pinfo.h (_pinfo): Change the type of progname to a wide char array.
	* registry.h (reg_key::get_int): Change the first argument from
	constant point to pointer to constant.
	(reg_key::get_string): Ditto. Change the last argument likewise.
	* registry.cc (reg_key::get_int): Accommodate change to the
	declaration.
	(reg_key::get_string): Ditto.
	* strace.cc (strace::hello): Accommodate change to the type of
	progname in _pinfo.
	(strace::vsprntf): Ditto.

Index: environ.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/environ.cc,v
retrieving revision 1.182
diff -u -r1.182 environ.cc
--- environ.cc	16 Nov 2009 20:05:49 -0000	1.182
+++ environ.cc	18 May 2010 05:31:45 -0000
@@ -29,6 +29,7 @@
 #include "registry.h"
 #include "environ.h"
 #include "child_info.h"
+#include "ntdll.h"
 
 extern bool dos_file_warning;
 extern bool ignore_case_with_glob;
@@ -698,18 +699,24 @@
 
 /* Set options from the registry. */
 static bool __stdcall
-regopt (const char *name, char *buf)
+regopt (const WCHAR *name, char *buf)
 {
   bool parsed_something = false;
-  char lname[strlen (name) + 1];
-  strlwr (strcpy (lname, name));
+  UNICODE_STRING lname;
+  size_t len = (wcslen(name) + 1) * sizeof (WCHAR);
+  RtlInitEmptyUnicodeString(&lname, (PWCHAR) alloca (len), len);
+  wcscpy(lname.Buffer, name);
+  RtlDowncaseUnicodeString(&lname, &lname, FALSE);
 
   for (int i = 0; i < 2; i++)
     {
       reg_key r (i, KEY_READ, CYGWIN_INFO_PROGRAM_OPTIONS_NAME, NULL);
 
-      if (r.get_string (lname, buf, NT_MAX_PATH, "") == ERROR_SUCCESS)
+      if (r.get_string (lname.Buffer, (PWCHAR) buf, NT_MAX_PATH, L"") == ERROR_SUCCESS)
 	{
+	  char *newp;
+	  sys_wcstombs_alloc(&newp, HEAP_NOTHEAP, (PWCHAR) buf);
+	  strcpy(buf, newp);
 	  parse_options (buf);
 	  parsed_something = true;
 	  break;
@@ -747,7 +754,7 @@
       }
 
   char *tmpbuf = tp.t_get ();
-  got_something_from_registry = regopt ("default", tmpbuf);
+  got_something_from_registry = regopt (L"default", tmpbuf);
   if (myself->progname[0])
     got_something_from_registry = regopt (myself->progname, tmpbuf)
 				  || got_something_from_registry;
Index: exceptions.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/exceptions.cc,v
retrieving revision 1.343
diff -u -r1.343 exceptions.cc
--- exceptions.cc	20 Apr 2010 10:44:52 -0000	1.343
+++ exceptions.cc	18 May 2010 05:31:45 -0000
@@ -130,24 +130,21 @@
 {
   if (myself->progname[0])
     {
-      const char *p;
+      const WCHAR *p;
       /* write to progname.stackdump if possible */
       if (!myself->progname[0])
-	p = "unknown";
-      else if ((p = strrchr (myself->progname, '\\')))
+	p = L"unknown";
+      else if ((p = wcsrchr (myself->progname, L'\\')))
 	p++;
       else
 	p = myself->progname;
 
-      WCHAR corefile[strlen (p) + sizeof (".stackdump")];
+      WCHAR corefile[wcslen (p) + sizeof (L".stackdump")];
+      wcscpy(corefile, p);
       UNICODE_STRING ucore;
       OBJECT_ATTRIBUTES attr;
       /* Create the UNICODE variation of <progname>.stackdump. */
-      RtlInitEmptyUnicodeString (&ucore, corefile,
-				 sizeof corefile - sizeof (WCHAR));
-      ucore.Length = sys_mbstowcs (ucore.Buffer,
-				   ucore.MaximumLength / sizeof (WCHAR),
-				   p, strlen (p)) * sizeof (WCHAR);
+      RtlInitUnicodeString (&ucore, corefile);
       RtlAppendUnicodeToString (&ucore, L".stackdump");
       /* Create an object attribute which refers to <progname>.stackdump
 	 in Cygwin's cwd.  Stick to caseinsensitivity. */
Index: external.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/external.cc,v
retrieving revision 1.114
diff -u -r1.114 external.cc
--- external.cc	29 Apr 2010 08:47:43 -0000	1.114
+++ external.cc	18 May 2010 05:31:45 -0000
@@ -89,7 +89,7 @@
 	  ep.rusage_self = p->rusage_self;
 	  ep.rusage_children = p->rusage_children;
 	  ep.progname[0] = '\0';
-	  strncat (ep.progname, p->progname, MAX_PATH - 1);
+	  sys_wcstombs(ep.progname, MAX_PATH, p->progname);
 	  ep.strace_mask = 0;
 	  ep.version = EXTERNAL_PINFO_VERSION;
 
@@ -99,7 +99,7 @@
 	  ep.gid32 = p->gid;
 
 	  ep.progname_long = ep_progname_long_buf;
-	  strcpy (ep.progname_long, p->progname);
+	  sys_wcstombs(ep.progname_long, NT_MAX_PATH, p->progname);
 	  break;
 	}
     }
Index: fhandler_process.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_process.cc,v
retrieving revision 1.90
diff -u -r1.90 fhandler_process.cc
--- fhandler_process.cc	9 Mar 2010 21:26:55 -0000	1.90
+++ fhandler_process.cc	18 May 2010 05:31:45 -0000
@@ -537,9 +537,9 @@
 format_process_winexename (void *data, char *&destbuf)
 {
   _pinfo *p = (_pinfo *) data;
-  int len = strlen (p->progname);
-  destbuf = (char *) crealloc_abort (destbuf, len + 2);
-  strcpy (destbuf, p->progname);
+  size_t len = sys_wcstombs (NULL, 0, p->progname);
+  destbuf = (char *) crealloc_abort (destbuf, len + 1);
+  sys_wcstombs (destbuf, len, p->progname);
   destbuf[len] = '\n';
   return len + 1;
 }
@@ -649,6 +649,7 @@
 {
   _pinfo *p = (_pinfo *) data;
   char cmd[NAME_MAX + 1];
+  WCHAR wcmd[NAME_MAX + 1];
   int state = 'R';
   unsigned long fault_count = 0UL,
 		utime = 0UL, stime = 0UL,
@@ -659,8 +660,9 @@
     strcpy (cmd, "<defunct>");
   else
     {
-      char *last_slash = strrchr (p->progname, '\\');
-      strcpy (cmd, last_slash ? last_slash + 1 : p->progname);
+      PWCHAR last_slash = wcsrchr (p->progname, L'\\');
+      wcscpy (wcmd, last_slash ? last_slash + 1 : p->progname);
+      sys_wcstombs (cmd, NAME_MAX + 1, wcmd);
       int len = strlen (cmd);
       if (len > 4)
 	{
@@ -779,6 +781,7 @@
 {
   _pinfo *p = (_pinfo *) data;
   char cmd[NAME_MAX + 1];
+  WCHAR wcmd[NAME_MAX + 1];
   int state = 'R';
   const char *state_str = "unknown";
   unsigned long vmsize = 0UL, vmrss = 0UL, vmdata = 0UL, vmlib = 0UL, vmtext = 0UL,
@@ -787,8 +790,9 @@
     strcpy (cmd, "<defunct>");
   else
     {
-      char *last_slash = strrchr (p->progname, '\\');
-      strcpy (cmd, last_slash ? last_slash + 1 : p->progname);
+      PWCHAR last_slash = wcsrchr (p->progname, L'\\');
+      wcscpy (wcmd, last_slash ? last_slash + 1 : p->progname);
+      sys_wcstombs (cmd, NAME_MAX + 1, wcmd);
       int len = strlen (cmd);
       if (len > 4)
 	{
Index: fork.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fork.cc,v
retrieving revision 1.210
diff -u -r1.210 fork.cc
--- fork.cc	18 Dec 2009 20:32:04 -0000	1.210
+++ fork.cc	18 May 2010 05:31:45 -0000
@@ -342,13 +342,8 @@
   si.lpReserved2 = (LPBYTE) &ch;
   si.cbReserved2 = sizeof (ch);
 
-  /* FIXME: myself->progname should be converted to WCHAR. */
-  tmp_pathbuf tp;
-  PWCHAR progname = tp.w_get ();
-  sys_mbstowcs (progname, NT_MAX_PATH, myself->progname);
-
   syscall_printf ("CreateProcess (%W, %W, 0, 0, 1, %p, 0, 0, %p, %p)",
-		  progname, progname, c_flags, &si, &pi);
+		  myself->progname, myself->progname, c_flags, &si, &pi);
   bool locked = __malloc_lock ();
   time_t start_time = time (NULL);
 
@@ -358,8 +353,8 @@
 
   while (1)
     {
-      rc = CreateProcessW (progname, /* image to run */
-			   progname, /* what we send in arg0 */
+      rc = CreateProcessW (myself->progname, /* image to run */
+			   myself->progname, /* what we send in arg0 */
 			   &sec_none_nih,
 			   &sec_none_nih,
 			   TRUE,	  /* inherit handles from parent */
@@ -430,7 +425,7 @@
 
   /* Initialize things that are done later in dll_crt0_1 that aren't done
      for the forkee.  */
-  strcpy (child->progname, myself->progname);
+  wcscpy (child->progname, myself->progname);
 
   /* Fill in fields in the child's process table entry.  */
   child->dwProcessId = pi.dwProcessId;
Index: pinfo.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/pinfo.cc,v
retrieving revision 1.260
diff -u -r1.260 pinfo.cc
--- pinfo.cc	12 Mar 2010 23:13:47 -0000	1.260
+++ pinfo.cc	18 May 2010 05:31:45 -0000
@@ -39,7 +39,7 @@
 pinfo_basic::pinfo_basic()
 {
   pid = dwProcessId = GetCurrentProcessId ();
-  GetModuleFileName (NULL, progname, sizeof (progname));
+  GetModuleFileNameW (NULL, progname, sizeof (progname));
 }
 
 pinfo_basic myself_initial NO_COPY;
@@ -62,7 +62,7 @@
   init (cygheap->pid, PID_IN_USE, h ?: INVALID_HANDLE_VALUE);
   procinfo->process_state |= PID_IN_USE;
   procinfo->dwProcessId = myself_initial.pid;
-  strcpy (procinfo->progname, myself_initial.progname);
+  wcscpy (procinfo->progname, myself_initial.progname);
   strace.hello ();
   debug_printf ("myself->dwProcessId %u", procinfo->dwProcessId);
   if (h)
@@ -121,7 +121,9 @@
     case STATUS_DLL_NOT_FOUND:
       {
 	char posix_prog[NT_MAX_PATH];
-	path_conv pc (myself->progname, PC_NOWARN);
+	UNICODE_STRING uc;
+	RtlInitUnicodeString(&uc, myself->progname);
+	path_conv pc (&uc, PC_NOWARN);
 	mount_table->conv_to_posix_path (pc.get_win32 (), posix_prog, 1);
 	small_printf ("%s: error while loading shared libraries: %s: cannot open shared object file: No such file or directory\n",
 		      posix_prog, find_first_notloaded_dll (pc));
Index: pinfo.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/pinfo.h,v
retrieving revision 1.109
diff -u -r1.109 pinfo.h
--- pinfo.h	6 Oct 2009 21:51:17 -0000	1.109
+++ pinfo.h	18 May 2010 05:31:45 -0000
@@ -64,7 +64,7 @@
   DWORD dwProcessId;
 
   /* Used to spawn a child for fork(), among other things. */
-  char progname[NT_MAX_PATH];
+  WCHAR progname[NT_MAX_PATH];
 
   /* User information.
      The information is derived from the GetUserName system call,
Index: registry.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/registry.cc,v
retrieving revision 1.40
diff -u -r1.40 registry.cc
--- registry.cc	12 Feb 2010 01:04:52 -0000	1.40
+++ registry.cc	18 May 2010 05:31:45 -0000
@@ -123,7 +123,7 @@
 }
 
 int
-reg_key::get_int (const PWCHAR name, int def)
+reg_key::get_int (const WCHAR *name, int def)
 {
   DWORD type;
   DWORD dst;
@@ -185,7 +185,7 @@
 }
 
 int
-reg_key::get_string (const PWCHAR name, PWCHAR dst, size_t max, const PWCHAR def)
+reg_key::get_string (const WCHAR *name, PWCHAR dst, size_t max, const WCHAR *def)
 {
   DWORD size = max;
   DWORD type;
Index: registry.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/registry.h,v
retrieving revision 1.9
diff -u -r1.9 registry.h
--- registry.h	20 Oct 2009 14:54:47 -0000	1.9
+++ registry.h	18 May 2010 05:31:45 -0000
@@ -32,9 +32,9 @@
   HKEY get_key ();
 
   int get_int (const char *, int);
-  int get_int (const PWCHAR, int);
+  int get_int (const WCHAR *, int);
   int get_string (const char *, char *, size_t, const char *);
-  int get_string (const PWCHAR, PWCHAR, size_t, const PWCHAR);
+  int get_string (const WCHAR *, PWCHAR, size_t, const WCHAR *);
 
   int set_int (const char *, int);
   int set_int (const PWCHAR, int);
Index: spawn.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/spawn.cc,v
retrieving revision 1.290
diff -u -r1.290 spawn.cc
--- spawn.cc	27 Apr 2010 23:06:48 -0000	1.290
+++ spawn.cc	18 May 2010 05:31:46 -0000
@@ -692,8 +692,8 @@
       myself->dwProcessId = pi.dwProcessId;
       strace.execing = 1;
       myself.hProcess = hExeced = pi.hProcess;
-      strcpy (myself->progname, real_path.get_win32 ()); // FIXME: race?
-      sigproc_printf ("new process name %s", myself->progname);
+      wcscpy (myself->progname, real_path.get_nt_native_path ()->Buffer); // FIXME: race?
+      sigproc_printf ("new process name %S", myself->progname);
       /* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
 	 process.  So, we need to wait around until the process we've just "execed"
 	 dies.  Use our own wait facility to wait for our own pid to exit (there
@@ -733,7 +733,7 @@
       child->dwProcessId = pi.dwProcessId;
       child.hProcess = pi.hProcess;
 
-      strcpy (child->progname, real_path.get_win32 ());
+      wcscpy (child->progname, real_path.get_nt_native_path ()->Buffer);
       /* FIXME: This introduces an unreferenced, open handle into the child.
 	 The purpose is to keep the pid shared memory open so that all of
 	 the fields filled out by child.remember do not disappear and so there
Index: strace.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/strace.cc,v
retrieving revision 1.67
diff -u -r1.67 strace.cc
--- strace.cc	31 Mar 2010 18:06:02 -0000	1.67
+++ strace.cc	18 May 2010 05:31:46 -0000
@@ -52,11 +52,11 @@
 	__small_sprintf (pidbuf, "(pid %d, ppid %d)", myself->pid, myself->ppid ?: 1);
       else
 	{
-	  GetModuleFileName (NULL, myself->progname, sizeof (myself->progname));
+	  GetModuleFileNameW (NULL, myself->progname, sizeof (myself->progname));
 	  __small_sprintf (pidbuf, "(windows pid %d)", GetCurrentProcessId ());
 	}
       prntf (1, NULL, "**********************************************");
-      prntf (1, NULL, "Program name: %s %s", myself->progname, pidbuf);
+      prntf (1, NULL, "Program name: %W %s", myself->progname, pidbuf);
       prntf (1, NULL, "App version:  %d.%d, api: %d.%d",
 	     user_data->dll_major, user_data->dll_minor,
 	     user_data->api_major, user_data->api_minor);
@@ -135,7 +135,7 @@
   int microsec = microseconds ();
   lmicrosec = microsec;
 
-  __small_sprintf (fmt, "%7d [%s] %s ", microsec, tn, "%s %s%s");
+  __small_sprintf (fmt, "%7d [%s] %s ", microsec, tn, "%W %s%s");
 
   SetLastError (err);
 
@@ -143,34 +143,32 @@
     count = 0;
   else
     {
-      char *pn;
+      PWCHAR pn = NULL;
+      WCHAR progname[NT_MAX_PATH];
       if (!cygwin_finished_initializing)
-	pn = myself ? myself->progname : NULL;
+	pn = (myself) ? myself->progname : NULL;
       else if (__progname)
-	pn = __progname;
-      else
-	pn = NULL;
+	sys_mbstowcs(pn = progname, NT_MAX_PATH, __progname);
 
-      char *p;
-      char progname[NT_MAX_PATH];
+      PWCHAR p;
       if (!pn)
-	GetModuleFileName (NULL, pn = progname, sizeof (progname));
+	GetModuleFileNameW (NULL, pn = progname, sizeof (progname));
       if (!pn)
 	/* hmm */;
-      else if ((p = strrchr (pn, '\\')) != NULL)
+      else if ((p = wcsrchr (pn, L'\\')) != NULL)
 	p++;
-      else if ((p = strrchr (pn, '/')) != NULL)
+      else if ((p = wcsrchr (pn, L'/')) != NULL)
 	p++;
       else
 	p = pn;
       if (p != progname)
-	strcpy (progname, p);
-      if ((p = strrchr (progname, '.')) != NULL
-	  && ascii_strcasematch (p, ".exe"))
+	wcscpy (progname, p);
+      if ((p = wcsrchr (progname, '.')) != NULL
+	  && !wcscasecmp (p, L".exe"))
 	*p = '\000';
       p = progname;
       char tmpbuf[20];
-      count = __small_sprintf (buf, fmt, p && *p ? p : "?", mypid (tmpbuf),
+      count = __small_sprintf (buf, fmt, *p ? p : L"?", mypid (tmpbuf),
 			       execing ? "!" : "");
       if (func)
 	count += getfunc (buf + count, func);

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019