This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: vfork always fail problem


>>> 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@acm.org

2010-05-18  Kazuhiro Fujida  <fujieda@acm.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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]