Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-03-07 14:24:51 +0300
committerCorinna Vinschen <corinna@vinschen.de>2008-03-07 14:24:51 +0300
commit752b16ce359bb46948b8aa2bc88f7c32bf2cc95b (patch)
tree1ed3d9abb89e7e21ee47faf099632cf05b3a05be
parentd8e218442b004997287aaf202af88d9f1f86074e (diff)
* Makefile.in (DLL_OFILES): Add tls_pbuf.o.
* autoload.cc (CreateDesktopW): Replace CreateDesktopA. (CreateWindowStationW): Replace CreateWindowStationA. (GetUserObjectInformationW): Replace GetUserObjectInformationA. * cygheap.h (cwdstuff::get): Assume default buffer size NT_MAX_PATH. * cygtls.cc (_cygtls::remove): Free temporary TLS path buffers. * cygtls.h (TP_NUM_C_BUFS): Define. (TP_NUM_W_BUFS): Define. (class tls_pathbuf): New class to store pointers to thread local temporary path buffers. (_local_storage::pathbufs): New member. * environ.cc (win_env::add_cache): Use temporary TLS path buffer instead of stack based buffer. (posify): Get temporary outenv buffer from calling function. (environ_init): Create temporary TLS path buffer for posify. (build_env): Create Windows environment block as WCHAR buffer. * environ.h (build_env): Change declaration accordingly. * external.cc (sync_winenv): Accommodate build_env change. * fhandler_console.cc (fhandler_console::need_invisible): Use GetUserObjectInformationW and CreateWindowStationW. * fhandler_process.cc (format_process_maps): Use temporary TLS path buffer instead of stack based buffer. * fork.cc (frok::parent): Convert to use CreateProcessW. * path.cc: Throughout use temporary TLS path buffers instead of stack based buffer. Replace checks for CYG_MAX_PATH by checks for NT_MAX_PATH. (getfileattr): New function to replace GetFileAttributesA. (normalize_win32_path): Remove Win32 and NT long path prefixes. (getwd): Assume PATH_MAX + 1 buffer per SUSv3. * path.h (class path_conv): Set path buffer to size NT_MAX_PATH. (iswdrive): Define. * pinfo.cc (commune_process): Use temporary TLS path buffer instead of stack based buffer. * registry.cc (get_registry_hive_path): Ditto. (load_registry_hive): Ditto. * spawn.cc (spawn_guts): Convert to use CreateProcessW and CreateProcessAsUserW. (av::fixup): Open/close file using NtOpenFile/NtClose. * syscalls.cc (mknod_worker): Allow PATH_MAX file name. (mknod32): Ditto. (getusershell): Ditto. * tls_pbuf.cc: New file implementing tls_pathbuf and tmp_pathbuf methods. * tls_pbuf.h: New header for files using tmp_pathbuf. * tlsoffsets.h: Regenerate. * winsup.h (NT_MAX_PATH): Define as 32767 to avoid USHORT overflow.
-rw-r--r--winsup/cygwin/ChangeLog49
-rw-r--r--winsup/cygwin/Makefile.in4
-rw-r--r--winsup/cygwin/autoload.cc6
-rw-r--r--winsup/cygwin/cygheap.h2
-rw-r--r--winsup/cygwin/cygtls.cc3
-rw-r--r--winsup/cygwin/cygtls.h19
-rw-r--r--winsup/cygwin/environ.cc41
-rw-r--r--winsup/cygwin/environ.h2
-rw-r--r--winsup/cygwin/external.cc13
-rw-r--r--winsup/cygwin/fhandler_console.cc4
-rw-r--r--winsup/cygwin/fhandler_process.cc9
-rw-r--r--winsup/cygwin/fork.cc36
-rw-r--r--winsup/cygwin/path.cc151
-rw-r--r--winsup/cygwin/path.h3
-rw-r--r--winsup/cygwin/pinfo.cc4
-rw-r--r--winsup/cygwin/registry.cc9
-rw-r--r--winsup/cygwin/spawn.cc119
-rw-r--r--winsup/cygwin/syscalls.cc10
-rw-r--r--winsup/cygwin/tls_pbuf.cc60
-rw-r--r--winsup/cygwin/tls_pbuf.h20
-rw-r--r--winsup/cygwin/tlsoffsets.h98
-rw-r--r--winsup/cygwin/winsup.h10
22 files changed, 468 insertions, 204 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a7ae9e73f..dd795bd04 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,52 @@
+2008-03-07 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in (DLL_OFILES): Add tls_pbuf.o.
+ * autoload.cc (CreateDesktopW): Replace CreateDesktopA.
+ (CreateWindowStationW): Replace CreateWindowStationA.
+ (GetUserObjectInformationW): Replace GetUserObjectInformationA.
+ * cygheap.h (cwdstuff::get): Assume default buffer size NT_MAX_PATH.
+ * cygtls.cc (_cygtls::remove): Free temporary TLS path buffers.
+ * cygtls.h (TP_NUM_C_BUFS): Define.
+ (TP_NUM_W_BUFS): Define.
+ (class tls_pathbuf): New class to store pointers to thread local
+ temporary path buffers.
+ (_local_storage::pathbufs): New member.
+ * environ.cc (win_env::add_cache): Use temporary TLS path buffer instead
+ of stack based buffer.
+ (posify): Get temporary outenv buffer from calling function.
+ (environ_init): Create temporary TLS path buffer for posify.
+ (build_env): Create Windows environment block as WCHAR buffer.
+ * environ.h (build_env): Change declaration accordingly.
+ * external.cc (sync_winenv): Accommodate build_env change.
+ * fhandler_console.cc (fhandler_console::need_invisible): Use
+ GetUserObjectInformationW and CreateWindowStationW.
+ * fhandler_process.cc (format_process_maps): Use temporary TLS path
+ buffer instead of stack based buffer.
+ * fork.cc (frok::parent): Convert to use CreateProcessW.
+ * path.cc: Throughout use temporary TLS path buffers instead of stack
+ based buffer. Replace checks for CYG_MAX_PATH by checks for
+ NT_MAX_PATH.
+ (getfileattr): New function to replace GetFileAttributesA.
+ (normalize_win32_path): Remove Win32 and NT long path prefixes.
+ (getwd): Assume PATH_MAX + 1 buffer per SUSv3.
+ * path.h (class path_conv): Set path buffer to size NT_MAX_PATH.
+ (iswdrive): Define.
+ * pinfo.cc (commune_process): Use temporary TLS path buffer instead of
+ stack based buffer.
+ * registry.cc (get_registry_hive_path): Ditto.
+ (load_registry_hive): Ditto.
+ * spawn.cc (spawn_guts): Convert to use CreateProcessW and
+ CreateProcessAsUserW.
+ (av::fixup): Open/close file using NtOpenFile/NtClose.
+ * syscalls.cc (mknod_worker): Allow PATH_MAX file name.
+ (mknod32): Ditto.
+ (getusershell): Ditto.
+ * tls_pbuf.cc: New file implementing tls_pathbuf and tmp_pathbuf
+ methods.
+ * tls_pbuf.h: New header for files using tmp_pathbuf.
+ * tlsoffsets.h: Regenerate.
+ * winsup.h (NT_MAX_PATH): Define as 32767 to avoid USHORT overflow.
+
2008-03-06 Corinna Vinschen <corinna@vinschen.de>
* child_info.h (CURR_CHILD_INFO_MAGIC): Reset.
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 9586bfdd2..35dc66c28 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -143,8 +143,8 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \
select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \
spawn.o strace.o strfuncs.o strptime.o strsep.o strsig.o sync.o \
syscalls.o sysconf.o syslog.o termios.o thread.o timelocal.o timer.o \
- times.o tty.o uinfo.o uname.o v8_regexp.o v8_regerror.o v8_regsub.o \
- wait.o wincap.o window.o winf.o xsique.o \
+ times.o tls_pbuf.o tty.o uinfo.o uname.o v8_regexp.o v8_regerror.o \
+ v8_regsub.o wait.o wincap.o window.o winf.o xsique.o \
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS)
GMON_OFILES:=gmon.o mcount.o profil.o
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 24dea1f78..22b7b6f3e 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -324,9 +324,9 @@ LoadDLLfunc (CharNextExA, 12, user32)
LoadDLLfunc (CloseClipboard, 0, user32)
LoadDLLfunc (CloseDesktop, 4, user32)
LoadDLLfunc (CloseWindowStation, 4, user32)
-LoadDLLfunc (CreateDesktopA, 24, user32)
+LoadDLLfunc (CreateDesktopW, 24, user32)
LoadDLLfunc (CreateWindowExA, 48, user32)
-LoadDLLfunc (CreateWindowStationA, 16, user32)
+LoadDLLfunc (CreateWindowStationW, 16, user32)
LoadDLLfunc (DefWindowProcA, 16, user32)
LoadDLLfunc (DispatchMessageA, 4, user32)
LoadDLLfunc (EmptyClipboard, 0, user32)
@@ -339,7 +339,7 @@ LoadDLLfunc (GetPriorityClipboardFormat, 8, user32)
LoadDLLfunc (GetProcessWindowStation, 0, user32)
LoadDLLfunc (GetThreadDesktop, 4, user32)
LoadDLLfunc (GetWindowThreadProcessId, 8, user32)
-LoadDLLfunc (GetUserObjectInformationA, 20, user32)
+LoadDLLfunc (GetUserObjectInformationW, 20, user32)
LoadDLLfunc (MessageBeep, 4, user32)
LoadDLLfunc (MessageBoxA, 16, user32)
LoadDLLfunc (MsgWaitForMultipleObjects, 20, user32)
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 567aecf69..d1bc5cc8a 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -230,7 +230,7 @@ struct cwdstuff
HANDLE dir;
DWORD drive_length;
static muto cwd_lock;
- char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH);
+ char *get (char *, int = 1, int = 0, unsigned = NT_MAX_PATH);
HANDLE get_handle () { return dir; }
DWORD get_drive (char * dst)
{
diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc
index 0370d06e8..749af0158 100644
--- a/winsup/cygwin/cygtls.cc
+++ b/winsup/cygwin/cygtls.cc
@@ -171,6 +171,9 @@ _cygtls::remove (DWORD wait)
free_local (hostent_buf);
}
+ /* Free temporary TLS path buffers. */
+ locals.pathbufs.destroy ();
+
do
{
sentry here (wait);
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 14ccffd41..43bdfee6a 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -33,7 +33,23 @@ details. */
#include "cygthread.h"
+#define TP_NUM_C_BUFS 10
+#define TP_NUM_W_BUFS 10
+
#pragma pack(push,4)
+/* Defined here to support auto rebuild of tlsoffsets.h. */
+class tls_pathbuf
+{
+ int c_cnt;
+ int w_cnt;
+ char *c_buf[TP_NUM_C_BUFS];
+ WCHAR *w_buf[TP_NUM_W_BUFS];
+
+public:
+ void destroy ();
+ friend class tmp_pathbuf;
+};
+
struct _local_storage
{
/*
@@ -96,6 +112,9 @@ struct _local_storage
/* syscalls.cc */
int setmode_file;
int setmode_mode;
+
+ /* All functions requiring temporary path buffers. */
+ tls_pathbuf pathbufs;
};
typedef struct struct_waitq
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 7e1fafd4a..3a427bb06 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -13,6 +13,7 @@ details. */
#include <stddef.h>
#include <string.h>
#include <wchar.h>
+#include <wctype.h>
#include <ctype.h>
#include <assert.h>
#include <sys/cygwin.h>
@@ -27,6 +28,7 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "cygtls.h"
+#include "tls_pbuf.h"
#include "registry.h"
#include "environ.h"
#include "child_info.h"
@@ -117,7 +119,8 @@ win_env::add_cache (const char *in_posix, const char *in_native)
}
else
{
- char buf[NT_MAX_PATH];
+ tmp_pathbuf tp;
+ char *buf = tp.c_get ();
strcpy (buf, name + namelen);
towin32 (in_posix, buf);
native = (char *) realloc (native, namelen + 1 + strlen (buf));
@@ -173,7 +176,7 @@ getwinenv (const char *env, const char *in_posix, win_env *temp)
/* Convert windows path specs to POSIX, if appropriate.
*/
static void __stdcall
-posify (char **here, const char *value)
+posify (char **here, const char *value, char *outenv)
{
char *src = *here;
win_env *conv;
@@ -186,7 +189,6 @@ posify (char **here, const char *value)
/* Turn all the items from c:<foo>;<bar> into their
mounted equivalents - if there is one. */
- char outenv[1 + len + NT_MAX_PATH];
memcpy (outenv, src, len);
char *newvalue = outenv + len;
if (!conv->toposix (value, newvalue) || _impure_ptr->_errno != EIDRM)
@@ -740,6 +742,7 @@ environ_init (char **envp, int envc)
bool got_something_from_registry;
static char NO_COPY cygterm[] = "TERM=cygwin";
myfault efault;
+ tmp_pathbuf tp;
if (efault.faulted ())
api_fatal ("internal error reading the windows environment - too many environment variables?");
@@ -804,6 +807,7 @@ environ_init (char **envp, int envc)
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
eventually want to use them). */
+ char *tmpbuf = tp.t_get ();
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
{
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
@@ -820,7 +824,7 @@ environ_init (char **envp, int envc)
if (*newp == 'C' && strncmp (newp, "CYGWIN=", sizeof ("CYGWIN=") - 1) == 0)
parse_options (newp + sizeof ("CYGWIN=") - 1);
if (*eq && conv_start_chars[(unsigned char)envp[i][0]])
- posify (envp + i, *++eq ? eq : --eq);
+ posify (envp + i, *++eq ? eq : --eq, tmpbuf);
debug_printf ("%p: %s", envp[i], envp[i]);
}
@@ -957,7 +961,7 @@ spenv::retrieve (bool no_envblock, const char *const env)
Converts environment variables noted in conv_envvars into win32 form
prior to placing them in the string. */
char ** __stdcall
-build_env (const char * const *envp, char *&envblock, int &envc,
+build_env (const char * const *envp, PWCHAR &envblock, int &envc,
bool no_envblock)
{
int len, n;
@@ -1041,8 +1045,8 @@ build_env (const char * const *envp, char *&envblock, int &envc,
qsort (pass_env, pass_envc, sizeof (char *), env_sort);
/* Create an environment block suitable for passing to CreateProcess. */
- char *s;
- envblock = (char *) malloc (2 + tl);
+ PWCHAR s;
+ envblock = (PWCHAR) malloc ((2 + tl) * sizeof (WCHAR));
int new_tl = 0;
for (srcp = pass_env, s = envblock; *srcp; srcp++)
{
@@ -1067,20 +1071,14 @@ build_env (const char * const *envp, char *&envblock, int &envc,
p = *srcp; /* Don't worry about it */
len = strlen (p) + 1;
- if (len >= 32 * 1024)
- {
- free (envblock);
- envblock = NULL;
- goto out;
- }
new_tl += len; /* Keep running total of block length so far */
/* See if we need to increase the size of the block. */
if (new_tl > tl)
{
tl = new_tl + 100;
- char *new_envblock =
- (char *) realloc (envblock, 2 + tl);
+ PWCHAR new_envblock =
+ (PWCHAR) realloc (envblock, (2 + tl) * sizeof (WCHAR));
/* If realloc moves the block, move `s' with it. */
if (new_envblock != envblock)
{
@@ -1089,23 +1087,22 @@ build_env (const char * const *envp, char *&envblock, int &envc,
}
}
- memcpy (s, p, len);
+ int slen = sys_mbstowcs (s, len, p, len);
/* See if environment variable is "special" in a Windows sense.
Under NT, the current directories for visited drives are stored
as =C:=\bar. Cygwin converts the '=' to '!' for hopefully obvious
reasons. We need to convert it back when building the envblock */
- if (s[0] == '!' && (isdrive (s + 1) || (s[1] == ':' && s[2] == ':'))
- && s[3] == '=')
- *s = '=';
- s += len;
+ if (s[0] == L'!' && (iswdrive (s + 1) || (s[1] == L':' && s[2] == L':'))
+ && s[3] == L'=')
+ *s = L'=';
+ s += slen + 1;
}
- *s = '\0'; /* Two null bytes at the end */
+ *s = L'\0'; /* Two null bytes at the end */
assert ((s - envblock) <= tl); /* Detect if we somehow ran over end
of buffer */
}
-out:
debug_printf ("envp %p, envc %d", newenv, envc);
return newenv;
}
diff --git a/winsup/cygwin/environ.h b/winsup/cygwin/environ.h
index 84c88a3c9..c2c29cf9a 100644
--- a/winsup/cygwin/environ.h
+++ b/winsup/cygwin/environ.h
@@ -45,7 +45,7 @@ char * __stdcall getwinenveq (const char *name, size_t len, int)
void __stdcall update_envptrs ();
extern char **__cygwin_environ, ***main_environ;
extern "C" char __stdcall **cur_environ ();
-char ** __stdcall build_env (const char * const *envp, char *&envblock,
+char ** __stdcall build_env (const char * const *envp, PWCHAR &envblock,
int &envc, bool need_envblock)
__attribute__ ((regparm (3)));
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 111bd31c5..32492ba4d 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -32,6 +32,7 @@ details. */
#include "environ.h"
#include <unistd.h>
#include <stdlib.h>
+#include <wchar.h>
child_info *get_cygwin_startup_info ();
@@ -137,9 +138,9 @@ static void
sync_winenv ()
{
int unused_envc;
- char *envblock = NULL;
+ PWCHAR envblock = NULL;
char **envp = build_env (cur_environ (), envblock, unused_envc, false);
- char *p = envblock;
+ PWCHAR p = envblock;
if (envp)
{
@@ -151,14 +152,14 @@ sync_winenv ()
return;
while (*p)
{
- char *eq = strchr (p, '=');
+ PWCHAR eq = wcschr (p, L'=');
if (eq)
{
- *eq = '\0';
- SetEnvironmentVariable (p, ++eq);
+ *eq = L'\0';
+ SetEnvironmentVariableW (p, ++eq);
p = eq;
}
- p = strchr (p, '\0') + 1;
+ p = wcschr (p, L'\0') + 1;
}
free (envblock);
}
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index ca1c0879b..0a445aa2e 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -1919,7 +1919,7 @@ fhandler_console::need_invisible ()
USEROBJECTFLAGS oi;
DWORD len;
if (!horig
- || !GetUserObjectInformation (horig, UOI_FLAGS, &oi, sizeof (oi), &len)
+ || !GetUserObjectInformationW (horig, UOI_FLAGS, &oi, sizeof (oi), &len)
|| !(oi.dwFlags & WSF_VISIBLE))
{
b = true;
@@ -1930,7 +1930,7 @@ fhandler_console::need_invisible ()
{
if (myself->ctty != TTY_CONSOLE)
{
- h = CreateWindowStation (NULL, 0, WINSTA_ACCESS, NULL);
+ h = CreateWindowStationW (NULL, 0, WINSTA_ACCESS, NULL);
termios_printf ("%p = CreateWindowStation(NULL), %E", h);
if (h)
{
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index b32f83960..b5aa6dfb9 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -23,6 +23,7 @@ details. */
#include "cygheap.h"
#include "ntdll.h"
#include "cygtls.h"
+#include "tls_pbuf.h"
#include <sys/param.h>
#include <assert.h>
#include <sys/sysmacros.h>
@@ -525,8 +526,10 @@ format_process_maps (_pinfo *p, char *&destbuf, size_t maxsize)
DWORD_PTR wset_size;
DWORD_PTR *workingset = NULL;
MODULEINFO info;
- WCHAR modname[NT_MAX_PATH];
- char posix_modname[NT_MAX_PATH];
+
+ tmp_pathbuf tp;
+ PWCHAR modname = tp.w_get ();
+ char *posix_modname = tp.c_get ();
if (!EnumProcessModules (proc, NULL, 0, &needed))
{
@@ -552,7 +555,7 @@ format_process_maps (_pinfo *p, char *&destbuf, size_t maxsize)
}
for (i = 0; i < needed / sizeof (HMODULE); i++)
if (GetModuleInformation (proc, modules[i], &info, sizeof info)
- && GetModuleFileNameExW (proc, modules[i], modname, sizeof modname))
+ && GetModuleFileNameExW (proc, modules[i], modname, NT_MAX_PATH))
{
char access[5];
strcpy (access, "r--p");
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 730bc386c..923c1dccc 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -24,6 +24,7 @@ details. */
#include "cygheap.h"
#include "child_info.h"
#include "cygtls.h"
+#include "tls_pbuf.h"
#include "perprocess.h"
#include "dll_init.h"
#include "sync.h"
@@ -348,16 +349,21 @@ frok::parent (volatile char * volatile stack_here)
ch.stackbottom, ch.stacktop, ch.stacksize);
PROCESS_INFORMATION pi;
- STARTUPINFO si;
+ STARTUPINFOW si;
memset (&si, 0, sizeof (si));
- si.cb = sizeof (STARTUPINFO);
+ si.cb = sizeof si;
si.lpReserved2 = (LPBYTE) &ch;
si.cbReserved2 = sizeof (ch);
- syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %p, 0, 0, %p, %p)",
- myself->progname, myself->progname, c_flags, &si, &pi);
+ /* 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);
bool locked = __malloc_lock ();
time_t start_time = time (NULL);
@@ -367,21 +373,21 @@ frok::parent (volatile char * volatile stack_here)
while (1)
{
- rc = CreateProcess (myself->progname, /* image to run */
- myself->progname, /* what we send in arg0 */
- &sec_none_nih,
- &sec_none_nih,
- TRUE, /* inherit handles from parent */
- c_flags,
- NULL, /* environment filled in later */
- 0, /* use current drive/directory */
- &si,
- &pi);
+ rc = CreateProcessW (progname, /* image to run */
+ progname, /* what we send in arg0 */
+ &sec_none_nih,
+ &sec_none_nih,
+ TRUE, /* inherit handles from parent */
+ c_flags,
+ NULL, /* environment filled in later */
+ 0, /* use current drive/directory */
+ &si,
+ &pi);
if (!rc)
{
this_errno = geterrno_from_win_error ();
- error = "CreateProcessA failed";
+ error = "CreateProcessW failed";
memset (&pi, 0, sizeof (pi));
goto cleanup;
}
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 4c4ce2966..11d01bc47 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -76,6 +76,7 @@ details. */
#include "shared_info.h"
#include "registry.h"
#include "cygtls.h"
+#include "tls_pbuf.h"
#include "environ.h"
#include <assert.h>
#include <ntdll.h>
@@ -319,7 +320,7 @@ normalize_posix_path (const char *src, char *dst, char *&tail)
*tail++ = '/';
}
- if ((tail - dst) >= CYG_MAX_PATH)
+ if ((tail - dst) >= NT_MAX_PATH)
{
debug_printf ("ENAMETOOLONG = normalize_posix_path (%s)", src);
return ENAMETOOLONG;
@@ -355,7 +356,8 @@ static void __stdcall mkrelpath (char *dst) __attribute__ ((regparm (2)));
static void __stdcall
mkrelpath (char *path)
{
- char cwd_win32[CYG_MAX_PATH];
+ tmp_pathbuf tp;
+ char *cwd_win32 = tp.c_get ();
if (!cygheap->cwd.get (cwd_win32, 0))
return;
@@ -647,7 +649,8 @@ warn_msdos (const char *src)
{
if (user_shared->warned_msdos || !dos_file_warning)
return;
- char posix_path[CYG_MAX_PATH];
+ tmp_pathbuf tp;
+ char *posix_path = tp.c_get ();
small_printf ("cygwin warning:\n");
if (cygwin_conv_to_full_posix_path (src, posix_path))
small_printf (" MS-DOS style path detected: %s\n POSIX equivalent preferred.\n",
@@ -662,6 +665,56 @@ warn_msdos (const char *src)
user_shared->warned_msdos = true;
}
+static DWORD
+getfileattr (const char *path) /* path has to be always absolute. */
+{
+ tmp_pathbuf tp;
+ UNICODE_STRING upath;
+ OBJECT_ATTRIBUTES attr;
+ FILE_BASIC_INFORMATION fbi;
+ NTSTATUS status;
+ IO_STATUS_BLOCK io;
+
+ RtlInitEmptyUnicodeString (&upath, tp.w_get (), NT_MAX_PATH * sizeof (WCHAR));
+ InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
+ get_nt_native_path (path, upath);
+
+ status = NtQueryAttributesFile (&attr, &fbi);
+ if (NT_SUCCESS (status))
+ return fbi.FileAttributes;
+
+ if (status != STATUS_OBJECT_NAME_NOT_FOUND
+ && status != STATUS_NO_SUCH_FILE) /* File not found on 9x share */
+ {
+ /* File exists but access denied. Try to get attribute through
+ directory query. */
+ UNICODE_STRING dirname, basename;
+ HANDLE dir;
+ FILE_DIRECTORY_INFORMATION fdi;
+
+ RtlSplitUnicodePath (&upath, &dirname, &basename);
+ InitializeObjectAttributes (&attr, &dirname,
+ OBJ_CASE_INSENSITIVE, NULL, NULL);
+ status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
+ &attr, &io, FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_FOR_BACKUP_INTENT
+ | FILE_DIRECTORY_FILE);
+ if (NT_SUCCESS (status))
+ {
+ status = NtQueryDirectoryFile (dir, NULL, NULL, 0, &io,
+ &fdi, sizeof fdi,
+ FileDirectoryInformation,
+ TRUE, &basename, TRUE);
+ NtClose (dir);
+ if (NT_SUCCESS (status) || status == STATUS_BUFFER_OVERFLOW)
+ return fdi.FileAttributes;
+ }
+ }
+ SetLastError (RtlNtStatusToDosError (status));
+ return INVALID_FILE_ATTRIBUTES;
+}
+
/* Convert an arbitrary path SRC to a pure Win32 path, suitable for
passing to Win32 API routines.
@@ -685,10 +738,11 @@ void
path_conv::check (PUNICODE_STRING src, unsigned opt,
const suffix_info *suffixes)
{
- char path[CYG_MAX_PATH];
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
user_shared->warned_msdos = true;
- sys_wcstombs (path, CYG_MAX_PATH, src->Buffer, src->Length / 2);
+ sys_wcstombs (path, NT_MAX_PATH, src->Buffer, src->Length / 2);
path_conv::check (path, opt, suffixes);
}
@@ -696,11 +750,12 @@ void
path_conv::check (const char *src, unsigned opt,
const suffix_info *suffixes)
{
- /* This array is used when expanding symlinks. It is CYG_MAX_PATH * 2
- in length so that we can hold the expanded symlink plus a
- trailer. */
- char path_copy[CYG_MAX_PATH + 3];
- char tmp_buf[2 * CYG_MAX_PATH + 3];
+ /* The tmp_buf array is used when expanding symlinks. It is NT_MAX_PATH * 2
+ in length so that we can hold the expanded symlink plus a trailer. */
+ tmp_pathbuf tp;
+ char *path_copy = tp.c_get ();
+ char *pathbuf = tp.c_get ();
+ char *tmp_buf = tp.t_get ();
symlink_info sym;
bool need_directory = 0;
bool saw_symlinks = 0;
@@ -785,7 +840,6 @@ path_conv::check (const char *src, unsigned opt,
for (unsigned pflags_or = opt & PC_NO_ACCESS_CHECK; ; pflags_or = 0)
{
const suffix_info *suff;
- char pathbuf[CYG_MAX_PATH];
char *full_path;
/* Don't allow symlink.check to set anything in the path_conv
@@ -818,7 +872,7 @@ path_conv::check (const char *src, unsigned opt,
fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY;
else
{
- fileattr = GetFileAttributes (this->path);
+ fileattr = getfileattr (this->path);
dev.devn = FH_FS;
}
goto out;
@@ -827,7 +881,7 @@ path_conv::check (const char *src, unsigned opt,
{
dev.devn = FH_FS;
#if 0
- fileattr = GetFileAttributes (this->path);
+ fileattr = getfileattr (this->path);
if (!component && fileattr == INVALID_FILE_ATTRIBUTES)
{
fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY;
@@ -1050,7 +1104,7 @@ virtual_component_retry:
}
/* Make sure there is enough space */
- if (headptr + symlen >= tmp_buf + sizeof (tmp_buf))
+ if (headptr + symlen >= tmp_buf + (2 * NT_MAX_PATH))
{
too_long:
error = ENAMETOOLONG;
@@ -1071,7 +1125,7 @@ virtual_component_retry:
if (*(headptr - 1) != '/')
*headptr++ = '/';
int taillen = path_end - tail + 1;
- if (headptr + taillen > tmp_buf + sizeof (tmp_buf))
+ if (headptr + taillen > tmp_buf + (2 * NT_MAX_PATH))
goto too_long;
memcpy (headptr, tail, taillen);
}
@@ -1239,11 +1293,12 @@ path_conv::~path_conv ()
bool
path_conv::is_binary ()
{
+ tmp_pathbuf tp;
+ PWCHAR bintest = tp.w_get ();
DWORD bin;
- PBYTE bintest[get_nt_native_path ()->Length + sizeof (WCHAR)];
return exec_state () == is_executable
&& RtlEqualUnicodePathSuffix (get_nt_native_path (), L".exe", TRUE)
- && GetBinaryTypeW (get_wide_win32_path ((PWCHAR) bintest), &bin);
+ && GetBinaryTypeW (get_wide_win32_path (bintest), &bin);
}
/* Return true if src_path is a valid, internally supported device name.
@@ -1286,6 +1341,19 @@ normalize_win32_path (const char *src, char *dst, char *&tail)
bool beg_src_slash = isdirsep (src[0]);
tail = dst;
+ /* Skip long path name prefixes in Win32 or NT syntax. */
+ if (beg_src_slash && (src[1] == '?' || isdirsep (src[1]))
+ && src[2] == '?' && isdirsep (src[3]))
+ {
+ src += 4;
+ if (ascii_strncasematch (src, "UNC", 3))
+ {
+ src += 2; /* Fortunately the first char is not copied... */
+ beg_src_slash = true;
+ }
+ else
+ beg_src_slash = isdirsep (src[0]);
+ }
if (beg_src_slash && isdirsep (src[1]))
{
if (isdirsep (src[2]))
@@ -1360,7 +1428,7 @@ normalize_win32_path (const char *src, char *dst, char *&tail)
*tail++ = *src;
src++;
}
- if ((tail - dst) >= CYG_MAX_PATH)
+ if ((tail - dst) >= NT_MAX_PATH)
return ENAMETOOLONG;
}
if (tail > dst + 1 && tail[-1] == '.' && tail[-2] == '\\')
@@ -1463,7 +1531,7 @@ conv_path_list (const char *src, char *dst, int to_posix)
{
char *s = strccpy (srcbuf, &src, src_delim);
int len = s - srcbuf;
- if (len >= CYG_MAX_PATH)
+ if (len >= NT_MAX_PATH)
{
err = ENAMETOOLONG;
break;
@@ -1704,14 +1772,14 @@ mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigne
dst[n++] = '\\';
if (!*p || !(flags & MOUNT_ENC))
{
- if ((n + strlen (p)) >= CYG_MAX_PATH)
+ if ((n + strlen (p)) >= NT_MAX_PATH)
err = ENAMETOOLONG;
else
backslashify (p, dst + n, 0);
}
else
{
- int left = CYG_MAX_PATH - n;
+ int left = NT_MAX_PATH - n;
while (*p)
{
char slash = 0;
@@ -1743,7 +1811,7 @@ mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigne
The result is zero for success, or an errno value.
- {,full_}win32_path must have sufficient space (i.e. CYG_MAX_PATH bytes). */
+ {,full_}win32_path must have sufficient space (i.e. NT_MAX_PATH bytes). */
int
mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
@@ -1983,7 +2051,7 @@ mount_info::cygdrive_win32_path (const char *src, char *dst, int& unit)
/* conv_to_posix_path: Ensure src_path is a POSIX path.
The result is zero for success, or an errno value.
- posix_path must have sufficient space (i.e. CYG_MAX_PATH bytes).
+ posix_path must have sufficient space (i.e. NT_MAX_PATH bytes).
If keep_rel_p is non-zero, relative paths stay that way. */
/* TODO: Change conv_to_posix_path to work with native paths. */
@@ -2004,7 +2072,8 @@ mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
changed = true;
}
}
- char buf[NT_MAX_PATH];
+ tmp_pathbuf tp;
+ char *buf = tp.c_get ();
sys_wcstombs (buf, NT_MAX_PATH, src_path);
int ret = conv_to_posix_path (buf, posix_path, keep_rel_p);
if (changed)
@@ -2033,7 +2102,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
trailing_slash_p ? "add-slash" : "no-add-slash");
MALLOC_CHECK;
- if (src_path_len >= CYG_MAX_PATH)
+ if (src_path_len >= NT_MAX_PATH)
{
debug_printf ("ENAMETOOLONG");
return ENAMETOOLONG;
@@ -2049,7 +2118,8 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
return 0;
}
- char pathbuf[CYG_MAX_PATH];
+ tmp_pathbuf tp;
+ char *pathbuf = tp.c_get ();
char *tail;
int rc = normalize_win32_path (src_path, pathbuf, tail);
if (rc != 0)
@@ -2059,6 +2129,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
}
int pathbuflen = tail - pathbuf;
+ char *tmpbuf = tp.c_get ();
for (int i = 0; i < nmounts; ++i)
{
mount_item &mi = mount[native_sorted[i]];
@@ -2080,7 +2151,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
nextchar = 1;
int addslash = nextchar > 0 ? 1 : 0;
- if ((mi.posix_pathlen + (pathbuflen - mi.native_pathlen) + addslash) >= CYG_MAX_PATH)
+ if ((mi.posix_pathlen + (pathbuflen - mi.native_pathlen) + addslash) >= NT_MAX_PATH)
return ENAMETOOLONG;
strcpy (posix_path, mi.posix_path);
if (addslash)
@@ -2097,7 +2168,6 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
}
if (mi.flags & MOUNT_ENC)
{
- char tmpbuf[CYG_MAX_PATH];
if (fnunmunge (tmpbuf, posix_path))
strcpy (posix_path, tmpbuf);
}
@@ -2161,6 +2231,10 @@ mount_info::set_flags_from_win32_path (const char *p)
void
mount_info::read_mounts (reg_key& r)
{
+ tmp_pathbuf tp;
+ char *native_path = tp.c_get ();
+ /* FIXME: The POSIX path is stored as value name right now, which is
+ restricted to 256 bytes. */
char posix_path[CYG_MAX_PATH];
HKEY key = r.get_key ();
DWORD i, posix_path_size;
@@ -2172,7 +2246,6 @@ mount_info::read_mounts (reg_key& r)
arbitrarily large number of mounts. */
for (i = 0; ; i++)
{
- char native_path[CYG_MAX_PATH];
int mount_flags;
posix_path_size = sizeof (posix_path);
@@ -2194,7 +2267,7 @@ mount_info::read_mounts (reg_key& r)
reg_key subkey = reg_key (key, KEY_READ, posix_path, NULL);
/* Fetch info from the subkey. */
- subkey.get_string ("native", native_path, sizeof (native_path), "");
+ subkey.get_string ("native", native_path, NT_MAX_PATH, "");
mount_flags = subkey.get_int ("flags", 0);
/* Add mount_item corresponding to registry mount point. */
@@ -2533,7 +2606,10 @@ mount_info::sort ()
int
mount_info::add_item (const char *native, const char *posix, unsigned mountflags, int reg_p)
{
- char nativetmp[CYG_MAX_PATH];
+ tmp_pathbuf tp;
+ char *nativetmp = tp.c_get ();
+ /* FIXME: The POSIX path is stored as value name right now, which is
+ restricted to 256 bytes. */
char posixtmp[CYG_MAX_PATH];
char *nativetail, *posixtail, error[] = "error";
int nativeerr, posixerr;
@@ -2607,7 +2683,8 @@ mount_info::add_item (const char *native, const char *posix, unsigned mountflags
int
mount_info::del_item (const char *path, unsigned flags, int reg_p)
{
- char pathtmp[CYG_MAX_PATH];
+ tmp_pathbuf tp;
+ char *pathtmp = tp.c_get ();
int posix_path_p = false;
/* Something's wrong if path is NULL or empty. */
@@ -3969,11 +4046,11 @@ getcwd (char *buf, size_t ulen)
return res;
}
-/* getwd: standards? */
+/* getwd: Legacy. */
extern "C" char *
getwd (char *buf)
{
- return getcwd (buf, CYG_MAX_PATH);
+ return getcwd (buf, PATH_MAX + 1); /*Per SuSv3!*/
}
/* chdir: POSIX 5.2.1.1 */
@@ -4558,9 +4635,10 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
else
drive_length = 0;
+ tmp_pathbuf tp;
if (!posix_cwd)
{
- posix_cwd = (const char *) alloca (NT_MAX_PATH);
+ posix_cwd = (const char *) tp.c_get ();
mount_table->conv_to_posix_path (win32.Buffer, (char *) posix_cwd, 0);
}
posix = (char *) crealloc_abort (posix, strlen (posix_cwd) + 1);
@@ -4578,6 +4656,7 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
{
MALLOC_CHECK;
+ tmp_pathbuf tp;
if (ulen)
/* nothing */;
else if (buf == NULL)
@@ -4593,7 +4672,7 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
char *tocopy;
if (!need_posix)
{
- tocopy = (char *) alloca (NT_MAX_PATH);
+ tocopy = tp.c_get ();
sys_wcstombs (tocopy, NT_MAX_PATH, win32.Buffer, win32.Length);
}
else
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index a19f382bc..268a1a5f1 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -283,7 +283,7 @@ class path_conv
DWORD get_symlink_length () { return symlink_length; };
private:
DWORD symlink_length;
- char path[CYG_MAX_PATH];
+ char path[NT_MAX_PATH];
};
/* Symlink marker */
@@ -310,6 +310,7 @@ const char * __stdcall find_exec (const char *name, path_conv& buf,
/* Common macros for checking for invalid path names */
#define isdrive(s) (isalpha (*(s)) && (s)[1] == ':')
+#define iswdrive(s) (iswalpha (*(s)) && (s)[1] == L':')
static inline bool
has_exec_chars (const char *buf, int len)
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 632cc5f71..85fdf9b37 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -33,6 +33,7 @@ details. */
#include "fhandler.h"
#include "cygmalloc.h"
#include "cygtls.h"
+#include "tls_pbuf.h"
#include "child_info.h"
static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
@@ -392,7 +393,8 @@ DWORD WINAPI
commune_process (void *arg)
{
siginfo_t& si = *((siginfo_t *) arg);
- char path[NT_MAX_PATH];
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
DWORD nr;
HANDLE& tothem = si._si_commune._si_write_handle;
HANDLE process_sync =
diff --git a/winsup/cygwin/registry.cc b/winsup/cygwin/registry.cc
index 8316551a5..ce0987502 100644
--- a/winsup/cygwin/registry.cc
+++ b/winsup/cygwin/registry.cc
@@ -19,6 +19,7 @@ details. */
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
+#include "tls_pbuf.h"
#include <wchar.h>
static const char cygnus_class[] = "cygnus";
@@ -220,12 +221,13 @@ get_registry_hive_path (const PWCHAR name, PWCHAR path)
wcpcpy (kend, name);
if (!RegOpenKeyExW (HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hkey))
{
- WCHAR buf[NT_MAX_PATH];
+ tmp_pathbuf tp;
+ PWCHAR buf = tp.w_get ();
DWORD type, siz;
path[0] = L'\0';
if (!RegQueryValueExW (hkey, L"ProfileImagePath", 0, &type,
- (BYTE *)buf, (siz = sizeof (buf), &siz)))
+ (BYTE *)buf, (siz = NT_MAX_PATH, &siz)))
ExpandEnvironmentStringsW (buf, path, NT_MAX_PATH);
RegCloseKey (hkey);
if (path[0])
@@ -238,7 +240,8 @@ get_registry_hive_path (const PWCHAR name, PWCHAR path)
void
load_registry_hive (const PWCHAR name)
{
- WCHAR path[NT_MAX_PATH];
+ tmp_pathbuf tp;
+ PWCHAR path = tp.w_get ();
HKEY hkey;
LONG ret;
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index e016f1797..4ea04d934 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -18,6 +18,7 @@ details. */
#include <limits.h>
#include <wingdi.h>
#include <winuser.h>
+#include <wchar.h>
#include <ctype.h>
#include "cygerrno.h"
#include <sys/cygwin.h>
@@ -33,6 +34,7 @@ details. */
#include "registry.h"
#include "environ.h"
#include "cygtls.h"
+#include "tls_pbuf.h"
#include "winf.h"
#include "ntdll.h"
@@ -301,18 +303,19 @@ spawn_guts (const char * prog_arg, const char *const *argv,
av newargv;
linebuf one_line;
child_info_spawn ch;
- char *envblock = NULL;
+ PWCHAR envblock = NULL;
path_conv real_path;
bool reset_sendsig = false;
- const char *runpath;
+ tmp_pathbuf tp;
+ PWCHAR runpath = tp.w_get ();
int c_flags;
bool wascygexec;
cygheap_exec_info *moreinfo;
bool null_app_name = false;
- STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
- NULL, NULL, NULL};
+ STARTUPINFOW si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
+ NULL, NULL, NULL};
int looped = 0;
HANDLE orig_wr_proc_pipe = NULL;
@@ -333,7 +336,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
else
chtype = PROC_EXEC;
- moreinfo = (cygheap_exec_info *) ccalloc_abort (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
+ moreinfo = (cygheap_exec_info *) ccalloc_abort (HEAP_1_EXEC, 1,
+ sizeof (cygheap_exec_info));
moreinfo->old_title = NULL;
/* CreateProcess takes one long string that is the command line (sigh).
@@ -382,7 +386,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
{
if (wascygexec)
newargv.dup_all ();
- else if (!one_line.fromargv (newargv, real_path.get_win32 (), real_path.iscygexec ()))
+ else if (!one_line.fromargv (newargv, real_path.get_win32 (),
+ real_path.iscygexec ()))
{
res = -1;
goto out;
@@ -395,12 +400,14 @@ spawn_guts (const char * prog_arg, const char *const *argv,
if (mode != _P_OVERLAY ||
!DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
- &moreinfo->myself_pinfo, 0,
- TRUE, DUPLICATE_SAME_ACCESS))
+ &moreinfo->myself_pinfo, 0, TRUE,
+ DUPLICATE_SAME_ACCESS))
moreinfo->myself_pinfo = NULL;
else
VerifyHandle (moreinfo->myself_pinfo);
}
+ WCHAR wone_line[one_line.ix + 1];
+ sys_mbstowcs (wone_line, one_line.ix + 1, one_line.buf);
PROCESS_INFORMATION pi;
pi.hProcess = pi.hThread = NULL;
@@ -418,7 +425,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
c_flags = GetPriorityClass (hMainProc);
sigproc_printf ("priority class %d", c_flags);
- c_flags |= CREATE_SEPARATE_WOW_VDM;
+ c_flags |= CREATE_SEPARATE_WOW_VDM | CREATE_UNICODE_ENVIRONMENT;
if (mode == _P_DETACH)
c_flags |= DETACHED_PROCESS;
@@ -444,8 +451,9 @@ spawn_guts (const char * prog_arg, const char *const *argv,
generating its own pids again? */
if (cygheap->pid_handle)
/* already done previously */;
- else if (DuplicateHandle (hMainProc, hMainProc, hMainProc, &cygheap->pid_handle,
- PROCESS_QUERY_INFORMATION, TRUE, 0))
+ else if (DuplicateHandle (hMainProc, hMainProc, hMainProc,
+ &cygheap->pid_handle, PROCESS_QUERY_INFORMATION,
+ TRUE, 0))
ProtectHandleINH (cygheap->pid_handle);
else
system_printf ("duplicate to pid_handle failed, %E");
@@ -456,19 +464,22 @@ spawn_guts (const char * prog_arg, const char *const *argv,
So we have to start the child in suspend state, unfortunately, to avoid
a race condition. */
if (!newargv.win16_exe
- && (!ch.iscygwin () || mode != _P_OVERLAY || cygheap->fdtab.need_fixup_before ()))
+ && (!ch.iscygwin () || mode != _P_OVERLAY
+ || cygheap->fdtab.need_fixup_before ()))
c_flags |= CREATE_SUSPENDED;
- runpath = null_app_name ? NULL : real_path.get_win32 ();
+ runpath = null_app_name ? NULL : real_path.get_wide_win32_path (runpath);
- syscall_printf ("null_app_name %d (%s, %.9500s)", null_app_name, runpath, one_line.buf);
+ syscall_printf ("null_app_name %d (%W, %.9500W)", null_app_name,
+ runpath, wone_line);
cygbench ("spawn-guts");
if (!real_path.iscygexec())
cygheap->fdtab.set_file_pointers_for_exec ();
- moreinfo->envp = build_env (envp, envblock, moreinfo->envc, real_path.iscygexec ());
+ moreinfo->envp = build_env (envp, envblock, moreinfo->envc,
+ real_path.iscygexec ());
if (!moreinfo->envp || !envblock)
{
set_errno (E2BIG);
@@ -496,16 +507,16 @@ loop:
&& cygheap->user.saved_gid == cygheap->user.real_gid
&& !cygheap->user.groups.issetgroups ()))
{
- rc = CreateProcess (runpath, /* image name - with full path */
- one_line.buf, /* what was passed to exec */
- &sec_none_nih,/* process security attrs */
- &sec_none_nih,/* thread security attrs */
- TRUE, /* inherit handles from parent */
- c_flags,
- envblock, /* environment */
- NULL,
- &si,
- &pi);
+ rc = CreateProcessW (runpath, /* image name - with full path */
+ wone_line, /* what was passed to exec */
+ &sec_none_nih, /* process security attrs */
+ &sec_none_nih, /* thread security attrs */
+ TRUE, /* inherit handles from parent */
+ c_flags,
+ envblock, /* environment */
+ NULL,
+ &si,
+ &pi);
}
else
{
@@ -513,7 +524,7 @@ loop:
if (mode == _P_OVERLAY)
myself.set_acl();
- char wstname[1024] = { '\0' };
+ WCHAR wstname[1024] = { L'\0' };
HWINSTA hwst_orig = NULL, hwst = NULL;
HDESK hdsk_orig = NULL, hdsk = NULL;
PSECURITY_ATTRIBUTES sa;
@@ -521,16 +532,16 @@ loop:
hwst_orig = GetProcessWindowStation ();
hdsk_orig = GetThreadDesktop (GetCurrentThreadId ());
- GetUserObjectInformation (hwst_orig, UOI_NAME, wstname, 1024, &n);
+ GetUserObjectInformationW (hwst_orig, UOI_NAME, wstname, 1024, &n);
/* Prior to Vista it was possible to start a service with the
"Interact with desktop" flag. This started the service in the
interactive window station of the console. A big security
risk, but we don't want to disable this behaviour for older
OSes because it's still heavily used by some users. They have
been warned. */
- if (!ascii_strcasematch (wstname, "WinSta0"))
+ if (wcscasecmp (wstname, L"WinSta0") != 0)
{
- char sid[128];
+ WCHAR sid[128];
sa = sec_user ((PSECURITY_ATTRIBUTES) alloca (1024),
cygheap->user.sid ());
@@ -540,34 +551,34 @@ loop:
make sense in terms of security to create a new window
station for every logon of the same user. It just fills up
the system with window stations for no good reason. */
- hwst = CreateWindowStationA (cygheap->user.get_windows_id (sid), 0,
+ hwst = CreateWindowStationW (cygheap->user.get_windows_id (sid), 0,
GENERIC_READ | GENERIC_WRITE, sa);
if (!hwst)
system_printf ("CreateWindowStation failed, %E");
else if (!SetProcessWindowStation (hwst))
system_printf ("SetProcessWindowStation failed, %E");
- else if (!(hdsk = CreateDesktopA ("Default", NULL, NULL, 0,
+ else if (!(hdsk = CreateDesktopW (L"Default", NULL, NULL, 0,
GENERIC_ALL, sa)))
system_printf ("CreateDesktop failed, %E");
else
{
- stpcpy (stpcpy (wstname, sid), "\\Default");
+ wcpcpy (wcpcpy (wstname, sid), L"\\Default");
si.lpDesktop = wstname;
- debug_printf ("Desktop: %s", si.lpDesktop);
+ debug_printf ("Desktop: %W", si.lpDesktop);
}
}
- rc = CreateProcessAsUser (cygheap->user.primary_token (),
- runpath, /* image name - with full path */
- one_line.buf, /* what was passed to exec */
- &sec_none_nih, /* process security attrs */
- &sec_none_nih, /* thread security attrs */
- TRUE, /* inherit handles from parent */
- c_flags,
- envblock, /* environment */
- NULL,
- &si,
- &pi);
+ rc = CreateProcessAsUserW (cygheap->user.primary_token (),
+ runpath, /* image name - with full path */
+ wone_line, /* what was passed to exec */
+ &sec_none_nih, /* process security attrs */
+ &sec_none_nih, /* thread security attrs */
+ TRUE, /* inherit handles from parent */
+ c_flags,
+ envblock, /* environment */
+ NULL,
+ &si,
+ &pi);
if (hwst)
{
SetProcessWindowStation (hwst_orig);
@@ -952,16 +963,22 @@ av::fixup (const char *prog_arg, path_conv& real_path, const char *ext)
char *pgm = NULL;
char *arg1 = NULL;
char *ptr, *buf;
-
- HANDLE h = CreateFile (real_path.get_win32 (), GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_none_nih, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, 0);
- if (h == INVALID_HANDLE_VALUE)
+ OBJECT_ATTRIBUTES attr;
+ IO_STATUS_BLOCK io;
+ HANDLE h;
+ NTSTATUS status;
+
+ status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
+ real_path.get_object_attr (attr, sec_none_nih),
+ &io, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_FOR_BACKUP_INTENT
+ | FILE_NON_DIRECTORY_FILE);
+ if (!NT_SUCCESS (status))
goto err;
HANDLE hm = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY, 0, 0, NULL);
- CloseHandle (h);
+ NtClose (h);
if (!hm)
{
/* ERROR_FILE_INVALID indicates very likely an empty file. */
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index d18cf98fa..bc472322e 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -2336,7 +2336,7 @@ static int __stdcall
mknod_worker (const char *path, mode_t type, mode_t mode, _major_t major,
_minor_t minor)
{
- char buf[sizeof (":\\00000000:00000000:00000000") + CYG_MAX_PATH];
+ char buf[sizeof (":\\00000000:00000000:00000000") + PATH_MAX];
sprintf (buf, ":\\%x:%x:%x", major, minor,
type | (mode & (S_IRWXU | S_IRWXG | S_IRWXO)));
return symlink_worker (buf, path, true, true);
@@ -2354,7 +2354,7 @@ mknod32 (const char *path, mode_t mode, __dev32_t dev)
return -1;
}
- if (strlen (path) >= CYG_MAX_PATH)
+ if (strlen (path) >= PATH_MAX)
return -1;
path_conv w32path (path, PC_SYM_NOFOLLOW);
@@ -3327,7 +3327,7 @@ getusershell ()
"/usr/bin/csh",
NULL
};
- static char buf[CYG_MAX_PATH];
+ static char buf[PATH_MAX];
int ch, buf_idx;
if (!shell_fp && !(shell_fp = fopen64 (ETC_SHELLS, "rt")))
@@ -3342,11 +3342,11 @@ getusershell ()
/* Get each non-whitespace character as part of the shell path as long as
it fits in buf. */
for (buf_idx = 0;
- ch != EOF && !isspace (ch) && buf_idx < CYG_MAX_PATH;
+ ch != EOF && !isspace (ch) && buf_idx < PATH_MAX;
buf_idx++, ch = getc (shell_fp))
buf[buf_idx] = ch;
/* Skip any trailing non-whitespace character not fitting in buf. If the
- path is longer than CYG_MAX_PATH, it's invalid anyway. */
+ path is longer than PATH_MAX, it's invalid anyway. */
while (ch != EOF && !isspace (ch))
ch = getc (shell_fp);
if (buf_idx)
diff --git a/winsup/cygwin/tls_pbuf.cc b/winsup/cygwin/tls_pbuf.cc
new file mode 100644
index 000000000..704f3bfc9
--- /dev/null
+++ b/winsup/cygwin/tls_pbuf.cc
@@ -0,0 +1,60 @@
+/* tls_pbuf.cc
+
+ Copyright 2008 Red Hat, Inc.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include <winsup.h>
+#include <malloc.h>
+#include "thread.h"
+#include "cygtls.h"
+#include "tls_pbuf.h"
+
+#define tls_pbuf _my_tls.locals.pathbufs
+
+void
+tls_pathbuf::destroy ()
+{
+ for (int i = 0; i < TP_NUM_C_BUFS; ++i)
+ if (c_buf[i])
+ free (c_buf[i]);
+ for (int i = 0; i < TP_NUM_W_BUFS; ++i)
+ if (w_buf[i])
+ free (w_buf[i]);
+}
+
+tmp_pathbuf::tmp_pathbuf ()
+: c_buf_old (tls_pbuf.c_cnt),
+ w_buf_old (tls_pbuf.w_cnt)
+{}
+
+tmp_pathbuf::~tmp_pathbuf ()
+{
+ tls_pbuf.c_cnt = c_buf_old;
+ tls_pbuf.w_cnt = w_buf_old;
+}
+
+char *
+tmp_pathbuf::c_get ()
+{
+ if (tls_pbuf.c_cnt >= TP_NUM_C_BUFS)
+ api_fatal ("Internal error: TP_NUM_C_BUFS too small.");
+ if (!tls_pbuf.c_buf[tls_pbuf.c_cnt]
+ && !(tls_pbuf.c_buf[tls_pbuf.c_cnt] = (char *) malloc (NT_MAX_PATH)))
+ api_fatal ("Internal error: Out of memory for new path buf.");
+ return tls_pbuf.c_buf[tls_pbuf.c_cnt++];
+}
+
+PWCHAR
+tmp_pathbuf::w_get ()
+{
+ if (tls_pbuf.w_cnt >= TP_NUM_W_BUFS)
+ api_fatal ("Internal error: TP_NUM_W_BUFS too small.");
+ if (!tls_pbuf.w_buf[tls_pbuf.w_cnt]
+ && !(tls_pbuf.w_buf[tls_pbuf.w_cnt]
+ = (PWCHAR) malloc (NT_MAX_PATH * sizeof (WCHAR))))
+ api_fatal ("Internal error: Out of memory for new wide path buf.");
+ return tls_pbuf.w_buf[tls_pbuf.w_cnt++];
+}
diff --git a/winsup/cygwin/tls_pbuf.h b/winsup/cygwin/tls_pbuf.h
new file mode 100644
index 000000000..b4a2a7a37
--- /dev/null
+++ b/winsup/cygwin/tls_pbuf.h
@@ -0,0 +1,20 @@
+/* tls_pbuf.h
+
+ Copyright 2008 Red Hat, Inc.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+class tmp_pathbuf
+{
+ int c_buf_old;
+ int w_buf_old;
+public:
+ tmp_pathbuf ();
+ ~tmp_pathbuf ();
+
+ char *c_get (); /* Create temporary TLS path buf of size NT_MAX_PATH. */
+ PWCHAR w_get (); /* Create temporary TLS path buf of size 2 * NT_MAX_PATH. */
+ inline char *t_get () { return (char *) w_get (); }
+};
diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h
index 5fa884ecb..c82520112 100644
--- a/winsup/cygwin/tlsoffsets.h
+++ b/winsup/cygwin/tlsoffsets.h
@@ -1,6 +1,6 @@
//;# autogenerated: Do not edit.
-//; $tls::sizeof__cygtls = 4196;
+//; $tls::sizeof__cygtls = 4284;
//; $tls::func = -12700;
//; $tls::pfunc = 0;
//; $tls::el = -12696;
@@ -39,30 +39,30 @@
//; $tls::p__dontuse = 420;
//; $tls::locals = -11216;
//; $tls::plocals = 1484;
-//; $tls::_ctinfo = -9600;
-//; $tls::p_ctinfo = 3100;
-//; $tls::andreas = -9596;
-//; $tls::pandreas = 3104;
-//; $tls::wq = -9588;
-//; $tls::pwq = 3112;
-//; $tls::prev = -9560;
-//; $tls::pprev = 3140;
-//; $tls::next = -9556;
-//; $tls::pnext = 3144;
-//; $tls::sig = -9552;
-//; $tls::psig = 3148;
-//; $tls::incyg = -9548;
-//; $tls::pincyg = 3152;
-//; $tls::spinning = -9544;
-//; $tls::pspinning = 3156;
-//; $tls::stacklock = -9540;
-//; $tls::pstacklock = 3160;
-//; $tls::stackptr = -9536;
-//; $tls::pstackptr = 3164;
-//; $tls::stack = -9532;
-//; $tls::pstack = 3168;
-//; $tls::initialized = -8508;
-//; $tls::pinitialized = 4192;
+//; $tls::_ctinfo = -9512;
+//; $tls::p_ctinfo = 3188;
+//; $tls::andreas = -9508;
+//; $tls::pandreas = 3192;
+//; $tls::wq = -9500;
+//; $tls::pwq = 3200;
+//; $tls::prev = -9472;
+//; $tls::pprev = 3228;
+//; $tls::next = -9468;
+//; $tls::pnext = 3232;
+//; $tls::sig = -9464;
+//; $tls::psig = 3236;
+//; $tls::incyg = -9460;
+//; $tls::pincyg = 3240;
+//; $tls::spinning = -9456;
+//; $tls::pspinning = 3244;
+//; $tls::stacklock = -9452;
+//; $tls::pstacklock = 3248;
+//; $tls::stackptr = -9448;
+//; $tls::pstackptr = 3252;
+//; $tls::stack = -9444;
+//; $tls::pstack = 3256;
+//; $tls::initialized = -8420;
+//; $tls::pinitialized = 4280;
//; __DATA__
#define tls_func (-12700)
@@ -103,27 +103,27 @@
#define tls_p__dontuse (420)
#define tls_locals (-11216)
#define tls_plocals (1484)
-#define tls__ctinfo (-9600)
-#define tls_p_ctinfo (3100)
-#define tls_andreas (-9596)
-#define tls_pandreas (3104)
-#define tls_wq (-9588)
-#define tls_pwq (3112)
-#define tls_prev (-9560)
-#define tls_pprev (3140)
-#define tls_next (-9556)
-#define tls_pnext (3144)
-#define tls_sig (-9552)
-#define tls_psig (3148)
-#define tls_incyg (-9548)
-#define tls_pincyg (3152)
-#define tls_spinning (-9544)
-#define tls_pspinning (3156)
-#define tls_stacklock (-9540)
-#define tls_pstacklock (3160)
-#define tls_stackptr (-9536)
-#define tls_pstackptr (3164)
-#define tls_stack (-9532)
-#define tls_pstack (3168)
-#define tls_initialized (-8508)
-#define tls_pinitialized (4192)
+#define tls__ctinfo (-9512)
+#define tls_p_ctinfo (3188)
+#define tls_andreas (-9508)
+#define tls_pandreas (3192)
+#define tls_wq (-9500)
+#define tls_pwq (3200)
+#define tls_prev (-9472)
+#define tls_pprev (3228)
+#define tls_next (-9468)
+#define tls_pnext (3232)
+#define tls_sig (-9464)
+#define tls_psig (3236)
+#define tls_incyg (-9460)
+#define tls_pincyg (3240)
+#define tls_spinning (-9456)
+#define tls_pspinning (3244)
+#define tls_stacklock (-9452)
+#define tls_pstacklock (3248)
+#define tls_stackptr (-9448)
+#define tls_pstackptr (3252)
+#define tls_stack (-9444)
+#define tls_pstack (3256)
+#define tls_initialized (-8420)
+#define tls_pinitialized (4280)
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 957cc38fd..e10ffe989 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -81,9 +81,13 @@ extern unsigned long cygwin_inet_addr (const char *cp);
buffer sizes. As MAX_PATH and PATH_MAX, this is defined including the
trailing 0. Internal buffers and internal path routines should use
NT_MAX_PATH. PATH_MAX as defined in limits.h is the maximum length of
- application provided path strings we handle. */
-/* FIXME: The name is preliminary and TBD. */
-#define NT_MAX_PATH 32768
+ application provided path strings we handle.
+
+ Note that it's defined one less than 32K. This is not only big enough,
+ it also allows to use the value in UNICODE_STRING fields Length and
+ MaximumLength when multiplied with sizeof (WCHAR). Both fields are
+ USHORT... */
+#define NT_MAX_PATH 32767
#ifdef __cplusplus