diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 747e8765e..2e10a382b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2015-12-06 Corinna Vinschen + + * 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 * dcrt0.cc (dll_crt0_0): On 64 bit, set wow64_needs_stack_adjustment diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 4e4c6145c..f0423f30f 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -540,7 +540,7 @@ format_process_exename (void *data, char *&destbuf) stpcpy (buf, ""); 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) { diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index 2ec6086b0..6c720e0dd 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -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; diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index c04805bfc..68977fd58 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -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: diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index 986f9a96b..c78fbc137 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -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); diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index ce17c0802..d86cf99a7 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -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); diff --git a/winsup/cygwin/release/2.4.0 b/winsup/cygwin/release/2.4.0 index 73d45e5a3..9c8144ea3 100644 --- a/winsup/cygwin/release/2.4.0 +++ b/winsup/cygwin/release/2.4.0 @@ -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. diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog index e5477cee2..f9ae2b54e 100644 --- a/winsup/doc/ChangeLog +++ b/winsup/doc/ChangeLog @@ -1,3 +1,9 @@ +2015-12-06 Corinna Vinschen + + * 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 * faq-using.xml: Add MacType to the BLODA. Fix formatting. diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 21bc6911f..98a9e6c14 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -31,6 +31,11 @@ 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. diff --git a/winsup/doc/path.xml b/winsup/doc/path.xml index bea67980a..81d4c3f35 100644 --- a/winsup/doc/path.xml +++ b/winsup/doc/path.xml @@ -54,8 +54,10 @@ relative paths in relative notation. Creating absolute paths is the default. - 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). */ size is the size of the buffer pointed to diff --git a/winsup/doc/utils.xml b/winsup/doc/utils.xml index f48bfaec0..d0f871efe 100644 --- a/winsup/doc/utils.xml +++ b/winsup/doc/utils.xml @@ -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. + The -U 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 + -U cygpath will generate such paths prepended by the + virtual /proc/cygdrive symbolic link, which will + never change, so the created path is safe against changing the cygdrive + prefix. + The -C option takes a single parameter: diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index de00ef71b..77572209d 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,3 +1,18 @@ +2015-12-06 Corinna Vinschen + + * 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 * kill.cc (strsigno): Don't call sys_sigabbrev for signal 0. diff --git a/winsup/utils/cygpath.cc b/winsup/utils/cygpath.cc index 6094eb7eb..0fbb2e90e 100644 --- a/winsup/utils/cygpath.cc +++ b/winsup/utils/cygpath.cc @@ -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);