* 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.
This commit is contained in:
Corinna Vinschen 2008-03-07 11:24:51 +00:00
parent d8e218442b
commit 752b16ce35
22 changed files with 467 additions and 203 deletions

View File

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

View File

@ -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

View File

@ -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)

View File

@ -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)
{

View File

@ -171,6 +171,9 @@ _cygtls::remove (DWORD wait)
free_local (hostent_buf);
}
/* Free temporary TLS path buffers. */
locals.pathbufs.destroy ();
do
{
sentry here (wait);

View File

@ -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

View File

@ -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;
}

View File

@ -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)));

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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");

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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 =

View File

@ -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;

View File

@ -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;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
HANDLE h;
NTSTATUS status;
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)
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. */

View File

@ -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)

60
winsup/cygwin/tls_pbuf.cc Normal file
View File

@ -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++];
}

20
winsup/cygwin/tls_pbuf.h Normal file
View File

@ -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 (); }
};

View File

@ -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)

View File

@ -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