public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
From: Ken Brown <kbrown@sourceware.org>
To: cygwin-cvs@sourceware.org
Subject: [newlib-cygwin] Cygwin: mkdir and rmdir: treat drive names specially
Date: Mon, 07 Oct 2019 20:13:00 -0000	[thread overview]
Message-ID: <20191007201320.28468.qmail@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=c561a625af9bdbcc475214036ebbedbcae1cb702

commit c561a625af9bdbcc475214036ebbedbcae1cb702
Author: Ken Brown <kbrown@cornell.edu>
Date:   Fri Sep 27 14:00:52 2019 -0400

    Cygwin: mkdir and rmdir: treat drive names specially
    
    If the directory name has the form 'x:' followed by one or more
    slashes or backslashes, and if there's at least one backslash, assume
    that the user is referring to 'x:\', the root directory of drive x,
    and don't strip the backslash.
    
    Previously all trailing slashes and backslashes were stripped, and the
    name was treated as a relative file name containing a literal colon.
    
    Addresses https://cygwin.com/ml/cygwin/2019-08/msg00334.html.

Diff:
---
 winsup/cygwin/dir.cc        | 33 ++++++++++++++++++++++++++++-----
 winsup/cygwin/release/3.1.0 |  4 ++++
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index 29a9dfa..3429fe0 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -313,15 +313,27 @@ mkdir (const char *dir, mode_t mode)
       /* Following Linux, and intentionally ignoring POSIX, do not
 	 resolve the last component of DIR if it is a symlink, even if
 	 DIR has a trailing slash.  Achieve this by stripping trailing
-	 slashes or backslashes.  */
+	 slashes or backslashes.
+
+	 Exception: If DIR == 'x:' followed by one or more slashes or
+	 backslashes, and if there's at least one backslash, assume
+	 that the user is referring to the root directory of drive x.
+	 Retain one backslash in this case.  */
       if (isdirsep (dir[strlen (dir) - 1]))
 	{
 	  /* This converts // to /, but since both give EEXIST, we're okay.  */
 	  char *buf;
 	  char *p = stpcpy (buf = tp.c_get (), dir) - 1;
+	  bool msdos = false;
 	  dir = buf;
 	  while (p > dir && isdirsep (*p))
-	    *p-- = '\0';
+	    {
+	      if (*p == '\\')
+		msdos = true;
+	      *p-- = '\0';
+	    }
+	  if (msdos && p == dir + 1 && isdrive (dir))
+	    p[1] = '\\';
 	}
       if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
 	__leave;   /* errno already set */;
@@ -360,20 +372,31 @@ rmdir (const char *dir)
 	  set_errno (ENOENT);
 	  __leave;
 	}
-
       /* Following Linux, and intentionally ignoring POSIX, do not
 	 resolve the last component of DIR if it is a symlink, even if
 	 DIR has a trailing slash.  Achieve this by stripping trailing
-	 slashes or backslashes.  */
+	 slashes or backslashes.
+
+	 Exception: If DIR == 'x:' followed by one or more slashes or
+	 backslashes, and if there's at least one backslash, assume
+	 that the user is referring to the root directory of drive x.
+	 Retain one backslash in this case.  */
       if (isdirsep (dir[strlen (dir) - 1]))
 	{
 	  /* This converts // to /, but since both give ENOTEMPTY,
 	     we're okay.  */
 	  char *buf;
 	  char *p = stpcpy (buf = tp.c_get (), dir) - 1;
+	  bool msdos = false;
 	  dir = buf;
 	  while (p > dir && isdirsep (*p))
-	    *p-- = '\0';
+	    {
+	      if (*p == '\\')
+		msdos = true;
+	      *p-- = '\0';
+	    }
+	  if (msdos && p == dir + 1 && isdrive (dir))
+	    p[1] = '\\';
 	}
       if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
 	__leave;   /* errno already set */;
diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0
index f3abff1..3f2f3c8 100644
--- a/winsup/cygwin/release/3.1.0
+++ b/winsup/cygwin/release/3.1.0
@@ -87,3 +87,7 @@ Bug Fixes
 
 - Fix an assertion failure on an invalid path.
   Addresses: https://cygwin.com/ml/cygwin/2019-09/msg00228.html
+
+- If the argument to mkdir(2) or rmdir(2) is 'x:\', don't strip the
+  trailing backslash.
+  Addresses: https://cygwin.com/ml/cygwin/2019-08/msg00334.html


                 reply	other threads:[~2019-10-07 20:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191007201320.28468.qmail@sourceware.org \
    --to=kbrown@sourceware.org \
    --cc=cygwin-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).