* winsup.h (NT_MAX_PATH): Revert ill-advised change to 32767.

Accommodate change throughout.

	* cygwin.din (cygwin_conv_path): Export.
	(cygwin_conv_path_list): Export.
	(cygwin_create_path): Export.
	* dcrt0.cc (dll_crt0_1): Use cygwin_conv_path.
	* dtable.cc (handle_to_fn): Ditto.  Don't expect UNICODE_STRING being
	0-terminated.
	* environ.cc (env_plist_to_posix): New helper function.
	(env_plist_to_win32): Ditto.
	(env_path_to_posix): Ditto.
	(env_path_to_win32): Ditto.
	(return_MAX_PATH): Remove.
	(conv_envvars): Use new helper functions.  Drop removed members.
	(win_env::operator =): Accommodate removal of path length functions.
	(win_env::add_cache): Accommodate new env helper function API.
	(posify): Ditto.
	* environ.h (struct win_env): Ditto. Remove path length function
	pointers since they are unused.
	* path.cc (warn_msdos): Use cygwin_conv_path.
	(getfileattr): Use new tmp_pathbuf::u_get method.
	(fillout_mntent): Ditto.
	(symlink_info::check): Ditto.
	(path_conv::check): Use sizeof (WCHAR) instead of constant 2.
	(symlink_info::check_reparse_point): Ditto.
	(conv_path_list): Get max size of target string as argument.  Call
	cygwin_conv_path as helper function.
	(cygwin_conv_path): New function.
	(cygwin_create_path): New function.
	(cygwin_conv_to_win32_path): Just call cygwin_conv_path with size set
	to MAX_PATH.
	(cygwin_conv_to_full_win32_path): Ditto.
	(cygwin_conv_to_posix_path): Ditto.
	(cygwin_conv_to_full_posix_path): Ditto.
	(conv_path_list_buf_size): Add FIXME comment.
	(env_PATH_to_posix): Rename from env_win32_to_posix_path_list.
	Add size argument as required for env helper functions.
	(cygwin_win32_to_posix_path_list): Call conv_path_list with size set to
	MAX_PATH.
	(cygwin_posix_to_win32_path_list): Ditto.
	(cygwin_conv_path_list): New function.
	(cwdstuff::get): Fix length argument in call to sys_wcstombs.
	* spawn.cc (find_exec): Use cygwin_conv_path_list.
	* tls_pbuf.h (tmp_pathbuf::u_get: New method.
	* uinfo.cc (cygheap_user::ontherange): Allocate temporary path buffers
	using tmp_pathbuf.  Use cygwin_conv_path.
	* winf.cc (av::unshift): Use cygwin_conv_path.
	* include/cygwin/version.h: Bump API minor number.
	* include/sys/cygwin.h: Comment out old cygwin32_XXX API.
	Mark old path handling API as deprecated.
	(cygwin_conv_path_t): Typedef.  Define values.
	(cygwin_conv_path): Declare.
	(cygwin_create_path): Declare.
	(cygwin_conv_path_list): Declare.
This commit is contained in:
Corinna Vinschen 2008-03-12 12:41:50 +00:00
parent 674310fb40
commit edab6053a2
17 changed files with 371 additions and 141 deletions

View File

@ -1,3 +1,61 @@
2008-03-12 Corinna Vinschen <corinna@vinschen.de>
* winsup.h (NT_MAX_PATH): Revert ill-advised change to 32767.
Accommodate change throughout.
* cygwin.din (cygwin_conv_path): Export.
(cygwin_conv_path_list): Export.
(cygwin_create_path): Export.
* dcrt0.cc (dll_crt0_1): Use cygwin_conv_path.
* dtable.cc (handle_to_fn): Ditto. Don't expect UNICODE_STRING being
0-terminated.
* environ.cc (env_plist_to_posix): New helper function.
(env_plist_to_win32): Ditto.
(env_path_to_posix): Ditto.
(env_path_to_win32): Ditto.
(return_MAX_PATH): Remove.
(conv_envvars): Use new helper functions. Drop removed members.
(win_env::operator =): Accommodate removal of path length functions.
(win_env::add_cache): Accommodate new env helper function API.
(posify): Ditto.
* environ.h (struct win_env): Ditto. Remove path length function
pointers since they are unused.
* path.cc (warn_msdos): Use cygwin_conv_path.
(getfileattr): Use new tmp_pathbuf::u_get method.
(fillout_mntent): Ditto.
(symlink_info::check): Ditto.
(path_conv::check): Use sizeof (WCHAR) instead of constant 2.
(symlink_info::check_reparse_point): Ditto.
(conv_path_list): Get max size of target string as argument. Call
cygwin_conv_path as helper function.
(cygwin_conv_path): New function.
(cygwin_create_path): New function.
(cygwin_conv_to_win32_path): Just call cygwin_conv_path with size set
to MAX_PATH.
(cygwin_conv_to_full_win32_path): Ditto.
(cygwin_conv_to_posix_path): Ditto.
(cygwin_conv_to_full_posix_path): Ditto.
(conv_path_list_buf_size): Add FIXME comment.
(env_PATH_to_posix): Rename from env_win32_to_posix_path_list.
Add size argument as required for env helper functions.
(cygwin_win32_to_posix_path_list): Call conv_path_list with size set to
MAX_PATH.
(cygwin_posix_to_win32_path_list): Ditto.
(cygwin_conv_path_list): New function.
(cwdstuff::get): Fix length argument in call to sys_wcstombs.
* spawn.cc (find_exec): Use cygwin_conv_path_list.
* tls_pbuf.h (tmp_pathbuf::u_get: New method.
* uinfo.cc (cygheap_user::ontherange): Allocate temporary path buffers
using tmp_pathbuf. Use cygwin_conv_path.
* winf.cc (av::unshift): Use cygwin_conv_path.
* include/cygwin/version.h: Bump API minor number.
* include/sys/cygwin.h: Comment out old cygwin32_XXX API.
Mark old path handling API as deprecated.
(cygwin_conv_path_t): Typedef. Define values.
(cygwin_conv_path): Declare.
(cygwin_create_path): Declare.
(cygwin_conv_path_list): Declare.
2008-03-11 Corinna Vinschen <corinna@vinschen.de>
* dlfcn.cc (get_full_path_of_dll): Allow paths up to PATH_MAX.

View File

@ -249,18 +249,6 @@ _cygtls::init_exception_handler (exception_handler *eh)
Windows 2008, which irremediably gets into an endless loop, taking 100%
CPU. That's why we reverted to a normal SEH chain and changed the way
the exception handler returns to the application. */
/* 2008-03-28 - The fun continues. Revert to doing something sorta like
before. Just make sure *only* the cygwin exception handler is installed
rather than honoring other exception handlers. The theory here is that
cygwin should be in control and there should be no Windows voodoo going
on behind the scenes.
This change was made so that this function could be called from
handle_exceptions to essentially "clean up" the exception handling
linked list.
The open question is whether making this NULL will have an adverse effect
on Windows functions. */
el.prev = _except_list;
_except_list = &el;
el.prev = NULL;
}

View File

@ -237,10 +237,13 @@ cygwin32_win32_to_posix_path_list = cygwin_win32_to_posix_path_list SIGFE
cygwin32_win32_to_posix_path_list_buf_size = cygwin_win32_to_posix_path_list_buf_size SIGFE
cygwin32_winpid_to_pid = cygwin_winpid_to_pid SIGFE
cygwin_attach_handle_to_fd SIGFE
cygwin_conv_path SIGFE
cygwin_conv_path_list SIGFE
cygwin_conv_to_full_posix_path SIGFE
cygwin_conv_to_full_win32_path SIGFE
cygwin_conv_to_posix_path SIGFE
cygwin_conv_to_win32_path SIGFE
cygwin_create_path SIGFE
cygwin_detach_dll SIGFE_MAYBE
cygwin_dll_init NOSIGFE
cygwin_internal NOSIGFE

View File

@ -859,7 +859,8 @@ dll_crt0_1 (void *)
if ((strchr (__argv[0], ':')) || (strchr (__argv[0], '\\')))
{
char *new_argv0 = (char *) malloc (NT_MAX_PATH);
cygwin_conv_to_posix_path (__argv[0], new_argv0);
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, __argv[0],
new_argv0, NT_MAX_PATH);
__argv[0] = (char *) realloc (new_argv0, strlen (new_argv0) + 1);
}
}

View File

@ -854,7 +854,7 @@ handle_to_fn (HANDLE h, char *posix_fn)
memset (fnbuf, 0, len);
ntfn = (OBJECT_NAME_INFORMATION *) fnbuf;
ntfn->Name.MaximumLength = NT_MAX_PATH * sizeof (WCHAR);
ntfn->Name.MaximumLength = (NT_MAX_PATH - 1) * sizeof (WCHAR);
ntfn->Name.Buffer = (WCHAR *) (ntfn + 1);
NTSTATUS res = NtQueryObject (h, ObjectNameInformation, ntfn, len, NULL);
@ -876,7 +876,8 @@ handle_to_fn (HANDLE h, char *posix_fn)
ntfn->Name.Buffer[ntfn->Name.Length / sizeof (WCHAR)] = 0;
char *win32_fn = tp.c_get ();
sys_wcstombs (win32_fn, NT_MAX_PATH, ntfn->Name.Buffer);
sys_wcstombs (win32_fn, NT_MAX_PATH, ntfn->Name.Buffer,
ntfn->Name.Length / sizeof (WCHAR));
debug_printf ("nt name '%s'", win32_fn);
if (!strncasematch (win32_fn, DEVICE_PREFIX, DEVICE_PREFIX_LEN)
|| !QueryDosDevice (NULL, fnbuf, len))
@ -947,7 +948,8 @@ handle_to_fn (HANDLE h, char *posix_fn)
}
if (!justslash)
cygwin_conv_to_full_posix_path (w32, posix_fn);
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, w32, posix_fn,
NT_MAX_PATH);
else
{
char *s, *d;

View File

@ -47,7 +47,37 @@ extern bool allow_server;
static char **lastenviron;
extern "C" int env_win32_to_posix_path_list (const char *, char *posix);
/* Helper functions for the below environment variables which have to
be converted Win32<->POSIX. */
extern "C" ssize_t env_PATH_to_posix (const void *, void *, size_t);
ssize_t
env_plist_to_posix (const void *win32, void *posix, size_t size)
{
return cygwin_conv_path_list (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, win32,
posix, size);
}
ssize_t
env_plist_to_win32 (const void *posix, void *win32, size_t size)
{
return cygwin_conv_path_list (CCP_POSIX_TO_WIN_A | CCP_RELATIVE, posix,
win32, size);
}
ssize_t
env_path_to_posix (const void *win32, void *posix, size_t size)
{
return cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, win32,
posix, size);
}
ssize_t
env_path_to_win32 (const void *posix, void *win32, size_t size)
{
return cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, posix,
win32, size);
}
#define ENVMALLOC \
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) \
@ -60,26 +90,16 @@ extern "C" int env_win32_to_posix_path_list (const char *, char *posix);
PATH needs to be here because CreateProcess uses it and gdb uses
CreateProcess. HOME is here because most shells use it and would be
confused by Windows style path names. */
static int return_MAX_PATH (const char *) {return CYG_MAX_PATH;}
static win_env conv_envvars[] =
{
{NL ("PATH="), NULL, NULL, env_win32_to_posix_path_list,
cygwin_posix_to_win32_path_list,
cygwin_win32_to_posix_path_list_buf_size,
cygwin_posix_to_win32_path_list_buf_size, true},
{NL ("HOME="), NULL, NULL, cygwin_conv_to_full_posix_path,
cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
{NL ("LD_LIBRARY_PATH="), NULL, NULL, cygwin_win32_to_posix_path_list,
cygwin_posix_to_win32_path_list,
cygwin_win32_to_posix_path_list_buf_size,
cygwin_posix_to_win32_path_list_buf_size, true},
{NL ("TMPDIR="), NULL, NULL, cygwin_conv_to_full_posix_path,
cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
{NL ("TMP="), NULL, NULL, cygwin_conv_to_full_posix_path,
cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
{NL ("TEMP="), NULL, NULL, cygwin_conv_to_full_posix_path,
cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
{NULL, 0, NULL, NULL, NULL, NULL, 0, 0}
{NL ("PATH="), NULL, NULL, env_PATH_to_posix, env_plist_to_win32, true},
{NL ("HOME="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
{NL ("LD_LIBRARY_PATH="), NULL, NULL,
env_plist_to_posix, env_plist_to_win32, true},
{NL ("TMPDIR="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
{NL ("TMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
{NL ("TEMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
{NULL, 0, NULL, NULL, 0, 0}
};
static unsigned char conv_start_chars[256] = {0};
@ -91,8 +111,6 @@ win_env::operator = (struct win_env& x)
namelen = x.namelen;
toposix = x.toposix;
towin32 = x.towin32;
posix_len = x.posix_len;
win32_len = x.win32_len;
immediate = false;
return *this;
}
@ -122,7 +140,7 @@ win_env::add_cache (const char *in_posix, const char *in_native)
tmp_pathbuf tp;
char *buf = tp.c_get ();
strcpy (buf, name + namelen);
towin32 (in_posix, buf);
towin32 (in_posix, buf, NT_MAX_PATH);
native = (char *) realloc (native, namelen + 1 + strlen (buf));
strcpy (native, name);
strcpy (native + namelen, buf);
@ -191,14 +209,15 @@ posify (char **here, const char *value, char *outenv)
memcpy (outenv, src, len);
char *newvalue = outenv + len;
if (!conv->toposix (value, newvalue) || _impure_ptr->_errno != EIDRM)
if (!conv->toposix (value, newvalue, NT_MAX_PATH - len)
|| _impure_ptr->_errno != EIDRM)
conv->add_cache (newvalue, *value != '/' ? value : NULL);
else
{
/* The conversion routine removed elements from a path list so we have
to recalculate the windows path to remove elements there, too. */
char cleanvalue[strlen (value) + 1];
conv->towin32 (newvalue, cleanvalue);
conv->towin32 (newvalue, cleanvalue, sizeof cleanvalue);
conv->add_cache (newvalue, cleanvalue);
}

View File

@ -23,10 +23,8 @@ struct win_env
size_t namelen;
char *posix;
char *native;
int (*toposix) (const char *, char *);
int (*towin32) (const char *, char *);
int (*posix_len) (const char *);
int (*win32_len) (const char *);
ssize_t (*toposix) (const void *, void *, size_t);
ssize_t (*towin32) (const void *, void *, size_t);
bool immediate;
void add_cache (const char *in_posix, const char *in_native = NULL)
__attribute__ ((regparm (3)));

View File

@ -470,6 +470,8 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
/* Main exception handler. */
extern exception_list *_except_list asm ("%fs:0");
extern "C" char *__progname;
int
_cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
@ -623,9 +625,10 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
me.copy_context (in);
/* Reinitialize exception handler list to include just ourselves so that any
exceptions that occur in a signal handler will be properly caught. */
me.init_exception_handler (handle_exceptions);
/* Temporarily replace windows top level SEH with our own handler.
We don't want any Windows magic kicking in. This top level frame
will be removed automatically after our exception handler returns. */
_except_list->handler = _cygtls::handle_exceptions;
if (masked
|| &me == _sig_tls
@ -634,7 +637,6 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
{
rtl_unwind (frame, e);
/* Print the exception to the console */
if (!myself->cygstarted)
for (int i = 0; status_info[i].name; i++)
@ -656,6 +658,7 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
return 0;
}
rtl_unwind (frame, e);
open_stackdumpfile ();
exception (e, in);
stackdump ((DWORD) ebp, 0, 1);

View File

@ -323,12 +323,13 @@ details. */
180: Export getxattr, lgetxattr, fgetxattr, listxattr, llistxattr,
flistxattr, setxattr, lsetxattr, fsetxattr, removexattr,
lremovexattr, fremovexattr.
181: Export cygwin_conv_path, cygwin_create_path, cygwin_conv_path_list.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 180
#define CYGWIN_VERSION_API_MINOR 181
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible

View File

@ -20,6 +20,7 @@ extern "C" {
#define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
#if 0 /* ENTIRELY DEPRECATED INTERFACES. */
extern pid_t cygwin32_winpid_to_pid (int);
extern void cygwin32_win32_to_posix_path_list (const char *, char *);
extern int cygwin32_win32_to_posix_path_list_buf_size (const char *);
@ -31,16 +32,64 @@ extern void cygwin32_conv_to_posix_path (const char *, char *);
extern void cygwin32_conv_to_full_posix_path (const char *, char *);
extern int cygwin32_posix_path_list_p (const char *);
extern void cygwin32_split_path (const char *, char *, char *);
#endif
/* DEPRECATED INTERFACES. These are restricted to MAX_PATH length.
Don't use in modern applications. */
extern int cygwin_win32_to_posix_path_list (const char *, char *)
__attribute__ ((deprecated));
extern int cygwin_win32_to_posix_path_list_buf_size (const char *)
__attribute__ ((deprecated));
extern int cygwin_posix_to_win32_path_list (const char *, char *)
__attribute__ ((deprecated));
extern int cygwin_posix_to_win32_path_list_buf_size (const char *)
__attribute__ ((deprecated));
extern int cygwin_conv_to_win32_path (const char *, char *)
__attribute__ ((deprecated));
extern int cygwin_conv_to_full_win32_path (const char *, char *)
__attribute__ ((deprecated));
extern int cygwin_conv_to_posix_path (const char *, char *)
__attribute__ ((deprecated));
extern int cygwin_conv_to_full_posix_path (const char *, char *)
__attribute__ ((deprecated));
/* Use these interfaces in favor of the above. */
/* Possible 'what' values in calls to cygwin_conv_path/cygwin_create_path. */
enum
{
CCP_POSIX_TO_WIN_A = 0, /* from is char*, to is char* */
CCP_POSIX_TO_WIN_W, /* from is char*, to is wchar_t* */
CCP_WIN_A_TO_POSIX, /* from is char*, to is char* */
CCP_WIN_W_TO_POSIX, /* from is wchar_t*, to is char* */
/* Or these values to the above as needed. */
CCP_ABSOLUTE = 0, /* Request absolute path (default). */
CCP_RELATIVE = 0x100 /* Request to keep path relative. */
};
typedef unsigned int cygwin_conv_path_t;
/* If size is 0, cygwin_conv_path returns the required buffer size in bytes.
Otherwise, it returns 0 on success, or -1 on error and errno is set to
one of the below values:
EINVAL what has an invalid value.
EFAULT from or to point into nirvana.
ENAMETOOLONG the resulting path is longer than 32K, or, in case
of what == CCP_POSIX_TO_WIN_A, longer than MAX_PATH.
ENOSPC size is less than required for the conversion.
*/
extern ssize_t cygwin_conv_path (cygwin_conv_path_t what, const void *from,
void *to, size_t size);
/* Same, but handles path lists separated by colon or semicolon. */
extern ssize_t cygwin_conv_path_list (cygwin_conv_path_t what, const void *from,
void *to, size_t size);
/* Allocate a buffer for the conversion result using malloc(3), and return
a pointer to it. Returns NULL if something goes wrong with errno set
to one of the above values, or to ENOMEM if malloc fails. */
extern void *cygwin_create_path (cygwin_conv_path_t what, const void *from);
extern pid_t cygwin_winpid_to_pid (int);
extern int cygwin_win32_to_posix_path_list (const char *, char *);
extern int cygwin_win32_to_posix_path_list_buf_size (const char *);
extern int cygwin_posix_to_win32_path_list (const char *, char *);
extern int cygwin_posix_to_win32_path_list_buf_size (const char *);
extern int cygwin_conv_to_win32_path (const char *, char *);
extern int cygwin_conv_to_full_win32_path (const char *, char *);
extern int cygwin_conv_to_posix_path (const char *, char *);
extern int cygwin_conv_to_full_posix_path (const char *, char *);
extern int cygwin_posix_path_list_p (const char *);
extern void cygwin_split_path (const char *, char *, char *);

View File

@ -652,7 +652,8 @@ warn_msdos (const char *src)
tmp_pathbuf tp;
char *posix_path = tp.c_get ();
small_printf ("cygwin warning:\n");
if (cygwin_conv_to_full_posix_path (src, posix_path))
if (cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, src,
posix_path, NT_MAX_PATH))
small_printf (" MS-DOS style path detected: %s\n POSIX equivalent preferred.\n",
src);
else
@ -661,7 +662,6 @@ warn_msdos (const char *src)
small_printf (" CYGWIN environment variable option \"nodosfilewarning\" turns off this warning.\n"
" Consult the user's guide for more details about POSIX paths:\n"
" http://cygwin.com/cygwin-ug-net/using.html#using-pathnames\n");
user_shared->warned_msdos = true;
}
@ -675,7 +675,7 @@ getfileattr (const char *path) /* path has to be always absolute. */
NTSTATUS status;
IO_STATUS_BLOCK io;
RtlInitEmptyUnicodeString (&upath, tp.w_get (), NT_MAX_PATH * sizeof (WCHAR));
tp.u_get (&upath);
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
get_nt_native_path (path, upath);
@ -742,7 +742,7 @@ path_conv::check (PUNICODE_STRING src, unsigned opt,
char *path = tp.c_get ();
user_shared->warned_msdos = true;
sys_wcstombs (path, NT_MAX_PATH, src->Buffer, src->Length / 2);
sys_wcstombs (path, NT_MAX_PATH, src->Buffer, src->Length / sizeof (WCHAR));
path_conv::check (path, opt, suffixes);
}
@ -1504,22 +1504,22 @@ nofinalslash (const char *src, char *dst)
/* conv_path_list: Convert a list of path names to/from Win32/POSIX. */
static int
conv_path_list (const char *src, char *dst, int to_posix)
conv_path_list (const char *src, char *dst, size_t size, int to_posix)
{
char src_delim, dst_delim;
int (*conv_fn) (const char *, char *);
cygwin_conv_path_t conv_fn;
if (to_posix)
{
src_delim = ';';
dst_delim = ':';
conv_fn = cygwin_conv_to_posix_path;
conv_fn = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
}
else
{
src_delim = ':';
dst_delim = ';';
conv_fn = cygwin_conv_to_win32_path;
conv_fn = CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
}
char *srcbuf = (char *) alloca (strlen (src) + 1);
@ -1530,16 +1530,22 @@ conv_path_list (const char *src, char *dst, int to_posix)
do
{
char *s = strccpy (srcbuf, &src, src_delim);
int len = s - srcbuf;
size_t len = s - srcbuf;
if (len >= NT_MAX_PATH)
{
err = ENAMETOOLONG;
break;
}
if (len)
err = conv_fn (srcbuf, ++d);
{
++d;
err = cygwin_conv_path (conv_fn, srcbuf, d, size - (d - dst));
}
else if (!to_posix)
err = conv_fn (".", ++d);
{
++d;
err = cygwin_conv_path (conv_fn, ".", d, size - (d - dst));
}
else
{
if (to_posix == ENV_CVT)
@ -2767,7 +2773,7 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
fs_info mntinfo;
tmp_pathbuf tp;
UNICODE_STRING unat;
RtlInitEmptyUnicodeString (&unat, tp.w_get (), NT_MAX_PATH * sizeof (WCHAR));
tp.u_get (&unat);
get_nt_native_path (native_path, unat);
if (append_bs)
RtlAppendUnicodeToString (&unat, L"\\");
@ -3431,7 +3437,7 @@ symlink_info::check_reparse_point (HANDLE h)
sys_wcstombs (srcbuf, SYMLINK_MAX + 1,
(WCHAR *)((char *)rp->SymbolicLinkReparseBuffer.PathBuffer
+ rp->SymbolicLinkReparseBuffer.SubstituteNameOffset),
rp->SymbolicLinkReparseBuffer.SubstituteNameLength / 2);
rp->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof (WCHAR));
pflags = PATH_SYMLINK | PATH_REP;
fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
}
@ -3445,7 +3451,7 @@ symlink_info::check_reparse_point (HANDLE h)
sys_wcstombs (srcbuf, SYMLINK_MAX + 1,
(WCHAR *)((char *)rp->MountPointReparseBuffer.PathBuffer
+ rp->MountPointReparseBuffer.SubstituteNameOffset),
rp->MountPointReparseBuffer.SubstituteNameLength / 2);
rp->MountPointReparseBuffer.SubstituteNameLength / sizeof (WCHAR));
pflags = PATH_SYMLINK | PATH_REP;
fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
}
@ -3724,7 +3730,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
tmp_pathbuf tp;
UNICODE_STRING upath;
OBJECT_ATTRIBUTES attr;
RtlInitEmptyUnicodeString (&upath, tp.w_get (), NT_MAX_PATH * sizeof (WCHAR));
tp.u_get (&upath);
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
while (suffix.next ())
@ -4154,36 +4160,114 @@ fchdir (int fd)
return -1;\
} while (0)
extern "C" ssize_t
cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
size_t size)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
path_conv p;
tmp_pathbuf tp;
size_t lsiz = 0;
char *buf = NULL;
int error = 0;
bool relative = !!(what & CCP_RELATIVE);
what &= ~CCP_RELATIVE;
switch (what)
{
case CCP_POSIX_TO_WIN_A:
p.check ((const char *) from,
PC_POSIX | PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK | PC_NOWARN
| (relative ? PC_NOFULL : 0));
if (p.error)
return_with_errno (p.error);
PUNICODE_STRING up = p.get_nt_native_path ();
buf = tp.c_get ();
sys_wcstombs (buf, NT_MAX_PATH, up->Buffer, up->Length / sizeof (WCHAR));
buf += 4; /* Skip \??\ */
if (ascii_strncasematch (buf, "UNC\\", 4))
*(buf += 2) = '\\';
lsiz = strlen (buf) + 1;
break;
case CCP_POSIX_TO_WIN_W:
p.check ((const char *) from,
PC_POSIX | PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK | PC_NOWARN
| (relative ? PC_NOFULL : 0));
if (p.error)
return_with_errno (p.error);
lsiz = (p.get_wide_win32_path_len () + 1) * sizeof (WCHAR);
break;
case CCP_WIN_A_TO_POSIX:
buf = tp.c_get ();
error = mount_table->conv_to_posix_path ((const char *) from, buf,
relative);
if (error)
return_with_errno (error);
lsiz = strlen (buf) + 1;
break;
case CCP_WIN_W_TO_POSIX:
buf = tp.c_get ();
error = mount_table->conv_to_posix_path ((const PWCHAR) from, buf,
relative);
if (error)
return_with_errno (error);
lsiz = strlen (buf) + 1;
break;
default:
set_errno (EINVAL);
return -1;
}
if (!size)
return lsiz;
if (size < lsiz)
{
set_errno (ENOSPC);
return -1;
}
switch (what)
{
case CCP_POSIX_TO_WIN_A:
case CCP_WIN_A_TO_POSIX:
case CCP_WIN_W_TO_POSIX:
strcpy ((char *) to, buf);
break;
case CCP_POSIX_TO_WIN_W:
p.get_wide_win32_path ((PWCHAR) to);
break;
}
return 0;
}
extern "C" void *
cygwin_create_path (cygwin_conv_path_t what, const void *from)
{
void *to;
ssize_t size = cygwin_conv_path (what, from, NULL, 0);
if (size <= 0)
return NULL;
if (!(to = malloc (size)))
return NULL;
if (cygwin_conv_path (what, from, to, size) == -1)
return NULL;
return to;
}
extern "C" int
cygwin_conv_to_win32_path (const char *path, char *win32_path)
{
path_conv p (path, PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK | PC_NOFULL | PC_NOWARN);
if (p.error)
{
win32_path[0] = '\0';
set_errno (p.error);
return -1;
}
strcpy (win32_path,
strcmp (p.get_win32 (), ".\\") == 0 ? "." : p.get_win32 ());
return 0;
return cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE, path, win32_path,
MAX_PATH);
}
extern "C" int
cygwin_conv_to_full_win32_path (const char *path, char *win32_path)
{
path_conv p (path, PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK | PC_NOWARN);
if (p.error)
{
win32_path[0] = '\0';
set_errno (p.error);
return -1;
}
strcpy (win32_path, p.get_win32 ());
return 0;
return cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, path, win32_path,
MAX_PATH);
}
/* This is exported to the world as cygwin_foo by cygwin.din. */
@ -4191,29 +4275,15 @@ cygwin_conv_to_full_win32_path (const char *path, char *win32_path)
extern "C" int
cygwin_conv_to_posix_path (const char *path, char *posix_path)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (!*path)
{
set_errno (ENOENT);
return -1;
}
return_with_errno (mount_table->conv_to_posix_path (path, posix_path, 1));
return cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, path, posix_path,
MAX_PATH);
}
extern "C" int
cygwin_conv_to_full_posix_path (const char *path, char *posix_path)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (!*path)
{
set_errno (ENOENT);
return -1;
}
return_with_errno (mount_table->conv_to_posix_path (path, posix_path, 0));
return cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, path, posix_path,
MAX_PATH);
}
/* The realpath function is supported on some UNIX systems. */
@ -4322,6 +4392,7 @@ conv_path_list_buf_size (const char *path_list, bool to_posix)
path_conv pc(".", PC_POSIX);
/* The theory is that an upper bound is
current_size + (num_elms * max_mount_path_len) */
/* FIXME: This method is questionable in the long run. */
unsigned nrel;
char delim = to_posix ? ';' : ':';
@ -4365,22 +4436,51 @@ cygwin_posix_to_win32_path_list_buf_size (const char *path_list)
return conv_path_list_buf_size (path_list, false);
}
extern "C" int
env_win32_to_posix_path_list (const char *win32, char *posix)
extern "C" ssize_t
env_PATH_to_posix (const void *win32, void *posix, size_t size)
{
return_with_errno (conv_path_list (win32, posix, ENV_CVT));
return_with_errno (conv_path_list ((const char *) win32, (char *) posix,
size, ENV_CVT));
}
extern "C" int
cygwin_win32_to_posix_path_list (const char *win32, char *posix)
{
return_with_errno (conv_path_list (win32, posix, 1));
return_with_errno (conv_path_list (win32, posix, MAX_PATH, 1));
}
extern "C" int
cygwin_posix_to_win32_path_list (const char *posix, char *win32)
{
return_with_errno (conv_path_list (posix, win32, 0));
return_with_errno (conv_path_list (posix, win32, MAX_PATH, 0));
}
extern "C" ssize_t
cygwin_conv_path_list (cygwin_conv_path_t what, const void *from, void *to,
size_t size)
{
/* FIXME: Path lists are (so far) always retaining relative paths. */
what &= ~CCP_RELATIVE;
switch (what)
{
case CCP_WIN_W_TO_POSIX:
case CCP_POSIX_TO_WIN_W:
/*FIXME*/
api_fatal ("wide char path lists not yet supported");
break;
case CCP_WIN_A_TO_POSIX:
case CCP_POSIX_TO_WIN_A:
if (size == 0)
return conv_path_list_buf_size ((const char *) from,
what == CCP_WIN_A_TO_POSIX);
return_with_errno (conv_path_list ((const char *) from, (char *) to,
size, what == CCP_WIN_A_TO_POSIX));
break;
default:
break;
}
set_errno (EINVAL);
return -1;
}
/* cygwin_split_path: Split a path into directory and file name parts.
@ -4685,7 +4785,8 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
if (!need_posix)
{
tocopy = tp.c_get ();
sys_wcstombs (tocopy, NT_MAX_PATH, win32.Buffer, win32.Length);
sys_wcstombs (tocopy, NT_MAX_PATH, win32.Buffer,
win32.Length / sizeof (WCHAR));
}
else
tocopy = posix;

View File

@ -138,9 +138,9 @@ find_exec (const char *name, path_conv& buf, const char *mywinenv,
if (strchr (mywinenv, '/'))
{
/* it's not really an environment variable at all */
int n = cygwin_posix_to_win32_path_list_buf_size (mywinenv);
char *s = (char *) alloca (n + 1);
if (cygwin_posix_to_win32_path_list (mywinenv, s))
int n = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, mywinenv, NULL, 0);
char *s = (char *) alloca (n);
if (cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, mywinenv, s, n))
goto errout;
path = s;
posix_path = mywinenv - 1;

View File

@ -42,7 +42,7 @@ 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 + 1)))
&& !(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++];
}
@ -54,7 +54,7 @@ tmp_pathbuf::w_get ()
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 + 1) * sizeof (WCHAR))))
= (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++];
}

View File

@ -17,4 +17,11 @@ public:
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 (); }
inline PUNICODE_STRING u_get (PUNICODE_STRING up)
{
up->Length = 0;
up->MaximumLength = (NT_MAX_PATH - 1) * sizeof (WCHAR);
up->Buffer = w_get ();
return up;
}
};

View File

@ -30,6 +30,7 @@ details. */
#include "child_info.h"
#include "environ.h"
#include "pwdgrp.h"
#include "tls_pbuf.h"
#include "ntdll.h"
/* Initialize the part of cygheap_user that does not depend on files.
@ -240,11 +241,10 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
LPUSER_INFO_3 ui = NULL;
WCHAR wuser[UNLEN + 1];
NET_API_STATUS ret;
char homepath_env_buf[CYG_MAX_PATH];
char homedrive_env_buf[3];
char *newhomedrive = NULL;
char *newhomepath = NULL;
tmp_pathbuf tp;
debug_printf ("what %d, pw %p", what, pw);
if (what == CH_HOME)
@ -273,11 +273,12 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
setenv ("HOME", "/", 1);
else
{
char home[CYG_MAX_PATH];
char buf[CYG_MAX_PATH];
char *home = tp.c_get ();
char *buf = tp.c_get ();
strcpy (buf, newhomedrive);
strcat (buf, newhomepath);
cygwin_conv_to_full_posix_path (buf, home);
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, buf, home,
NT_MAX_PATH);
debug_printf ("Set HOME (from HOMEDRIVE/HOMEPATH) to %s", home);
setenv ("HOME", home, 1);
}
@ -286,10 +287,12 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
if (what != CH_HOME && homepath == NULL && newhomepath == NULL)
{
char *homepath_env_buf = tp.c_get ();
if (!pw)
pw = internal_getpwnam (name ());
if (pw && pw->pw_dir && *pw->pw_dir)
cygwin_conv_to_full_win32_path (pw->pw_dir, homepath_env_buf);
cygwin_conv_path (CCP_POSIX_TO_WIN_A, pw->pw_dir, homepath_env_buf,
NT_MAX_PATH);
else
{
homepath_env_buf[0] = homepath_env_buf[1] = '\0';
@ -301,16 +304,17 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
sys_mbstowcs (wuser, sizeof (wuser) / sizeof (*wuser), winname ());
if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3, (LPBYTE *) &ui)))
{
sys_wcstombs (homepath_env_buf, CYG_MAX_PATH,
sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
ui->usri3_home_dir);
if (!homepath_env_buf[0])
{
sys_wcstombs (homepath_env_buf, CYG_MAX_PATH,
sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
ui->usri3_home_dir_drive);
if (homepath_env_buf[0])
strcat (homepath_env_buf, "\\");
else
cygwin_conv_to_full_win32_path ("/", homepath_env_buf);
cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE,
"/", homepath_env_buf, NT_MAX_PATH);
}
}
}

View File

@ -141,7 +141,8 @@ av::unshift (const char *what, int conv)
char *buf = tp.c_get ();
if (conv)
{
cygwin_conv_to_posix_path (what, buf);
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, what, buf,
NT_MAX_PATH);
char *p = strchr (buf, '\0') - 4;
if (p > buf && ascii_strcasematch (p, ".exe"))
*p = '\0';

View File

@ -81,13 +81,8 @@ 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.
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
application provided path strings we handle. */
#define NT_MAX_PATH 32768
#ifdef __cplusplus