[Top][All Lists]
[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"),
- Re: root-dev-ino.c limitation,
Eric Blake <=