bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: root-dev-ino.c limitation


From: Eric Blake
Subject: Re: root-dev-ino.c limitation
Date: Mon, 27 Feb 2006 23:13:05 +0000

> > So cygwin has are two root directories, / and //, with distinct dev/inode
> > pairs?
> 
> That would imply that there are two distinct trees.

Correct.  There is no way to get from / to // or vice versa,
short of a mount point (and even then, mount points can
only be placed in the / hierarchy).  The / hierarchy is all files
accessible on the local machine, and the // hierarchy accesses
the Windows \\server\share semantics for remote shared
drives.  Local drives do not have to be shared, meaning that
/ is not always available as an alternate spelling somewhere
in the // hierarchy.  Furthermore, /../. is /, and //../. is //.

>  But, as I
> understand it, / is a subtree of //.  If so, isn't // the "real" root,
> and can't the algorithm simply use the dev and ino for // on Cygwin,
> so that getcwd always returns a name that begins with "//"?

No.  Most operations in cygwin use the normal root of '/' - it
is only access to remote servers where a path starts with '//'.

>  This
> wouldn't remove the need for some //-specific stuff, but it would mean
> fewer changes to the code.

I've already done a first cut at the edits, attached for review.
Obviously, I will need to clean up where
DOUBLE_SLASH_IS_DISTINCT_ROOT gets defined, and merge
this patch in with my outstanding basename/dirname patch
before it can be applied.  But it was surprisingly easier than
I feared, and also uncovered a real bug in pwd.c (file_name_prepend
already adds /, so when your current directory is "/", pwd
was printing "//").

-- 
Eric Blake
Index: lib/root-dev-ino.c
===================================================================
RCS file: /sources/coreutils/coreutils/lib/root-dev-ino.c,v
retrieving revision 1.3
diff -u -r1.3 root-dev-ino.c
--- lib/root-dev-ino.c  24 Sep 2005 13:32:45 -0000      1.3
+++ lib/root-dev-ino.c  27 Feb 2006 23:04:49 -0000
@@ -1,5 +1,5 @@
 /* root-dev-ino.c -- get the device and inode numbers for `/'.
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2006 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
@@ -27,13 +27,19 @@
 /* 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 DOUBLE_SLASH_IS_DISTINCT_ROOT
+  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;
+#endif /* DOUBLE_SLASH_IS_DISTINCT_ROOT */
   return root_d_i;
 }
Index: lib/root-dev-ino.h
===================================================================
RCS file: /sources/coreutils/coreutils/lib/root-dev-ino.h,v
retrieving revision 1.1
diff -u -r1.1 root-dev-ino.h
--- lib/root-dev-ino.h  9 Nov 2003 21:18:35 -0000       1.1
+++ lib/root-dev-ino.h  27 Feb 2006 23:04:49 -0000
@@ -3,16 +3,27 @@
 
 # include "dev-ino.h"
 
-struct dev_ino *
-get_root_dev_ino (struct dev_ino *root_d_i);
+#define DOUBLE_SLASH_IS_DISTINCT_ROOT 1 /* ebb clean up this line */
+struct root_dev_ino
+{
+  struct dev_ino single_slash;
+#if DOUBLE_SLASH_IS_DISTINCT_ROOT
+  struct dev_ino double_slash;
+#endif
+};
+
+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))
+# if !DOUBLE_SLASH_IS_DISTINCT_ROOT
+
+#  define ROOT_DEV_INO_CHECK(Root_dev_ino, Dir_statbuf)         \
+  (Root_dev_ino && SAME_INODE (*Dir_statbuf, (Root_dev_ino)->single_slash))
 
-# define ROOT_DEV_INO_WARN(Dirname)                                    \
+#  define ROOT_DEV_INO_WARN(Dirname)                                   \
   do                                                                   \
     {                                                                  \
       if (STREQ (Dirname, "/"))                                                
\
@@ -26,4 +37,26 @@
     }                                                                  \
   while (0)
 
+# else /* DOUBLE_SLASH_IS_DISTINCT_ROOT */
+
+#  define ROOT_DEV_INO_CHECK(Root_dev_ino, Dir_statbuf)         \
+  (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, "/") || STREQ (Dirname, "//"))                \
+       error (0, 0, _("it is dangerous to operate recursively on %s"), \
+              quote (Dirname));                                        \
+      else                                                             \
+       error (0, 0,                                                    \
+              _("it is dangerous to operate recursively on %s (same as %s)"), \
+              quote_n (0, Dirname), quote_n (1, "/"));                 \
+      error (0, 0, _("use --no-preserve-root to override this failsafe")); \
+    }                                                                  \
+  while (0)
+
+# endif /* DOUBLE_SLASH_IS_DISTINCT_ROOT */
+
 #endif
Index: src/chmod.c
===================================================================
RCS file: /sources/coreutils/coreutils/src/chmod.c,v
retrieving revision 1.114
diff -u -r1.114 chmod.c
--- src/chmod.c 17 Jan 2006 17:25:42 -0000      1.114
+++ src/chmod.c 27 Feb 2006 23:04:49 -0000
@@ -1,5 +1,5 @@
 /* chmod -- change permission modes of files
-   Copyright (C) 89, 90, 91, 1995-2005 Free Software Foundation, Inc.
+   Copyright (C) 89, 90, 91, 1995-2006 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
@@ -84,7 +84,7 @@
 
 /* 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.  */
@@ -497,7 +497,7 @@
 
   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"),
Index: src/chown-core.h
===================================================================
RCS file: /sources/coreutils/coreutils/src/chown-core.h,v
retrieving revision 1.10
diff -u -r1.10 chown-core.h
--- src/chown-core.h    14 May 2005 07:58:36 -0000      1.10
+++ src/chown-core.h    27 Feb 2006 23:04:49 -0000
@@ -1,6 +1,6 @@
 /* chown-core.h -- types and prototypes shared by chown and chgrp.
 
-   Copyright (C) 2000, 2003, 2004 Free Software Foundation.
+   Copyright (C) 2000, 2003, 2004, 2006 Free Software Foundation.
 
    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
@@ -51,7 +51,7 @@
 
   /* 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;
Index: src/chown.c
===================================================================
RCS file: /sources/coreutils/coreutils/src/chown.c,v
retrieving revision 1.125
diff -u -r1.125 chown.c
--- src/chown.c 6 Feb 2006 08:00:31 -0000       1.125
+++ src/chown.c 27 Feb 2006 23:04:49 -0000
@@ -328,7 +328,7 @@
 
   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"),
Index: src/pwd.c
===================================================================
RCS file: /sources/coreutils/coreutils/src/pwd.c,v
retrieving revision 1.59
diff -u -r1.59 pwd.c
--- src/pwd.c   26 Feb 2006 10:02:49 -0000      1.59
+++ src/pwd.c   27 Feb 2006 23:04:49 -0000
@@ -259,8 +259,8 @@
 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)
@@ -273,14 +273,19 @@
   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++);
     }
 
   if (file_name->start[0] == '\0')
-    file_name_prepend (file_name, "/", 1);
+    file_name_prepend (file_name, "", 0);
+#if DOUBLE_SLASH_IS_DISTINCT_ROOT
+  /* 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);
+#endif
 }
 
 int
Index: src/remove.h
===================================================================
RCS file: /sources/coreutils/coreutils/src/remove.h,v
retrieving revision 1.15
diff -u -r1.15 remove.h
--- src/remove.h        2 Nov 2005 21:51:57 -0000       1.15
+++ src/remove.h        27 Feb 2006 23:04:49 -0000
@@ -1,6 +1,6 @@
 /* Remove directory entries.
 
-   Copyright (C) 1998, 2000, 2002, 2003, 2004, 2005 Free Software
+   Copyright (C) 1998, 2000, 2002, 2003, 2004, 2005, 2006 Free Software
    Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,7 @@
 
   /* Pointer to the device and inode numbers of `/', when --recursive.
      Otherwise NULL.  */
-  struct dev_ino *root_dev_ino;
+  struct root_dev_ino *root_dev_ino;
 
   /* If nonzero, stdin is a tty.  */
   bool stdin_tty;
Index: src/rm.c
===================================================================
RCS file: /sources/coreutils/coreutils/src/rm.c,v
retrieving revision 1.139
diff -u -r1.139 rm.c
--- src/rm.c    20 Feb 2006 12:48:11 -0000      1.139
+++ src/rm.c    27 Feb 2006 23:04:49 -0000
@@ -337,7 +337,7 @@
 
   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"),

reply via email to

[Prev in Thread] Current Thread [Next in Thread]