* path.cc (conv_path_list): Take cygwin_conv_path_t as third parameter.

Allow all types of CCP conversions.  Accommodate throughout.
	(cygwin_conv_path): Use current ANSI or OEM codepage for WIN_A
	conversions, depending on current file API codepage setting.
	(cygwin_conv_path_list): Allow all CCP conversion types.
	* include/sys/cygwin.h (CCP_CONVTYPE_MASK): Add to cygwin_conv_path_t
	enum for convenience.
This commit is contained in:
Corinna Vinschen 2011-12-02 16:06:10 +00:00
parent 13a20f9565
commit a887cf0ef5
3 changed files with 88 additions and 33 deletions

View File

@ -1,3 +1,13 @@
2011-12-02 Corinna Vinschen <vinschen@redhat.com>
* path.cc (conv_path_list): Take cygwin_conv_path_t as third parameter.
Allow all types of CCP conversions. Accommodate throughout.
(cygwin_conv_path): Use current ANSI or OEM codepage for WIN_A
conversions, depending on current file API codepage setting.
(cygwin_conv_path_list): Allow all CCP conversion types.
* include/sys/cygwin.h (CCP_CONVTYPE_MASK): Add to cygwin_conv_path_t
enum for convenience.
2011-11-29 Christopher Faylor <me.cygwin2011@cgf.cx> 2011-11-29 Christopher Faylor <me.cygwin2011@cgf.cx>
* sigproc.cc (get_proc_lock): Remove extra NULL check. Return false on * sigproc.cc (get_proc_lock): Remove extra NULL check. Return false on

View File

@ -50,6 +50,8 @@ enum
CCP_WIN_A_TO_POSIX, /* from is char*, to is char* */ CCP_WIN_A_TO_POSIX, /* from is char*, to is char* */
CCP_WIN_W_TO_POSIX, /* from is wchar_t*, to is char* */ CCP_WIN_W_TO_POSIX, /* from is wchar_t*, to is char* */
CCP_CONVTYPE_MASK = 3,
/* Or these values to the above as needed. */ /* Or these values to the above as needed. */
CCP_ABSOLUTE = 0, /* Request absolute path (default). */ CCP_ABSOLUTE = 0, /* Request absolute path (default). */
CCP_RELATIVE = 0x100 /* Request to keep path relative. */ CCP_RELATIVE = 0x100 /* Request to keep path relative. */

View File

@ -55,6 +55,7 @@
#include <wingdi.h> #include <wingdi.h>
#include <winuser.h> #include <winuser.h>
#include <winnetwk.h> #include <winnetwk.h>
#include <winnls.h>
#include <shlobj.h> #include <shlobj.h>
#include <sys/cygwin.h> #include <sys/cygwin.h>
#include "cygerrno.h" #include "cygerrno.h"
@ -1312,24 +1313,28 @@ nofinalslash (const char *src, char *dst)
/* conv_path_list: Convert a list of path names to/from Win32/POSIX. */ /* conv_path_list: Convert a list of path names to/from Win32/POSIX. */
static int static int
conv_path_list (const char *src, char *dst, size_t size, int to_posix) conv_path_list (const char *src, char *dst, size_t size,
cygwin_conv_path_t what)
{ {
tmp_pathbuf tp; tmp_pathbuf tp;
char src_delim, dst_delim; char src_delim, dst_delim;
cygwin_conv_path_t conv_fn;
size_t len; size_t len;
bool env_cvt = false;
if (to_posix) if (what == (cygwin_conv_path_t) ENV_CVT)
{
what = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
env_cvt = true;
}
if (what & CCP_WIN_A_TO_POSIX)
{ {
src_delim = ';'; src_delim = ';';
dst_delim = ':'; dst_delim = ':';
conv_fn = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
} }
else else
{ {
src_delim = ':'; src_delim = ':';
dst_delim = ';'; dst_delim = ';';
conv_fn = CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
} }
char *srcbuf; char *srcbuf;
@ -1355,7 +1360,7 @@ conv_path_list (const char *src, char *dst, size_t size, int to_posix)
/* Paths in Win32 path lists in the environment (%Path%), are often /* Paths in Win32 path lists in the environment (%Path%), are often
enclosed in quotes (usually paths with spaces). Trailing backslashes enclosed in quotes (usually paths with spaces). Trailing backslashes
are common, too. Remove them. */ are common, too. Remove them. */
if (to_posix == ENV_CVT && len) if (env_cvt && len)
{ {
if (*srcpath == '"') if (*srcpath == '"')
{ {
@ -1372,16 +1377,16 @@ conv_path_list (const char *src, char *dst, size_t size, int to_posix)
if (len) if (len)
{ {
++d; ++d;
err = cygwin_conv_path (conv_fn, srcpath, d, size - (d - dst)); err = cygwin_conv_path (what, srcpath, d, size - (d - dst));
} }
else if (!to_posix) else if ((what & CCP_CONVTYPE_MASK) == CCP_POSIX_TO_WIN_A)
{ {
++d; ++d;
err = cygwin_conv_path (conv_fn, ".", d, size - (d - dst)); err = cygwin_conv_path (what, ".", d, size - (d - dst));
} }
else else
{ {
if (to_posix == ENV_CVT) if (env_cvt)
saw_empty = true; saw_empty = true;
continue; continue;
} }
@ -2947,7 +2952,11 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
return_with_errno (p.error); return_with_errno (p.error);
PUNICODE_STRING up = p.get_nt_native_path (); PUNICODE_STRING up = p.get_nt_native_path ();
buf = tp.c_get (); buf = tp.c_get ();
sys_wcstombs (buf, NT_MAX_PATH, up->Buffer, up->Length / sizeof (WCHAR)); UINT cp = AreFileApisANSI () ? CP_ACP : CP_OEMCP;
int len = WideCharToMultiByte (cp, WC_NO_BEST_FIT_CHARS,
up->Buffer, up->Length / sizeof (WCHAR),
buf, NT_MAX_PATH, NULL, NULL);
buf[len] = '\0';
/* Convert native path to standard DOS path. */ /* Convert native path to standard DOS path. */
if (!strncmp (buf, "\\??\\", 4)) if (!strncmp (buf, "\\??\\", 4))
{ {
@ -2959,12 +2968,14 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
{ {
/* Device name points to somewhere else in the NT namespace. /* Device name points to somewhere else in the NT namespace.
Use GLOBALROOT prefix to convert to Win32 path. */ Use GLOBALROOT prefix to convert to Win32 path. */
char *p = buf + sys_wcstombs (buf, NT_MAX_PATH, char *p = buf + WideCharToMultiByte (cp, WC_NO_BEST_FIT_CHARS,
ro_u_globalroot.Buffer, ro_u_globalroot.Buffer,
ro_u_globalroot.Length ro_u_globalroot.Length / sizeof (WCHAR),
/ sizeof (WCHAR)); buf, NT_MAX_PATH, NULL, NULL);
sys_wcstombs (p, NT_MAX_PATH - (p - buf), len = WideCharToMultiByte (cp, WC_NO_BEST_FIT_CHARS,
up->Buffer, up->Length / sizeof (WCHAR)); up->Buffer, up->Length / sizeof (WCHAR),
p, NT_MAX_PATH - (p - buf), NULL, NULL);
p[len] = '\0';
} }
lsiz = strlen (buf) + 1; lsiz = strlen (buf) + 1;
/* TODO: Incoming "." is a special case which leads to a trailing /* TODO: Incoming "." is a special case which leads to a trailing
@ -3036,12 +3047,16 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
lsiz *= sizeof (WCHAR); lsiz *= sizeof (WCHAR);
break; break;
case CCP_WIN_A_TO_POSIX: case CCP_WIN_A_TO_POSIX:
{
UINT cp = AreFileApisANSI () ? CP_ACP : CP_OEMCP;
PWCHAR wbuf = tp.w_get ();
MultiByteToWideChar (cp, 0, (const char *) from, -1, wbuf, NT_MAX_PATH);
buf = tp.c_get (); buf = tp.c_get ();
error = mount_table->conv_to_posix_path ((const char *) from, buf, error = mount_table->conv_to_posix_path (wbuf, buf, relative);
relative);
if (error) if (error)
return_with_errno (error); return_with_errno (error);
lsiz = strlen (buf) + 1; lsiz = strlen (buf) + 1;
}
break; break;
case CCP_WIN_W_TO_POSIX: case CCP_WIN_W_TO_POSIX:
buf = tp.c_get (); buf = tp.c_get ();
@ -3280,35 +3295,63 @@ env_PATH_to_posix (const void *win32, void *posix, size_t size)
extern "C" int extern "C" int
cygwin_win32_to_posix_path_list (const char *win32, char *posix) cygwin_win32_to_posix_path_list (const char *win32, char *posix)
{ {
return_with_errno (conv_path_list (win32, posix, MAX_PATH, 1)); return_with_errno (conv_path_list (win32, posix, MAX_PATH,
CCP_WIN_A_TO_POSIX | CCP_RELATIVE));
} }
extern "C" int extern "C" int
cygwin_posix_to_win32_path_list (const char *posix, char *win32) cygwin_posix_to_win32_path_list (const char *posix, char *win32)
{ {
return_with_errno (conv_path_list (posix, win32, MAX_PATH, 0)); return_with_errno (conv_path_list (posix, win32, MAX_PATH,
CCP_POSIX_TO_WIN_A | CCP_RELATIVE));
} }
extern "C" ssize_t extern "C" ssize_t
cygwin_conv_path_list (cygwin_conv_path_t what, const void *from, void *to, cygwin_conv_path_list (cygwin_conv_path_t what, const void *from, void *to,
size_t size) size_t size)
{ {
/* FIXME: Path lists are (so far) always retaining relative paths. */ int ret;
what &= ~CCP_RELATIVE; char *winp = NULL;
switch (what) void *orig_to = NULL;
size_t orig_size = (size_t) -1;
tmp_pathbuf tp;
switch (what & CCP_CONVTYPE_MASK)
{ {
case CCP_WIN_W_TO_POSIX: case CCP_WIN_W_TO_POSIX:
case CCP_POSIX_TO_WIN_W: if (!sys_wcstombs_alloc (&winp, HEAP_NOTHEAP, (const wchar_t *) from,
/*FIXME*/ (size_t) -1))
api_fatal ("wide char path lists not yet supported"); return -1;
what = (what & ~CCP_CONVTYPE_MASK) | CCP_WIN_A_TO_POSIX;
from = (const void *) winp;
break; break;
case CCP_POSIX_TO_WIN_W:
if (size == 0)
return conv_path_list_buf_size ((const char *) from, 0)
* sizeof (WCHAR);
what = (what & ~CCP_CONVTYPE_MASK) | CCP_POSIX_TO_WIN_A;
orig_to = to;
orig_size = size;
to = (void *) tp.w_get ();
size = 65536;
break;
}
switch (what & CCP_CONVTYPE_MASK)
{
case CCP_WIN_A_TO_POSIX: case CCP_WIN_A_TO_POSIX:
case CCP_POSIX_TO_WIN_A: case CCP_POSIX_TO_WIN_A:
if (size == 0) if (size == 0)
return conv_path_list_buf_size ((const char *) from, return conv_path_list_buf_size ((const char *) from,
what == CCP_WIN_A_TO_POSIX); what == CCP_WIN_A_TO_POSIX);
return_with_errno (conv_path_list ((const char *) from, (char *) to, ret = conv_path_list ((const char *) from, (char *) to, size, what);
size, what == CCP_WIN_A_TO_POSIX)); /* Free winp buffer in case of CCP_WIN_W_TO_POSIX. */
if (winp)
free (winp);
/* Convert to WCHAR in case of CCP_POSIX_TO_WIN_W. */
if (orig_to)
sys_mbstowcs ((wchar_t *) orig_to, size / sizeof (WCHAR),
(const char *) to, (size_t) -1);
return_with_errno (ret);
break; break;
default: default:
break; break;