Allow cygwin_conv_path(3) and cygpath(1) to emit /proc/cygdrive prefixed path

* include/sys/cygwin.h (CCP_PROC_CYGDRIVE): New flag.
        * mount.cc (mount_info::cygdrive_posix_path): Take flag values rather
        than just a trailing_slash_p bool.  Emit /proc/cygdrive path if
        CCP_PROC_CYGDRIVE flag is given.
        (mount_info::conv_to_posix_path): Take flag values rather than just
        a keep_rel_p bool.  Rename _p variables.  Print flag value as hex in
        debug_printf.  Call cygdrive_posix_path with flag values.
        * mount.h (mount_info::cygdrive_posix_path): Accommodate above change
        in declaration.
        (mount_info::conv_to_posix_path): Ditto.
        * fhandler_process.cc (format_process_exename): Accommodate change to
        mount_info::conv_to_posix_path.
        * path.cc (cygwin_conv_path): Ditto.

        * cygpath.cc (absolute_flag): Initialize to CCP_RELATIVE to simplify
        expressions.
        (cygdrive_flag): New global flag.
        (long_options): Add --proc-cygdrive option.
        (options): Add -U option.
        (usage): Add description for -U option.
        (do_sysfolders): Or cygdrive_flag to cygwin_conv_path call.
        (do_pathconv): Simply or absolute_flag to conv_func.  Or
        cygdrive_flag to conv_func.
        (do_options): Initalize absolute_flag to CCP_RELATIVE.  Initialize new
        cygdrive_flag.  Set absolute_flag to CCP_ABSOLUTE on -a.  Set
        cygdrive_flag to CCP_PROC_CYGDRIVE on -U.

        * new-features.xml (ov-new2.4): Document cygpath -U option.
        * utils.xml (cygpath): Ditto.
        * path.xml (func-cygwin-path): Add CCP_PROC_CYGDRIVE description.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2015-12-06 17:25:48 +01:00
parent 3ff65caea5
commit 5aa8817e3a
13 changed files with 131 additions and 45 deletions

View File

@ -1,3 +1,19 @@
2015-12-06 Corinna Vinschen <corinna@vinschen.de>
* include/sys/cygwin.h (CCP_PROC_CYGDRIVE): New flag.
* mount.cc (mount_info::cygdrive_posix_path): Take flag values rather
than just a trailing_slash_p bool. Emit /proc/cygdrive path if
CCP_PROC_CYGDRIVE flag is given.
(mount_info::conv_to_posix_path): Take flag values rather than just
a keep_rel_p bool. Rename _p variables. Print flag value as hex in
debug_printf. Call cygdrive_posix_path with flag values.
* mount.h (mount_info::cygdrive_posix_path): Accommodate above change
in declaration.
(mount_info::conv_to_posix_path): Ditto.
* fhandler_process.cc (format_process_exename): Accommodate change to
mount_info::conv_to_posix_path.
* path.cc (cygwin_conv_path): Ditto.
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
* dcrt0.cc (dll_crt0_0): On 64 bit, set wow64_needs_stack_adjustment

View File

@ -540,7 +540,7 @@ format_process_exename (void *data, char *&destbuf)
stpcpy (buf, "<defunct>");
else
{
mount_table->conv_to_posix_path (p->progname, buf, 1);
mount_table->conv_to_posix_path (p->progname, buf, CCP_RELATIVE);
len = strlen (buf);
if (len > 4)
{

View File

@ -2,7 +2,7 @@
/* sys/cygwin.h
Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
2009, 2010, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc.
This file is part of Cygwin.
@ -57,8 +57,10 @@ enum
CCP_CONVTYPE_MASK = 3,
/* Or these values to the above as needed. */
CCP_ABSOLUTE = 0, /* Request absolute path (default). */
CCP_RELATIVE = 0x100 /* Request to keep path relative. */
CCP_ABSOLUTE = 0, /* Request absolute path (default). */
CCP_RELATIVE = 0x100, /* Request to keep path relative. */
CCP_PROC_CYGDRIVE = 0x200 /* Request to return /proc/cygdrive
path (only with CCP_*_TO_POSIX). */
};
typedef unsigned int cygwin_conv_path_t;

View File

@ -791,14 +791,28 @@ mount_info::get_mounts_here (const char *parent_dir, int parent_dir_len,
/* cygdrive_posix_path: Build POSIX path used as the
mount point for cygdrives created when there is no other way to
obtain a POSIX path from a Win32 one. */
obtain a POSIX path from a Win32 one.
Recognized flag values:
- 0x001: Add trailing slash.
- 0x200 == CCP_PROC_CYGDRIVE: Return /proc/cygdrive rather than actual
cygdrive prefix. */
void
mount_info::cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p)
mount_info::cygdrive_posix_path (const char *src, char *dst, int flags)
{
int len = cygdrive_len;
int len;
memcpy (dst, cygdrive, len + 1);
if (flags & CCP_PROC_CYGDRIVE)
{
len = sizeof ("/proc/cygdrive/") - 1;
memcpy (dst, "/proc/cygdrive/", len + 1);
}
else
{
len = cygdrive_len;
memcpy (dst, cygdrive, len + 1);
}
/* Now finish the path off with the drive letter to be used.
The cygdrive prefix always ends with a trailing slash so
@ -816,7 +830,7 @@ mount_info::cygdrive_posix_path (const char *src, char *dst, int trailing_slash_
n = 2;
strcpy (dst + len, src + n);
}
slashify (dst, dst, trailing_slash_p);
slashify (dst, dst, !!(flags & 0x1));
}
int
@ -855,7 +869,7 @@ mount_info::cygdrive_win32_path (const char *src, char *dst, int& unit)
/* src_path is a wide Win32 path. */
int
mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
int keep_rel_p)
int ccp_flags)
{
bool changed = false;
if (!wcsncmp (src_path, L"\\\\?\\", 4))
@ -870,7 +884,7 @@ mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_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);
int ret = conv_to_posix_path (buf, posix_path, ccp_flags);
if (changed)
src_path[0] = L'C';
return ret;
@ -878,23 +892,22 @@ mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
int
mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
int keep_rel_p)
int ccp_flags)
{
int src_path_len = strlen (src_path);
int relative_path_p = !isabspath (src_path);
int trailing_slash_p;
int relative = !isabspath (src_path);
int append_slash;
if (src_path_len <= 1)
trailing_slash_p = 0;
append_slash = 0;
else
{
const char *lastchar = src_path + src_path_len - 1;
trailing_slash_p = isdirsep (*lastchar) && lastchar[-1] != ':';
append_slash = isdirsep (*lastchar) && lastchar[-1] != ':';
}
debug_printf ("conv_to_posix_path (%s, %s, %s)", src_path,
keep_rel_p ? "keep-rel" : "no-keep-rel",
trailing_slash_p ? "add-slash" : "no-add-slash");
debug_printf ("conv_to_posix_path (%s, 0x%x, %s)", src_path, ccp_flags,
append_slash ? "add-slash" : "no-add-slash");
MALLOC_CHECK;
if (src_path_len >= NT_MAX_PATH)
@ -906,7 +919,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
/* FIXME: For now, if the path is relative and it's supposed to stay
that way, skip mount table processing. */
if (keep_rel_p && relative_path_p)
if ((ccp_flags & CCP_RELATIVE) && relative)
{
slashify (src_path, posix_path, 0);
debug_printf ("%s = conv_to_posix_path (%s)", posix_path, src_path);
@ -953,8 +966,9 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
strcat (posix_path, "/");
if (nextchar)
slashify (p,
posix_path + addslash + (mi.posix_pathlen == 1 ? 0 : mi.posix_pathlen),
trailing_slash_p);
posix_path + addslash + (mi.posix_pathlen == 1
? 0 : mi.posix_pathlen),
append_slash);
if (cygheap->root.exists ())
{
@ -972,7 +986,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
{
const char *p = pathbuf + cygheap->root.native_length ();
if (*p)
slashify (p, posix_path, trailing_slash_p);
slashify (p, posix_path, append_slash);
else
{
posix_path[0] = '/';
@ -987,12 +1001,12 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
caller must want an absolute path (otherwise we would have returned
above). So we always return an absolute path at this point. */
if (isdrive (pathbuf))
cygdrive_posix_path (pathbuf, posix_path, trailing_slash_p);
cygdrive_posix_path (pathbuf, posix_path, append_slash | ccp_flags);
else
{
/* The use of src_path and not pathbuf here is intentional.
We couldn't translate the path, so just ensure no \'s are present. */
slashify (src_path, posix_path, trailing_slash_p);
slashify (src_path, posix_path, append_slash);
}
out:

View File

@ -195,16 +195,15 @@ class mount_info
unsigned set_flags_from_win32_path (const char *path);
int conv_to_win32_path (const char *src_path, char *dst, device&,
unsigned *flags = NULL);
int conv_to_posix_path (PWCHAR src_path, char *posix_path,
int keep_rel_p);
int conv_to_posix_path (PWCHAR src_path, char *posix_path, int ccp_flags);
int conv_to_posix_path (const char *src_path, char *posix_path,
int keep_rel_p);
int ccp_flags);
struct mntent *getmntent (int x);
int write_cygdrive_info (const char *cygdrive_prefix, unsigned flags);
int get_cygdrive_info (char *user, char *system, char* user_flags,
char* system_flags);
void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
void cygdrive_posix_path (const char *src, char *dst, int flags);
int get_mounts_here (const char *parent_dir, int,
PUNICODE_STRING mount_points,
PUNICODE_STRING cygd);

View File

@ -3342,7 +3342,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
char *buf = NULL;
PWCHAR path = NULL;
int error = 0;
bool relative = !!(what & CCP_RELATIVE);
int how = what & ~CCP_CONVTYPE_MASK;
what &= CCP_CONVTYPE_MASK;
int ret = -1;
@ -3360,7 +3360,8 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
{
p.check ((const char *) from,
PC_POSIX | PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP
| PC_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
| PC_NO_ACCESS_CHECK | PC_NOWARN
| ((how & CCP_RELATIVE) ? PC_NOFULL : 0));
if (p.error)
{
set_errno (p.error);
@ -3393,7 +3394,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
backslash ".\\" in the Win32 path. That's a result of the
conversion in normalize_posix_path. This should not occur
so the below code is just a band-aid. */
if (relative && !strcmp ((const char *) from, ".")
if ((how & CCP_RELATIVE) && !strcmp ((const char *) from, ".")
&& !strcmp (buf, ".\\"))
{
lsiz = 2;
@ -3404,14 +3405,15 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
case CCP_POSIX_TO_WIN_W:
p.check ((const char *) from,
PC_POSIX | PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP
| PC_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
| PC_NO_ACCESS_CHECK | PC_NOWARN
| ((how & CCP_RELATIVE) ? PC_NOFULL : 0));
if (p.error)
{
set_errno (p.error);
__leave;
}
/* Relative Windows paths are always restricted to MAX_PATH chars. */
if (relative && !isabspath (p.get_win32 ())
if ((how & CCP_RELATIVE) && !isabspath (p.get_win32 ())
&& sys_mbstowcs (NULL, 0, p.get_win32 ()) > MAX_PATH)
{
/* Recreate as absolute path. */
@ -3455,7 +3457,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
lsiz += ro_u_globalroot.Length / sizeof (WCHAR);
}
/* TODO: Same ".\\" band-aid as in CCP_POSIX_TO_WIN_A case. */
if (relative && !strcmp ((const char *) from, ".")
if ((how & CCP_RELATIVE) && !strcmp ((const char *) from, ".")
&& !wcscmp (path, L".\\"))
{
lsiz = 2;
@ -3466,7 +3468,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
case CCP_WIN_A_TO_POSIX:
buf = tp.c_get ();
error = mount_table->conv_to_posix_path ((const char *) from, buf,
relative);
how);
if (error)
{
set_errno (p.error);
@ -3477,7 +3479,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
case CCP_WIN_W_TO_POSIX:
buf = tp.c_get ();
error = mount_table->conv_to_posix_path ((const PWCHAR) from, buf,
relative);
how);
if (error)
{
set_errno (error);

View File

@ -22,6 +22,9 @@ What's new:
who created the file. This only works for files and directories
created by Cygwin processes.
- cygpath has a new -U option, which creates cygdrive paths using the
unambiguous /proc/cygdrive prefix.
- New API: rpmatch.

View File

@ -1,3 +1,9 @@
2015-12-06 Corinna Vinschen <corinna@vinschen.de>
* new-features.xml (ov-new2.4): Document cygpath -U option.
* utils.xml (cygpath): Ditto.
* path.xml (func-cygwin-path): Add CCP_PROC_CYGDRIVE description.
2015-11-25 David Macek <david.macek.0@gmail.com>
* faq-using.xml: Add MacType to the BLODA. Fix formatting.

View File

@ -31,6 +31,11 @@ who created the file. This only works for files and directories
created by Cygwin processes.
</para></listitem>
<listitem><para>
cygpath has a new -U option, which creates cygdrive paths using the
unambiguous /proc/cygdrive prefix.
</para></listitem>
<listitem><para>
New API: rpmatch.
</para></listitem>

View File

@ -54,8 +54,10 @@ relative paths in relative notation. Creating absolute paths is the
default.</para>
<programlisting>
CCP_ABSOLUTE = 0, /* Request absolute path (default). */
CCP_RELATIVE = 0x100 /* Request to keep path relative. */
CCP_ABSOLUTE = 0, /* Request absolute path (default). */
CCP_RELATIVE = 0x100 /* Request to keep path relative. */
CCP_PROC_CYGDRIVE = 0x200 /* Request to return /proc/cygdrive path
(only with CCP_*_TO_POSIX). */
</programlisting>
<para><parameter>size</parameter> is the size of the buffer pointed to

View File

@ -315,6 +315,8 @@ Path conversion options:
-a, --absolute output absolute path
-l, --long-name print Windows long form of NAMEs (with -w, -m only)
-p, --path NAME is a PATH list (i.e., '/bin:/usr/bin')
-U, --proc-cygdrive Emit /proc/cygdrive path instead of cygdrive prefix
when converting Windows path to UNIX path.
-s, --short-name print DOS (short) form of NAMEs (with -w, -m only)
-C, --codepage CP print DOS, Windows, or mixed pathname in Windows
codepage CP. CP can be a numeric codepage identifier,
@ -380,6 +382,16 @@ Other options:
graphical tools like Windows Explorer might expect pathnames in the
current ANSI codepage.</para>
<para>The <literal>-U</literal> option allows to use cygpath to create
unambiguous Unix paths pointing outside the Cygwin tree andf thus having
no explicit POSIX path. Those paths usually use the cygdrive prefix.
However, the cygdrive prefix can be changed by the user, so symbolic links
created using the cygdrive prefix are not foolproof. With
<literal>-U</literal> cygpath will generate such paths prepended by the
virtual <pathname>/proc/cygdrive</pathname> symbolic link, which will
never change, so the created path is safe against changing the cygdrive
prefix.</para>
<para>The <literal>-C</literal> option takes a single parameter:</para>
<itemizedlist spacing="compact">
<listitem>

View File

@ -1,3 +1,18 @@
2015-12-06 Corinna Vinschen <corinna@vinschen.de>
* cygpath.cc (absolute_flag): Initialize to CCP_RELATIVE to simplify
expressions.
(cygdrive_flag): New global flag.
(long_options): Add --proc-cygdrive option.
(options): Add -U option.
(usage): Add description for -U option.
(do_sysfolders): Or cygdrive_flag to cygwin_conv_path call.
(do_pathconv): Simply or absolute_flag to conv_func. Or
cygdrive_flag to conv_func.
(do_options): Initalize absolute_flag to CCP_RELATIVE. Initialize new
cygdrive_flag. Set absolute_flag to CCP_ABSOLUTE on -a. Set
cygdrive_flag to CCP_PROC_CYGDRIVE on -U.
2015-11-26 Michael Kwasigroch <mkwasigr@web.de>
* kill.cc (strsigno): Don't call sys_sigabbrev for signal 0.

View File

@ -1,6 +1,6 @@
/* cygpath.cc -- convert pathnames between Windows and Unix format
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
2009, 2010, 2011, 2012, 2013, 2015 Red Hat, Inc.
This file is part of Cygwin.
@ -36,7 +36,7 @@ details. */
static char *prog_name;
static char *file_arg, *output_arg;
static int path_flag, unix_flag, windows_flag, absolute_flag;
static int path_flag, unix_flag, windows_flag, absolute_flag, cygdrive_flag;
static int shortname_flag, longname_flag;
static int ignore_flag, allusers_flag, output_flag;
static int mixed_flag, options_from_file_flag, mode_flag;
@ -56,6 +56,7 @@ static struct option long_options[] = {
{(char *) "mode", no_argument, NULL, 'M'},
{(char *) "option", no_argument, NULL, 'o'},
{(char *) "path", no_argument, NULL, 'p'},
{(char *) "proc-cygdrive", no_argument, NULL, 'U'},
{(char *) "short-name", no_argument, NULL, 's'},
{(char *) "type", required_argument, NULL, 't'},
{(char *) "unix", no_argument, NULL, 'u'},
@ -73,7 +74,7 @@ static struct option long_options[] = {
{0, no_argument, 0, 0}
};
static char options[] = "ac:df:hilmMopst:uVwAC:DHOPSWF:";
static char options[] = "ac:df:hilmMopst:uUVwAC:DHOPSWF:";
static void
usage (FILE * stream, int status)
@ -101,6 +102,8 @@ Path conversion options:\n\
-a, --absolute output absolute path\n\
-l, --long-name print Windows long form of NAMEs (with -w, -m only)\n\
-p, --path NAME is a PATH list (i.e., '/bin:/usr/bin')\n\
-U, --proc-cygdrive Emit /proc/cygdrive path instead of cygdrive prefix\n\
when converting Windows path to UNIX path.\n\
-s, --short-name print DOS (short) form of NAMEs (with -w, -m only)\n\
-C, --codepage CP print DOS, Windows, or mixed pathname in Windows\n\
codepage CP. CP can be a numeric codepage identifier,\n\
@ -607,7 +610,8 @@ do_sysfolders (char option)
}
else if (!windows_flag)
{
if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, wbuf, buf, PATH_MAX))
if (cygwin_conv_path (CCP_WIN_W_TO_POSIX | cygdrive_flag,
wbuf, buf, PATH_MAX))
fprintf (stderr, "%s: error converting \"%ls\" - %s\n",
prog_name, wbuf, strerror (errno));
}
@ -652,7 +656,7 @@ do_pathconv (char *filename)
bool print_tmp = false;
cygwin_conv_path_t conv_func =
(unix_flag ? CCP_WIN_W_TO_POSIX : CCP_POSIX_TO_WIN_W)
| (absolute_flag ? CCP_ABSOLUTE : CCP_RELATIVE);
| absolute_flag | cygdrive_flag;
if (!filename || !filename[0])
{
@ -792,6 +796,8 @@ do_options (int argc, char **argv, int from_file)
output_flag = 0;
mode_flag = 0;
codepage = 0;
cygdrive_flag = 0;
absolute_flag = CCP_RELATIVE;
if (!from_file)
options_from_file_flag = 0;
optind = 0;
@ -801,7 +807,7 @@ do_options (int argc, char **argv, int from_file)
switch (c)
{
case 'a':
absolute_flag = 1;
absolute_flag = CCP_ABSOLUTE;
break;
case 'c':
@ -883,6 +889,10 @@ do_options (int argc, char **argv, int from_file)
allusers_flag = 1;
break;
case 'U':
cygdrive_flag = CCP_PROC_CYGDRIVE;
break;
case 'C':
if (!optarg)
usage (stderr, 1);