about summary refs log tree commit diff
path: root/pkgs/tools/misc/coreutils
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2015-10-03 13:33:13 +0200
committerVladimír Čunát <vcunat@gmail.com>2015-10-03 13:33:37 +0200
commit5227fb1dd53fcb5918b9342dff4868f4ad68427e (patch)
treed6cd521e3f67944031216a27f740f28f22b73b41 /pkgs/tools/misc/coreutils
parentd6dd3b8bd1eaeeb21dfdb5051cd4732c748ce5d7 (diff)
parent33373d939a19f465228ddede6d38ce9032b5916b (diff)
Merge commit staging+systemd into closure-size
Many non-conflict problems weren't (fully) resolved in this commit yet.
Diffstat (limited to 'pkgs/tools/misc/coreutils')
-rw-r--r--pkgs/tools/misc/coreutils/coreutils-8.23-4.cygwin.patch1259
-rw-r--r--pkgs/tools/misc/coreutils/default.nix11
2 files changed, 1267 insertions, 3 deletions
diff --git a/pkgs/tools/misc/coreutils/coreutils-8.23-4.cygwin.patch b/pkgs/tools/misc/coreutils/coreutils-8.23-4.cygwin.patch
new file mode 100644
index 0000000000000..2f69347ffabdb
--- /dev/null
+++ b/pkgs/tools/misc/coreutils/coreutils-8.23-4.cygwin.patch
@@ -0,0 +1,1259 @@
+--- coreutils-8.23/ChangeLog	2014-07-18 15:22:24.000000000 -0700
++++ coreutils-8.23/ChangeLog	2014-10-13 08:56:50.775188900 -0700
+@@ -1,3 +1,220 @@
++2014-10-13  U-WIN-RSJ0SJPBR3E\Administrator  <Administrator@WIN-KQ1OCEBI2E8>
++
++	Cygwin release 8.23-4
++	* copy.c (copy_internal): Fix typo that broke recursive copy
++	when dealing with directories.
++
++2014-09-24  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.23-3
++	* lib/cygwin.c (cygwin_spelling): Skip .exe magic if .exe is
++	already present.  Also honor .exe magic on symlinks.
++	* lib/same.c (same_name): Treat files as same if only difference
++	is .exe magic.
++	* copy.c (copy): Move symlink special casing here.
++	* install.c (strip): Update caller.
++	* ls.c (gobble_file): Likewise.
++	* stat.c (do_statfs, do_stat): Likewise.
++
++2014-08-12  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.23-2.
++	Drop hostname.
++
++2014-08-01  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.23-1.
++	* configure.ac: Disable stdbuf.
++	* lib/local.mk: Upstream switched to flat make, impacting how
++	we build local cygwin.c code.
++	* lib/canonicalize.c: Accepted upstream.
++	* lib/file-has-acl.c: Likewise.
++	* realpath.c: Likewise.
++	* su.c: Upstream dropped su.
++	* Makefile.am: Drop su changes.
++	* chroot.c: Adapt to new upstream code.
++
++2012-02-04  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.15-1.
++	* lib/fts.c: Early gnulib fix is now upstream.
++	* lib/canonicalize.c: Backport gnulib fix for /// -> /.
++	* realpath.c: Backport gnulib fix for --relative-to.
++
++2011-10-27  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.14-1.
++	* lib/ftc.c: Backport gnulib fix to make rm close before rmdir.
++	* lib/cygwin.c (cygwin_spelling): Fix logic when 'f' and 'f.exe'
++	exist but are different files.
++	* stat.c: Fix --append-exe.
++
++2011-02-04  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.10-1.
++
++2010-12-24  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.8-1.
++	* lib/mountlist.c (ME_REMOTE): Restore previous cygwin hack to
++	determine remote drives, lost since 6.11-1.
++
++2010-04-29  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.5-1.
++
++2010-03-11  Eric Blake  <eblake@redhat.com>
++
++	Cygwin release 8.4-1.
++	* lib/xfreopen.c (xfreopen): Consolidate workaround for broken
++	freopen usage into one place.
++	* copy.c (copy): Reinstate .exe magic handling when copying
++	files with implicit .exe.
++
++2008-12-13  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 7.0-1.
++
++2008-06-02  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 6.12-1.
++
++2008-05-12  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 6.11-1, requires cygwin 1.7.0.
++	* lib/cygwin.h (CYGWIN_APPEND_EXE): Accomodate new PATH_MAX.
++	* lib/cygwin.c (cygwin_spelling): Accomodate new trailing
++	`.' semantics.
++	* lib/same.c (same_name): Accomodate new PATH_MAX.
++
++2008-01-24  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 6.10-1.
++	* lib/hash-triple.c (triple_hash): Hash case-insensitively.
++	* lib/hash-pjw.h (hash_pjw_case): New interface.
++	* lib/hash-pjw.c (hash_pjw_case): New function.
++	* chcon.c (main): Support my root_dev_ino tweaks.
++
++2007-08-21  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 6.9-5.
++	* same.c (same_name): Detect same file differing only by case.
++	* copy.c (same_file_ok): Add parameter to detect when case
++	change is being attempted.
++	(triple_hash): Hash names case-insensitively.
++	(copy_internal): Accommodate case-change attempts.
++	* mv.c (do_move): Allow 'mv foo/ Foo/' as shorthand for
++	'mv -T foo/ Foo/'.
++
++2007-07-23  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 6.9-4.
++	* dd.c (main): Fix typo in earlier cygwin patch.
++
++2007-05-29  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 6.9-3.
++	* cksum.c (main): Don't lose append mode.
++	* md5sum.c (main): Likewise.
++	* cat.c (main): Likewise.
++	* head.c (main): Likewise.
++	* tac.c (main): Likewise.
++	* tail.c (main): Likewise.
++	* tee.c (main): Likewise.
++	* tr.c (main): Likewise.
++
++2006-11-24  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 6.6-2.
++	* lib/cygwin.c (cygwin_spelling): Work even with old-style
++	symlinks, which lacked .lnk suffix.
++
++2006-04-14  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 5.94-5. Experimental only, depends on cygwin
++	snapshot 20060329 or later.
++	* dd.c (main): Default to binary mode.
++	* system.h (rpl_freopen): Remove this hack, now that cygwin
++	freopen(NULL) works.
++	* lib/quotearg.c (quote_eight_bit): New variable, so I can...
++	(quotearg_buffer_restyled): treat 8-bit	characters as printable
++	when outputting to a terminal.
++	* lib/quote.c (quote_n): Use it.
++
++2006-02-28  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 5.94-4. Experimental only, depends on cygwin
++	snapshot 20060227 or later.
++	* lib/root-dev-ino.h (struct root_dev_ino): New struct.
++	(ROOT_DEV_INO_CHECK, ROOT_DEV_INO_WARN): Also track //.
++	* lib/root-dev-ino.c (get_root_dev_ino): Also track //.
++	* chmod.c (root_dev_ino): Use new type.
++	(main): Ditto.
++	* chown-core.h (struct Chown_option): Ditto.
++	* chown.c (main): Ditto.
++	* remove.h (struct rm_options): Ditto.
++	* rm.c (main): Ditto.
++	* pwd.c (robust_getcwd): Ditto.  Also fix bug when in / or //.
++
++2006-01-24  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 5.93-3, depends on cygwin-1.5.19-1 or later.
++	* cksum.c (main): Always output binary files.
++	* md5sum.c (main): Likewise.
++	* su.c (correct_password): On NT machines, attempt
++	passwordless login first, and give better error message if
++	password check fails.  I still don't know how to distinguish
++	between insufficient privileges vs. incorrect password.
++	* dircolors.c (main): Silence warning from tcsh 6.14.00.
++
++2005-10-15  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 5.90-3, depends on snapshot 20051003 or later (will
++	become cygwin 1.5.19).
++	* doc/coreutils.texi (ls invocation, stat invocation): Document
++	--append-exe.
++	* ls.c (usage): Ditto.
++	(gobble_file): Append .exe as needed when requested.
++	* stat.c (usage): Document --append-exe.
++	(do_stat, do_statfs): Append .exe as needed when requested.
++
++2005-10-08  Eric Blake  <ebb9@byu.net>
++
++	Cygwin release 5.90-2, depends on snapshot 20051003 or later (will
++	become cygwin 1.5.19).
++	* lib/mkdir-p.c (make_dir_parents): Fix bug in last patch.
++	* lib/cygwin.h (CYGWIN_APPEND_EXE): Factor into common macro.
++	* copy.c (copy): Use new macro.
++	* install.c (strip): Ditto.
++	* ln.c (do_link): Ditto.
++
++2005-07-13  Eric Blake  <ebb9@byu.net>
++
++	* doc/coreutils.texi (ln invocation): Document --disable-exe-magic.
++	* ln.c (usage): Likewise.
++	(do_link): Skip .exe magic when requested.
++
++2005-07-12  Eric Blake  <ebb9@byu.net>
++
++	* lib/cygwin.c (cygwin_spelling): Don't append .exe to directories.
++	Make sure .exe exists before returning 1, because otherwise
++	virtual directories such as /cygdrive have problems.
++
++2005-07-07  Eric Blake  <ebb9@byu.net>
++
++	* lib/cygwin.h: New file, defining cygwin_spelling.
++	* lib/cygwin.c: New file.
++	* lib/Makefile.am: Compile it.
++	* copy.c (copy_internal, copy): Use new cygwin_spelling() to
++	undo .exe magic.
++	* link.c (do_link): Likewise.
++	* install.c (strip): Likewise.
++
++2005-01-03  Corinna Vinschen  <corinna@vinschen.de>
++
++	* install.c (strip): Check for .exe here since strip doesn't.
++
++
+ 2014-07-18  Pádraig Brady  <P@draigBrady.com>
+ 
+ 	version 8.23
+--- coreutils-8.23/configure.ac	2014-07-17 18:40:57.000000000 -0700
++++ coreutils-8.23/configure.ac	2014-10-13 08:30:37.165262300 -0700
+@@ -473,7 +473,7 @@ AC_COMPILE_IFELSE(
+   [stdbuf_supported=yes],
+   [stdbuf_supported=no])
+ AC_MSG_RESULT([$stdbuf_supported])
+-if test "$stdbuf_supported" = "yes"; then
++if test "$stdbuf_supported" = "yes" && test -z "$EXEEXT"; then
+   gl_ADD_PROG([optional_bin_progs], [stdbuf])
+ fi
+ 
+--- coreutils-8.23/doc/coreutils.texi	2014-07-13 15:09:52.000000000 -0700
++++ coreutils-8.23/doc/coreutils.texi	2014-10-13 08:30:37.180881200 -0700
+@@ -7838,6 +7838,14 @@ These options change how file names them
+ 
+ @table @samp
+ 
++@item --append-exe
++@opindex --append-exe
++@cindex appending exe on cygwin
++Cygwin only: Cygwin normally performs @samp{.exe} magic, where a
++command line argument typed without an .exe extension transparently
++refers to the existing file with an extension.  Specifying this option
++will make the .exe show if cygwin magic was involved.
++
+ @item -b
+ @itemx --escape
+ @itemx --quoting-style=escape
+@@ -11799,6 +11807,14 @@ With this option, @command{stat} acts on
+ by each symbolic link argument.
+ Without it, @command{stat} acts on any symbolic link argument directly.
+ 
++@item --append-exe
++@opindex --append-exe
++@cindex appending exe on cygwin
++Cygwin only: Cygwin normally performs .exe magic, where a command line
++argument typed without an .exe extension transparently refers to the
++existing file with an extension.  Specifying this option will make
++the .exe show if cygwin magic was involved.
++
+ @item -f
+ @itemx --file-system
+ @opindex -f
+--- coreutils-8.23/lib/cygwin.c	1969-12-31 16:00:00.000000000 -0800
++++ coreutils-8.23/lib/cygwin.c	2014-10-13 08:30:37.180881200 -0700
+@@ -0,0 +1,67 @@
++/* cygwin.c - helper functions unique to Cygwin
++
++   Copyright (C) 2005, 2006, 2008, 2011 Free Software Foundation, Inc.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3, or (at your option)
++   any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software Foundation,
++   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++   Written by Eric Blake.  */
++
++#include <config.h>
++
++#include "cygwin.h"
++
++#include <errno.h>
++#include <limits.h>
++#include <string.h>
++#include <unistd.h>
++
++/* Return -1 if PATH is not found, 0 if PATH will not have .exe
++   appended (it is possible that a PATH that does not exist still
++   returns 0 instead of -1, or fails for a PATH that exists but cannot
++   be stat'ed), and positive if PATH has ".exe" automatically appended
++   by cygwin (1 if PATH is a symlink, 2 otherwise).  Won't change errno.  */
++
++int
++cygwin_spelling (char const *path)
++{
++  int saved_errno = errno;
++  int result = 0; /* Start with assumption that PATH is okay.  */
++  int len;
++  struct stat st1;
++  struct stat st2;
++  char *path_exe;
++
++  if (! path || ! *path || len > PATH_MAX)
++    /* PATH will cause EINVAL or ENAMETOOLONG, treat it as non-existing.  */
++    return -1;
++  len = strlen (path);
++  if (path[len - 1] == '/'
++      || (len > 4 && !strcasecmp (&path[len - 4], ".exe")))
++    /* Don't change spelling if there is a trailing `/' or '.exe'.  */
++    return 0;
++  if (lstat (path, &st1) < 0 || S_ISDIR(st1.st_mode))
++    {
++      errno = saved_errno;
++      return -1;
++    }
++  path_exe = malloca (len + 5); /* adding ".exe" and NUL.  */
++  strcat (stpcpy (path_exe, path), ".exe");
++  if (lstat (path_exe, &st2) == 0 && st1.st_ino == st2.st_ino)
++    result = 1 + !S_ISLNK(st1.st_mode);
++  freea (path_exe);
++
++  errno = saved_errno;
++  return result;
++}
+--- coreutils-8.23/lib/cygwin.h	1969-12-31 16:00:00.000000000 -0800
++++ coreutils-8.23/lib/cygwin.h	2014-10-13 08:30:37.180881200 -0700
+@@ -0,0 +1,38 @@
++/* cygwin.h - helper functions unique to Cygwin
++
++   Copyright (C) 2005, 2006, 2008, 2010, 2011 Free Software Foundation, Inc.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3, or (at your option)
++   any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software Foundation,
++   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++   Written by Eric Blake.  */
++
++#ifndef CYGWIN_H
++# define CYGWIN_H 1
++
++#include "malloca.h"
++
++int cygwin_spelling (char const *);
++
++/* Append ".exe" to char *__NAME_ORIG, where __NAME is either NULL or
++   between __NAME_ORIG and the nul terminator.  Both params will be
++   evaluated more than once and assigned the new value.  The user must
++   later call freea(__NAME).  */
++#define CYGWIN_APPEND_EXE(__name, __name_orig)                          \
++  __name_orig = __name =                                                \
++    strcat (strcpy (malloca (strchr (__name ? __name : __name_orig, '\0') \
++                             - (__name_orig) + 5),                      \
++                    __name_orig), ".exe")
++
++#endif /* CYGWIN_H */
+--- coreutils-8.23/lib/hash-pjw.c	2014-05-29 05:05:50.000000000 -0700
++++ coreutils-8.23/lib/hash-pjw.c	2014-10-13 08:30:37.180881200 -0700
+@@ -19,6 +19,7 @@
+ 
+ #include "hash-pjw.h"
+ 
++#include <ctype.h>
+ #include <limits.h>
+ 
+ #define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
+@@ -38,3 +39,16 @@ hash_pjw (const void *x, size_t tablesiz
+ 
+   return h % tablesize;
+ }
++
++/* Likewise, but case-insensitive.  */
++size_t
++hash_pjw_case (const void *x, size_t tablesize)
++{
++  const unsigned char *s;
++  size_t h = 0;
++
++  for (s = x; *s; s++)
++    h = tolower (*s) + ((h << 9) | (h >> (SIZE_BITS - 9)));
++
++  return h % tablesize;
++}
+--- coreutils-8.23/lib/hash-pjw.h	2014-05-29 05:05:50.000000000 -0700
++++ coreutils-8.23/lib/hash-pjw.h	2014-10-13 08:30:37.180881200 -0700
+@@ -21,3 +21,4 @@
+    The result is platform dependent: it depends on the size of the 'size_t'
+    type and on the signedness of the 'char' type.  */
+ extern size_t hash_pjw (void const *x, size_t tablesize) _GL_ATTRIBUTE_PURE;
++extern size_t hash_pjw_case (void const *x, size_t tablesize) _GL_ATTRIBUTE_PURE;
+--- coreutils-8.23/lib/hash-triple.c	2014-05-29 05:05:50.000000000 -0700
++++ coreutils-8.23/lib/hash-triple.c	2014-10-13 08:30:37.180881200 -0700
+@@ -34,7 +34,13 @@ size_t
+ triple_hash (void const *x, size_t table_size)
+ {
+   struct F_triple const *p = x;
++#if !__CYGWIN__
+   size_t tmp = hash_pjw (p->name, table_size);
++#else // cygwin
++  /* Hash case-insensitively, to force collisions on names that differ by
++     case; copy.c can then account for case-insensitive renames. */
++  size_t tmp = hash_pjw_case (p->name, table_size);
++#endif
+ 
+   /* Ignoring the device number here should be fine.  */
+   return (tmp ^ p->st_ino) % table_size;
+--- coreutils-8.23/lib/local.mk	2013-12-04 06:48:30.000000000 -0800
++++ coreutils-8.23/lib/local.mk	2014-10-13 08:30:37.180881200 -0700
+@@ -3,3 +3,6 @@ include lib/gnulib.mk
+ # Allow "make distdir" to succeed before "make all" has run.
+ dist-hook: $(noinst_LIBRARIES)
+ .PHONY: dist-hook
++
++# Hook in cygwin helper
++lib_libcoreutils_a_SOURCES += lib/cygwin.c lib/cygwin.h
+--- coreutils-8.23/lib/root-dev-ino.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/lib/root-dev-ino.c	2014-10-13 08:30:37.180881200 -0700
+@@ -25,13 +25,17 @@
+ /* Call lstat to get the device and inode numbers for '/'.
+    Upon failure, return NULL.  Otherwise, set the members of
+    *ROOT_D_I accordingly and return ROOT_D_I.  */
+-struct dev_ino *
+-get_root_dev_ino (struct dev_ino *root_d_i)
++struct root_dev_ino *
++get_root_dev_ino (struct root_dev_ino *root_d_i)
+ {
+   struct stat statbuf;
+   if (lstat ("/", &statbuf))
+     return NULL;
+-  root_d_i->st_ino = statbuf.st_ino;
+-  root_d_i->st_dev = statbuf.st_dev;
++  root_d_i->single_slash.st_ino = statbuf.st_ino;
++  root_d_i->single_slash.st_dev = statbuf.st_dev;
++  if (lstat ("//", &statbuf))
++    return NULL;
++  root_d_i->double_slash.st_ino = statbuf.st_ino;
++  root_d_i->double_slash.st_dev = statbuf.st_dev;
+   return root_d_i;
+ }
+--- coreutils-8.23/lib/root-dev-ino.h	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/lib/root-dev-ino.h	2014-10-13 08:30:37.180881200 -0700
+@@ -21,19 +21,26 @@
+ # include "dev-ino.h"
+ # include "same-inode.h"
+ 
+-struct dev_ino *
+-get_root_dev_ino (struct dev_ino *root_d_i);
++struct root_dev_ino
++{
++  struct dev_ino single_slash;
++  struct dev_ino double_slash;
++};
++
++struct root_dev_ino *
++get_root_dev_ino (struct root_dev_ino *root_d_i);
+ 
+ /* These macros are common to the programs that support the
+    --preserve-root and --no-preserve-root options.  */
+ 
+ # define ROOT_DEV_INO_CHECK(Root_dev_ino, Dir_statbuf) \
+-    (Root_dev_ino && SAME_INODE (*Dir_statbuf, *Root_dev_ino))
++  (Root_dev_ino && (SAME_INODE (*Dir_statbuf, (Root_dev_ino)->single_slash) \
++                    || SAME_INODE (*Dir_statbuf, (Root_dev_ino)->double_slash)))
+ 
+ # define ROOT_DEV_INO_WARN(Dirname)					\
+   do									\
+     {									\
+-      if (STREQ (Dirname, "/"))						\
++      if (STREQ (Dirname, "/") || STREQ (Dirname, "//"))                \
+         error (0, 0, _("it is dangerous to operate recursively on %s"),	\
+                quote (Dirname));					\
+       else								\
+--- coreutils-8.23/lib/same.c	2014-05-29 05:05:50.000000000 -0700
++++ coreutils-8.23/lib/same.c	2014-10-13 08:30:37.180881200 -0700
+@@ -40,6 +40,13 @@
+ #include "error.h"
+ #include "same-inode.h"
+ 
++#if __CYGWIN__
++# include <sys/cygwin.h>
++# include "cygwin.h"
++# include "malloca.h"
++# include "memcasecmp.h"
++#endif
++
+ #ifndef MIN
+ # define MIN(a, b) ((a) < (b) ? (a) : (b))
+ #endif
+@@ -59,6 +66,45 @@ same_name (const char *source, const cha
+     (source_baselen == dest_baselen
+      && memcmp (source_basename, dest_basename, dest_baselen) == 0);
+   bool compare_dirs = identical_basenames;
++#if __CYGWIN__
++  /* If two names differ case-insensitively by only an '.exe' suffix,
++     do some sleuthing to see if .exe magic matters on the shorter
++     name.  Swapping the longer name to dest avoids duplication.  */
++  if (source_baselen == dest_baselen + 4)
++    {
++      char const *tmp_basename = source_basename;
++      size_t tmp_baselen = source_baselen;
++      source_basename = dest_basename;
++      source_baselen = dest_baselen;
++      dest_basename = tmp_basename;
++      dest_baselen = tmp_baselen;
++    }
++  if (source_baselen + 4 == dest_baselen
++      && !memcasecmp (dest_basename - 4, ".exe", 4)
++      && !memcasecmp (source_basename, dest_basename, source_baselen)
++      && 0 < cygwin_spelling(source))
++    dest_baselen -= 4;
++  /* Some, but not all, files are case-insensitive (depending on mount
++     options, CYGWIN=case settings, and virtual file systems).  Do
++     some sleuthing to decide whether case-insensitivity matters.  */
++  if (! compare_dirs && source_baselen == dest_baselen)
++    {
++      ssize_t wsrclen = cygwin_conv_path (CCP_POSIX_TO_WIN_W,
++                                          source, NULL, 0);
++      ssize_t wdstlen = cygwin_conv_path (CCP_POSIX_TO_WIN_W,
++                                          dest, NULL, 0);
++      char *wsrc = malloca (wsrclen);
++      char *wdst = malloca (wdstlen);
++      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, source, wsrc, wsrclen))
++        error (EXIT_FAILURE, errno, "unable to convert path name %s", source);
++      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, dest, wdst, wdstlen))
++        error (EXIT_FAILURE, errno, "unable to convert path name %s", dest);
++      if (wsrclen == wdstlen && memcasecmp (wsrc, wdst, wsrclen) == 0)
++        compare_dirs = true;
++      freea (wsrc);
++      freea (wdst);
++    }
++#endif /* __CYGWIN__ */
+   bool same = false;
+ 
+ #if ! _POSIX_NO_TRUNC && HAVE_PATHCONF && defined _PC_NAME_MAX
+--- coreutils-8.23/lib/xfreopen.c	2014-05-29 05:05:50.000000000 -0700
++++ coreutils-8.23/lib/xfreopen.c	2014-10-13 08:30:37.180881200 -0700
+@@ -18,6 +18,7 @@
+ #include "xfreopen.h"
+ 
+ #include <errno.h>
++#include <fcntl.h>
+ #include "error.h"
+ #include "exitfail.h"
+ #include "quote.h"
+@@ -26,9 +27,17 @@
+ #include "gettext.h"
+ #define _(msgid) gettext (msgid)
+ 
++#define STREQ(s1, s2) (strcmp (s1, s2) == 0)
++
+ void
+ xfreopen (char const *filename, char const *mode, FILE *fp)
+ {
++  if (!filename && STREQ (mode, "wb"))
++    {
++      int flag = fcntl (fileno (fp), F_GETFL);
++      if (0 <= flag && (flag & O_APPEND))
++        mode = "ab";
++    }
+   if (!freopen (filename, mode, fp))
+     {
+       char const *f = (filename ? filename
+--- coreutils-8.23/chcon.c	2014-07-13 15:09:52.000000000 -0700
++++ coreutils-8.23/src/chcon.c	2014-10-13 08:30:37.180881200 -0700
+@@ -48,7 +48,7 @@ static bool verbose;
+ 
+ /* Pointer to the device and inode numbers of '/', when --recursive.
+    Otherwise NULL.  */
+-static struct dev_ino *root_dev_ino;
++static struct root_dev_ino *root_dev_ino;
+ 
+ /* The name of the context file is being given. */
+ static char const *specified_context;
+@@ -569,7 +569,7 @@ main (int argc, char **argv)
+ 
+   if (recurse && preserve_root)
+     {
+-      static struct dev_ino dev_ino_buf;
++      static struct root_dev_ino dev_ino_buf;
+       root_dev_ino = get_root_dev_ino (&dev_ino_buf);
+       if (root_dev_ino == NULL)
+         error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
+--- coreutils-8.23/chgrp.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/chgrp.c	2014-10-13 08:30:37.180881200 -0700
+@@ -299,7 +299,7 @@ main (int argc, char **argv)
+ 
+   if (chopt.recurse && preserve_root)
+     {
+-      static struct dev_ino dev_ino_buf;
++      static struct root_dev_ino dev_ino_buf;
+       chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
+       if (chopt.root_dev_ino == NULL)
+         error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
+--- coreutils-8.23/chmod.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/chmod.c	2014-10-13 08:30:37.180881200 -0700
+@@ -81,7 +81,7 @@ static enum Verbosity verbosity = V_off;
+ 
+ /* Pointer to the device and inode numbers of '/', when --recursive.
+    Otherwise NULL.  */
+-static struct dev_ino *root_dev_ino;
++static struct root_dev_ino *root_dev_ino;
+ 
+ /* For long options that have no equivalent short option, use a
+    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
+@@ -552,7 +552,7 @@ main (int argc, char **argv)
+ 
+   if (recurse && preserve_root)
+     {
+-      static struct dev_ino dev_ino_buf;
++      static struct root_dev_ino dev_ino_buf;
+       root_dev_ino = get_root_dev_ino (&dev_ino_buf);
+       if (root_dev_ino == NULL)
+         error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
+--- coreutils-8.23/chown-core.h	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/chown-core.h	2014-10-13 08:30:37.196451900 -0700
+@@ -50,7 +50,7 @@ struct Chown_option
+ 
+   /* Pointer to the device and inode numbers of '/', when --recursive.
+      Need not be freed.  Otherwise NULL.  */
+-  struct dev_ino *root_dev_ino;
++  struct root_dev_ino *root_dev_ino;
+ 
+   /* This corresponds to the --dereference (opposite of -h) option.  */
+   bool affect_symlink_referent;
+--- coreutils-8.23/chown.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/chown.c	2014-10-13 08:30:37.196451900 -0700
+@@ -312,7 +312,7 @@ main (int argc, char **argv)
+ 
+   if (chopt.recurse && preserve_root)
+     {
+-      static struct dev_ino dev_ino_buf;
++      static struct root_dev_ino dev_ino_buf;
+       chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
+       if (chopt.root_dev_ino == NULL)
+         error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
+--- coreutils-8.23/chroot.c	2014-07-13 16:59:20.000000000 -0700
++++ coreutils-8.23/src/chroot.c	2014-10-13 08:30:37.196451900 -0700
+@@ -163,7 +163,7 @@ parse_additional_groups (char const *gro
+ static bool
+ is_root (const char* dir)
+ {
+-  struct dev_ino root_ino;
++  struct root_dev_ino root_ino;
+   if (! get_root_dev_ino (&root_ino))
+     error (EXIT_CANCELED, errno, _("failed to get attributes of %s"),
+            quote ("/"));
+@@ -173,7 +173,7 @@ is_root (const char* dir)
+     error (EXIT_CANCELED, errno, _("failed to get attributes of %s"),
+            quote (dir));
+ 
+-  return SAME_INODE (root_ino, arg_st);
++  return ROOT_DEV_INO_CHECK (&root_ino, &arg_st);
+ }
+ 
+ void
+--- coreutils-8.23/cksum.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/cksum.c	2014-10-13 08:30:37.196451900 -0700
+@@ -301,6 +301,9 @@ main (int argc, char **argv)
+ 
+   have_read_stdin = false;
+ 
++  if (O_BINARY)
++    xfreopen (NULL, "wb", stdout);
++
+   if (optind == argc)
+     ok = cksum ("-", false);
+   else
+--- coreutils-8.23/copy.c	2014-07-13 15:09:52.000000000 -0700
++++ coreutils-8.23/src/copy.c	2014-10-13 08:49:30.450181800 -0700
+@@ -70,6 +70,10 @@
+ # include "verror.h"
+ #endif
+ 
++#if __CYGWIN__
++# include "cygwin.h"
++#endif
++
+ #ifndef HAVE_FCHOWN
+ # define HAVE_FCHOWN false
+ # define fchown(fd, uid, gid) (-1)
+@@ -1313,7 +1317,11 @@ close_src_desc:
+ static bool
+ same_file_ok (char const *src_name, struct stat const *src_sb,
+               char const *dst_name, struct stat const *dst_sb,
+-              const struct cp_options *x, bool *return_now, bool *unlink_src)
++              const struct cp_options *x, bool *return_now, bool *unlink_src
++#if __CYGWIN__
++	      , bool *case_change
++#endif
++	      )
+ {
+   const struct stat *src_sb_link;
+   const struct stat *dst_sb_link;
+@@ -1461,6 +1469,18 @@ same_file_ok (char const *src_name, stru
+       if (S_ISLNK (dst_sb_link->st_mode))
+         return true;
+ 
++#if __CYGWIN__
++      /* If the files have the same name, but differ in case, then let
++        rename() change the case.  */
++      if (same_link && x->move_mode && same_name (src_name, dst_name)
++         && memcmp (last_component (src_name), last_component (dst_name),
++                    base_len (src_name)) != 0)
++       {
++         *case_change = true;
++         return true;
++       }
++#endif /* __CYGWIN__ */
++
+       if (same_link
+           && 1 < dst_sb_link->st_nlink
+           && ! same_name (src_name, dst_name))
+@@ -1813,10 +1833,20 @@ copy_internal (char const *src_name, cha
+          && ! (x->move_mode || x->symbolic_link || x->hard_link
+                || x->backup_type != no_backups
+                || x->unlink_dest_before_opening));
+-      if ((use_stat
+-           ? stat (dst_name, &dst_sb)
+-           : lstat (dst_name, &dst_sb))
+-          != 0)
++      int res = (use_stat
++                 ? stat (dst_name, &dst_sb)
++                 : lstat (dst_name, &dst_sb));
++#if __CYGWIN__
++      /* stat("a") succeeds even if it was really "a.exe".  */
++      if (! res && 0 < cygwin_spelling (dst_name))
++        {
++          /* Only DST_NAME.exe exists, but we want the non-existant
++             DST_NAME.  */
++          res = -1;
++          errno = ENOENT;
++        }
++#endif /* __CYGWIN__ */
++      if (res != 0)
+         {
+           if (errno != ENOENT)
+             {
+@@ -1833,10 +1863,17 @@ copy_internal (char const *src_name, cha
+              that it is stat'able or lstat'able.  */
+           bool return_now;
+           bool unlink_src;
++#if __CYGWIN__
++          bool case_change = false;
++#endif /* __CYGWIN__ */
+ 
+           have_dst_lstat = !use_stat;
+           if (! same_file_ok (src_name, &src_sb, dst_name, &dst_sb,
+-                              x, &return_now, &unlink_src))
++                              x, &return_now, &unlink_src
++#if __CYGWIN__
++                              , &case_change
++#endif
++))
+             {
+               error (0, 0, _("%s and %s are the same file"),
+                      quote_n (0, src_name), quote_n (1, dst_name));
+@@ -1895,6 +1932,9 @@ copy_internal (char const *src_name, cha
+              cp and mv treat -i and -f differently.  */
+           if (x->move_mode)
+             {
++#if __CYGWIN__
++              if (!case_change)
++#endif /* __CYGWIN__ */
+               if (abandon_move (x, dst_name, &dst_sb)
+                   || (unlink_src && unlink (src_name) == 0))
+                 {
+@@ -2058,7 +2098,11 @@ copy_internal (char const *src_name, cha
+                    /* Never unlink dst_name when in move mode.  */
+                    && ! x->move_mode
+                    && (x->unlink_dest_before_opening
+-                       || (x->preserve_links && 1 < dst_sb.st_nlink)
++                       || (x->preserve_links && 1 < dst_sb.st_nlink
++#if __CYGWIN__
++                           && !case_change
++#endif /* __CYGWIN__ */
++			   )
+                        || (x->dereference == DEREF_NEVER
+                            && ! S_ISREG (src_sb.st_mode))
+                        ))
+@@ -2816,6 +2860,21 @@ copy (char const *src_name, char const *
+ {
+   assert (valid_options (options));
+ 
++#if __CYGWIN__
++  /* .exe magic - if src exists with an implicit .exe suffix and is
++     not a symlink, but dst does not exist and was also specified
++     without a suffix, then append .exe to dst.  */
++  int cygwin = cygwin_spelling (src_name);
++  char *p;
++  if (cygwin == 2
++      && ((p = strchr (dst_name, '\0') - 4) <= dst_name
++          || strcasecmp (p, ".exe") != 0))
++    {
++      cygwin = 3;
++      CYGWIN_APPEND_EXE (p, dst_name);
++    }
++#endif /* __CYGWIN__ */
++
+   /* Record the file names: they're used in case of error, when copying
+      a directory into itself.  I don't like to make these tools do *any*
+      extra work in the common case when that work is solely to handle
+@@ -2827,10 +2886,15 @@ copy (char const *src_name, char const *
+   top_level_dst_name = dst_name;
+ 
+   bool first_dir_created_per_command_line_arg = false;
+-  return copy_internal (src_name, dst_name, nonexistent_dst, NULL, NULL,
++  bool result = copy_internal (src_name, dst_name, nonexistent_dst, NULL, NULL,
+                         options, true,
+                         &first_dir_created_per_command_line_arg,
+                         copy_into_self, rename_succeeded);
++#if __CYGWIN__
++  if (cygwin == 3)
++    freea ((char *) dst_name);
++#endif /* __CYGWIN__ */
++  return result;
+ }
+ 
+ /* Set *X to the default options for a value of type struct cp_options.  */
+--- coreutils-8.23/dd.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/dd.c	2014-10-13 08:30:37.196451900 -0700
+@@ -37,6 +37,10 @@
+ #include "xstrtol.h"
+ #include "xtime.h"
+ 
++#if __CYGWIN__
++# include <io.h>
++#endif
++
+ /* The official name of this program (e.g., no 'g' prefix).  */
+ #define PROGRAM_NAME "dd"
+ 
+@@ -1862,6 +1866,13 @@ copy_with_unblock (char const *buf, size
+ static void
+ set_fd_flags (int fd, int add_flags, char const *name)
+ {
++#if __CYGWIN__
++  /* Cygwin does not allow fcntl to set the mode.  */
++  int mode_flags = add_flags & (O_BINARY | O_TEXT);
++  add_flags &= ~(O_BINARY | O_TEXT);
++  if (mode_flags && setmode (fd, mode_flags) == -1)
++    error (EXIT_FAILURE, errno, _("setting flags for %s"), quote (name));
++#endif /* __CYGWIN__ */
+   /* Ignore file creation flags that are no-ops on file descriptors.  */
+   add_flags &= ~ (O_NOCTTY | O_NOFOLLOW);
+ 
+@@ -2242,6 +2253,8 @@ main (int argc, char **argv)
+     }
+   else
+     {
++      if ((input_flags & (O_BINARY | O_TEXT)) == 0)
++	input_flags |= O_BINARY;
+       if (fd_reopen (STDIN_FILENO, input_file, O_RDONLY | input_flags, 0) < 0)
+         error (EXIT_FAILURE, errno, _("failed to open %s"), quote (input_file));
+     }
+@@ -2264,6 +2277,8 @@ main (int argc, char **argv)
+            | (conversions_mask & C_NOCREAT ? 0 : O_CREAT)
+            | (conversions_mask & C_EXCL ? O_EXCL : 0)
+            | (seek_records || (conversions_mask & C_NOTRUNC) ? 0 : O_TRUNC));
++      if ((opts & (O_BINARY | O_TEXT)) == 0)
++        opts |= O_BINARY;
+ 
+       /* Open the output file with *read* access only if we might
+          need to read to satisfy a 'seek=' request.  If we can't read
+--- coreutils-8.23/dircolors.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/dircolors.c	2014-10-13 08:30:37.196451900 -0700
+@@ -494,8 +494,12 @@ main (int argc, char **argv)
+             }
+           else
+             {
++              /* tcsh treats LS_COLORS as a magic shell variable for its
++                 builtin ls-F, but does not recognize all the categories
++                 that coreutils ls does.  Therefore, silence stderr to
++                 avoid messages like "Unknown colorls variable `su'.".  */
+               prefix = "setenv LS_COLORS '";
+-              suffix = "'\n";
++              suffix = "' >&/dev/null\n";
+             }
+           fputs (prefix, stdout);
+           fwrite (s, 1, len, stdout);
+--- coreutils-8.23/install.c	2014-07-13 15:09:52.000000000 -0700
++++ coreutils-8.23/src/install.c	2014-10-13 08:30:37.196451900 -0700
+@@ -44,6 +44,10 @@
+ #include "utimens.h"
+ #include "xstrtol.h"
+ 
++#if __CYGWIN__
++# include "cygwin.h"
++#endif
++
+ /* The official name of this program (e.g., no 'g' prefix).  */
+ #define PROGRAM_NAME "install"
+ 
+@@ -531,6 +535,16 @@ strip (char const *name)
+       error (0, errno, _("fork system call failed"));
+       break;
+     case 0:			/* Child. */
++#if __CYGWIN__
++      {
++	/* Check for .exe here, since strip doesn't.  */
++	char *p;
++	if (((p = strchr (name, '\0') - 4) <= name
++	     || strcasecmp (p, ".exe") != 0)
++	    && 0 < cygwin_spelling (name))
++          CYGWIN_APPEND_EXE (p, name);
++      }
++#endif /* __CYGWIN__ */
+       execlp (strip_program, strip_program, name, NULL);
+       error (EXIT_FAILURE, errno, _("cannot run %s"), strip_program);
+       break;
+--- coreutils-8.23/ls.c	2014-07-13 15:09:52.000000000 -0700
++++ coreutils-8.23/src/ls.c	2014-10-13 08:30:37.196451900 -0700
+@@ -117,6 +117,10 @@
+ # include <sys/capability.h>
+ #endif
+ 
++#if __CYGWIN__
++# include "cygwin.h"
++#endif
++
+ #define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
+                       : (ls_mode == LS_MULTI_COL \
+                          ? "dir" : "vdir"))
+@@ -747,6 +751,11 @@ static char const *long_time_format[2] =
+     N_("%b %e %H:%M")
+   };
+ 
++#if __CYGWIN__
++/* Whether .exe should be appended to command-line args as needed.  */
++static bool append_exe;
++#endif /* __CYGWIN__ */
++
+ /* The set of signals that are caught.  */
+ 
+ static sigset_t caught_signals;
+@@ -782,6 +791,9 @@ enum
+ enum
+ {
+   AUTHOR_OPTION = CHAR_MAX + 1,
++#if __CYGWIN__
++  APPEND_EXE_OPTION,
++#endif /* __CYGWIN__ */
+   BLOCK_SIZE_OPTION,
+   COLOR_OPTION,
+   DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION,
+@@ -843,6 +855,9 @@ static struct option const long_options[
+   {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
+   {"context", no_argument, 0, 'Z'},
+   {"author", no_argument, NULL, AUTHOR_OPTION},
++#if __CYGWIN__
++  {"append-exe", no_argument, NULL, APPEND_EXE_OPTION},
++#endif /* __CYGWIN__ */
+   {GETOPT_HELP_OPTION_DECL},
+   {GETOPT_VERSION_OPTION_DECL},
+   {NULL, 0, NULL, 0}
+@@ -1954,6 +1969,12 @@ decode_switches (int argc, char **argv)
+           print_scontext = true;
+           break;
+ 
++#if __CYGWIN__
++        case APPEND_EXE_OPTION:
++          append_exe = true;
++          break;
++#endif /* __CYGWIN__ */
++
+         case_GETOPT_HELP_CHAR;
+ 
+         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+@@ -2924,6 +2945,12 @@ gobble_file (char const *name, enum file
+   uintmax_t blocks = 0;
+   struct fileinfo *f;
+ 
++#if __CYGWIN__
++  char *name_alt = NULL;
++  if (command_line_arg && append_exe && 0 < cygwin_spelling (name))
++    CYGWIN_APPEND_EXE (name_alt, name);
++#endif /* __CYGWIN__ */
++
+   /* An inode value prior to gobble_file necessarily came from readdir,
+      which is not used for command line arguments.  */
+   assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER);
+@@ -3035,11 +3062,19 @@ gobble_file (char const *name, enum file
+           file_failure (command_line_arg,
+                         _("cannot access %s"), absolute_name);
+           if (command_line_arg)
+-            return 0;
++            {
++#if __CYGWIN__
++              freea (name_alt);
++#endif /* __CYGWIN__ */
++              return 0;
++            }
+ 
+           f->name = xstrdup (name);
+           cwd_n_used++;
+ 
++#if __CYGWIN__
++          freea (name_alt);
++#endif /* __CYGWIN__ */
+           return 0;
+         }
+ 
+@@ -3223,6 +3258,9 @@ gobble_file (char const *name, enum file
+   f->name = xstrdup (name);
+   cwd_n_used++;
+ 
++#if __CYGWIN__
++  freea (name_alt);
++#endif /* __CYGWIN__ */
+   return blocks;
+ }
+ 
+@@ -4923,6 +4961,11 @@ Sort entries alphabetically if none of -
+   -Z, --context              print any security context of each file\n\
+   -1                         list one file per line\n\
+ "), stdout);
++#if __CYGWIN__
++      fputs (_("\
++      --append-exe           append .exe if cygwin magic was needed\n\
++"), stdout);
++#endif /* __CYGWIN__ */
+       fputs (HELP_OPTION_DESCRIPTION, stdout);
+       fputs (VERSION_OPTION_DESCRIPTION, stdout);
+       emit_size_note ();
+--- coreutils-8.23/md5sum.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/md5sum.c	2014-10-13 08:30:37.212072800 -0700
+@@ -813,6 +813,9 @@ main (int argc, char **argv)
+   if (optind == argc)
+     argv[argc++] = bad_cast ("-");
+ 
++  if (O_BINARY)
++    xfreopen (NULL, "wb", stdout);
++
+   for (; optind < argc; ++optind)
+     {
+       char *file = argv[optind];
+--- coreutils-8.23/mv.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/mv.c	2014-10-13 08:30:37.212072800 -0700
+@@ -92,7 +92,7 @@ rm_option_init (struct rm_options *x)
+   x->require_restore_cwd = true;
+ 
+   {
+-    static struct dev_ino dev_ino_buf;
++    static struct root_dev_ino dev_ino_buf;
+     x->root_dev_ino = get_root_dev_ino (&dev_ino_buf);
+     if (x->root_dev_ino == NULL)
+       error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
+@@ -467,6 +467,16 @@ main (int argc, char **argv)
+   else if (!target_directory)
+     {
+       assert (2 <= n_files);
++#if __CYGWIN__
++      struct stat s1, s2;
++      if (2 == n_files
++	  && lstat (file[0], &s1) == 0 && lstat (file[1], &s2) == 0
++	  && s1.st_ino == s2.st_ino)
++	{
++	  /* Allow 'mv foo Foo' to change case of the directory foo.  */
++	}
++      else
++#endif /* __CYGWIN__ */
+       if (target_directory_operand (file[n_files - 1]))
+         target_directory = file[--n_files];
+       else if (2 < n_files)
+--- coreutils-8.23/pwd.c	2014-07-13 15:09:52.000000000 -0700
++++ coreutils-8.23/src/pwd.c	2014-10-13 08:30:37.212072800 -0700
+@@ -268,8 +268,8 @@ static void
+ robust_getcwd (struct file_name *file_name)
+ {
+   size_t height = 1;
+-  struct dev_ino dev_ino_buf;
+-  struct dev_ino *root_dev_ino = get_root_dev_ino (&dev_ino_buf);
++  struct root_dev_ino dev_ino_buf;
++  struct root_dev_ino *root_dev_ino = get_root_dev_ino (&dev_ino_buf);
+   struct stat dot_sb;
+ 
+   if (root_dev_ino == NULL)
+@@ -282,7 +282,7 @@ robust_getcwd (struct file_name *file_na
+   while (1)
+     {
+       /* If we've reached the root, we're done.  */
+-      if (SAME_INODE (dot_sb, *root_dev_ino))
++      if (ROOT_DEV_INO_CHECK (root_dev_ino, &dot_sb))
+         break;
+ 
+       find_dir_entry (&dot_sb, file_name, height++);
+@@ -291,6 +291,9 @@ robust_getcwd (struct file_name *file_na
+   /* See if a leading slash is needed; file_name_prepend adds one.  */
+   if (file_name->start[0] == '\0')
+     file_name_prepend (file_name, "", 0);
++  /* If we aren't in `/', we must be in `//'.  */
++  if (! SAME_INODE (root_dev_ino->single_slash, dot_sb))
++    file_name_prepend (file_name, "", 0);
+ }
+ 
+ 
+--- coreutils-8.23/remove.h	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/remove.h	2014-10-13 08:30:37.212072800 -0700
+@@ -54,7 +54,7 @@ struct rm_options
+ 
+   /* Pointer to the device and inode numbers of '/', when --recursive
+      and preserving '/'.  Otherwise NULL.  */
+-  struct dev_ino *root_dev_ino;
++  struct root_dev_ino *root_dev_ino;
+ 
+   /* If nonzero, stdin is a tty.  */
+   bool stdin_tty;
+--- coreutils-8.23/rm.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/rm.c	2014-10-13 08:30:37.212072800 -0700
+@@ -325,7 +325,7 @@ main (int argc, char **argv)
+ 
+   if (x.recursive && preserve_root)
+     {
+-      static struct dev_ino dev_ino_buf;
++      static struct root_dev_ino dev_ino_buf;
+       x.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
+       if (x.root_dev_ino == NULL)
+         error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
+--- coreutils-8.23/stat.c	2014-07-11 04:00:07.000000000 -0700
++++ coreutils-8.23/src/stat.c	2014-10-13 08:30:37.212072800 -0700
+@@ -73,6 +73,13 @@
+ #include "find-mount-point.h"
+ #include "xvasprintf.h"
+ 
++#if __CYGWIN__
++# include "cygwin.h"
++/* Whether .exe should be appended to command-line args as needed.  */
++static bool append_exe;
++# define APPEND_EXE_OPTION 10000
++#endif
++
+ #if USE_STATVFS
+ # define STRUCT_STATVFS struct statvfs
+ # define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATVFS_F_FSID_IS_INTEGER
+@@ -189,6 +196,9 @@ static struct option const long_options[
+   {"format", required_argument, NULL, 'c'},
+   {"printf", required_argument, NULL, PRINTF_OPTION},
+   {"terse", no_argument, NULL, 't'},
++#if __CYGWIN__
++  {"append-exe", no_argument, NULL, APPEND_EXE_OPTION},
++#endif /* __CYGWIN__ */
+   {GETOPT_HELP_OPTION_DECL},
+   {GETOPT_VERSION_OPTION_DECL},
+   {NULL, 0, NULL, 0}
+@@ -1264,14 +1274,26 @@ do_statfs (char const *filename, char co
+       return false;
+     }
+ 
++#if __CYGWIN__
++  char *name_alt = NULL;
++  if (append_exe && 0 < cygwin_spelling (filename))
++    CYGWIN_APPEND_EXE (name_alt, filename);
++#endif /* __CYGWIN__ */
++
+   if (STATFS (filename, &statfsbuf) != 0)
+     {
+       error (0, errno, _("cannot read file system information for %s"),
+              quote (filename));
++#if __CYGWIN__
++      freea (name_alt);
++#endif /* __CYGWIN__ */
+       return false;
+     }
+ 
+   bool fail = print_it (format, -1, filename, print_statfs, &statfsbuf);
++#if __CYGWIN__
++  freea (name_alt);
++#endif /* __CYGWIN__ */
+   return ! fail;
+ }
+ 
+@@ -1282,6 +1304,7 @@ do_stat (char const *filename, char cons
+ {
+   int fd = STREQ (filename, "-") ? 0 : -1;
+   struct stat statbuf;
++  char *name_alt = NULL;
+ 
+   if (0 <= fd)
+     {
+@@ -1294,18 +1317,29 @@ do_stat (char const *filename, char cons
+   /* We can't use the shorter
+      (follow_links?stat:lstat) (filename, &statbug)
+      since stat might be a function-like macro.  */
+-  else if ((follow_links
+-            ? stat (filename, &statbuf)
+-            : lstat (filename, &statbuf)) != 0)
++  else
+     {
+-      error (0, errno, _("cannot stat %s"), quote (filename));
+-      return false;
++      if ((follow_links
++	   ? stat (filename, &statbuf)
++	   : lstat (filename, &statbuf)) != 0)
++	{
++	  error (0, errno, _("cannot stat %s"), quote (filename));
++	  return false;
++	}
++
++#if __CYGWIN__
++      if (append_exe && 0 < cygwin_spelling (filename))
++        CYGWIN_APPEND_EXE (name_alt, filename);
++#endif /* __CYGWIN__ */
+     }
+ 
+   if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode))
+     format = format2;
+ 
+   bool fail = print_it (format, fd, filename, print_stat, &statbuf);
++#if __CYGWIN__
++  freea (name_alt);
++#endif /* __CYGWIN__ */
+   return ! fail;
+ }
+ 
+@@ -1427,6 +1461,11 @@ Display file or file system status.\n\
+                           if you want a newline, include \\n in FORMAT\n\
+   -t, --terse           print the information in terse form\n\
+ "), stdout);
++#if __CYGWIN__
++      fputs (_("\
++      --append-exe      append .exe if cygwin magic was needed\n\
++"), stdout);
++#endif /* __CYGWIN__ */
+       fputs (HELP_OPTION_DESCRIPTION, stdout);
+       fputs (VERSION_OPTION_DESCRIPTION, stdout);
+ 
+@@ -1547,6 +1586,12 @@ main (int argc, char *argv[])
+           terse = true;
+           break;
+ 
++#if __CYGWIN__
++        case APPEND_EXE_OPTION:
++          append_exe = true;
++          break;
++#endif /* __CYGWIN__ */
++
+         case_GETOPT_HELP_CHAR;
+ 
+         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
diff --git a/pkgs/tools/misc/coreutils/default.nix b/pkgs/tools/misc/coreutils/default.nix
index 64bfd08d93a1b..8e5ccdd243dbd 100644
--- a/pkgs/tools/misc/coreutils/default.nix
+++ b/pkgs/tools/misc/coreutils/default.nix
@@ -1,6 +1,7 @@
 { stdenv, fetchurl, perl, xz, gmp ? null
 , aclSupport ? false, acl ? null
 , selinuxSupport? false, libselinux ? null, libsepol ? null
+, autoconf, automake114x, texinfo
 }:
 
 assert aclSupport -> acl != null;
@@ -11,16 +12,19 @@ with { inherit (stdenv.lib) optional optionals optionalString optionalAttrs; };
 
 let
   self = stdenv.mkDerivation rec {
-    name = "coreutils-8.23";
+    name = "coreutils-8.24";
 
     src = fetchurl {
       url = "mirror://gnu/coreutils/${name}.tar.xz";
-      sha256 = "0bdq6yggyl7nkc2pbl6pxhhyx15nyqhz3ds6rfn448n6rxdwlhzc";
+      sha256 = "0w11jw3fb5sslf0f72kxy7llxgk1ia3a6bcw0c9kmvxrlj355mx2";
     };
 
+    patches = if stdenv.isCygwin then [ ./coreutils-8.23-4.cygwin.patch ] else null;
+
     # The test tends to fail on btrfs and maybe other unusual filesystems.
     postPatch = stdenv.lib.optionalString (!stdenv.isDarwin) ''
       sed '2i echo Skipping dd sparse test && exit 0' -i ./tests/dd/sparse.sh
+      sed '2i echo Skipping cp sparse test && exit 0' -i ./tests/cp/sparse.sh
     '';
 
     outputs = [ "out" "info" ];
@@ -28,10 +32,11 @@ let
     nativeBuildInputs = [ perl xz.bin ];
     buildInputs = [ gmp ]
       ++ optional aclSupport acl
+      ++ optionals stdenv.isCygwin [ autoconf automake114x texinfo ]   # due to patch
       ++ optionals selinuxSupport [ libselinux libsepol ];
 
     crossAttrs = {
-      buildInputs = [ gmp ]
+      buildInputs = [ gmp.crossDrv ]
         ++ optional aclSupport acl.crossDrv
         ++ optionals selinuxSupport [ libselinux.crossDrv libsepol.crossDrv ]
         ++ optional (stdenv.ccCross.libc ? libiconv)