[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: snapshot in a few hours
From: |
Eric Blake |
Subject: |
Re: snapshot in a few hours |
Date: |
Fri, 04 Sep 2009 14:10:29 -0600 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.23) Gecko/20090812 Thunderbird/2.0.0.23 Mnenhy/0.7.6.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
According to Eric Blake on 9/4/2009 2:06 PM:
> According to Jim Meyering on 9/4/2009 12:12 PM:
>>> copy.c needs to use #if LINK_FOLLOWS_SYMLINKS instead of #ifdef.
>> Sounds good.
>
> How about the following two patches?
Aargh. Did it again, and attached the wrong file.
- --
Don't work too hard, make some time for fun as well!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkqhdDUACgkQ84KuGfSFAYA6wwCgq5STSFqPB/hNXqJGmkhNhELw
tq8AoLVYolZz6Z9cs41zPQEkMsZcgLkF
=byq4
-----END PGP SIGNATURE-----
>From ed13602fa561e66a2695ddd7eeeb2f218ce9020f Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Fri, 4 Sep 2009 12:40:39 -0600
Subject: [PATCH 1/2] mv, cp: tweak LINK_FOLLOWS_SYMLINKS logic
* gnulib: Update to latest gnulib.
* src/copy.c (copy_internal): Adjust comment in light of POSIX
2008, and deal with macro now being tri-state.
---
gnulib | 2 +-
src/copy.c | 30 ++++++++++++++++--------------
2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/gnulib b/gnulib
index 9b740ea..ee67d8e 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit 9b740ea4bcb104eeceb0c847a376d2b7dbb77d1b
+Subproject commit ee67d8ea6bd183f5ce32d90a6764705d766c3d6b
diff --git a/src/copy.c b/src/copy.c
index e604ec5..178a640 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1974,21 +1974,23 @@ copy_internal (char const *src_name, char const
*dst_name,
}
}
+ /* POSIX 2008 states that it is implementation-defined whether
+ link() on a symlink creates a hard-link to the symlink, or only
+ to the referent (effectively dereferencing the symlink) (POSIX
+ 2001 required the latter behavior, although many systems provided
+ the former). Yet cp, invoked with `--link --no-dereference',
+ should not follow the link. We can approximate the desired
+ behavior by skipping this hard-link creating block and instead
+ copying the symlink, via the `S_ISLNK'- copying code below.
+ LINK_FOLLOWS_SYMLINKS is tri-state; if it is -1, we don't know
+ how link() behaves, so we use the fallback case for safety.
+
+ FIXME - use a gnulib linkat emulation for more fine-tuned
+ emulation, particularly when LINK_FOLLOWS_SYMLINKS is -1. */
else if (x->hard_link
-#ifdef LINK_FOLLOWS_SYMLINKS
- /* A POSIX-conforming link syscall dereferences a symlink, yet cp,
- invoked with `--link --no-dereference', should not. Thus, with
- a POSIX-conforming link system call, we can't use link() here,
- since that would create a hard link to the referent (effectively
- dereferencing the symlink), rather than to the symlink itself.
- We can approximate the desired behavior by skipping this hard-link
- creating block and instead copying the symlink, via the `S_ISLNK'-
- copying code below.
- When link operates on the symlinks themselves, we use this block
- and just call link(). */
- && !(S_ISLNK (src_mode) && x->dereference == DEREF_NEVER)
-#endif
- )
+ && (!LINK_FOLLOWS_SYMLINKS
+ || !S_ISLNK (src_mode)
+ || x->dereference != DEREF_NEVER))
{
if (link (src_name, dst_name))
{
--
1.6.3.3.334.g916e1
>From 410eddc47c10082591b2487b234a3b5a6155daaf Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Fri, 4 Sep 2009 13:56:16 -0600
Subject: [PATCH 2/2] ln: add comments related to POSIX 2008
* src/ln.c (ENABLE_HARD_LINK_TO_SYMLINK_WARNING): Delete.
(do_link): Update comments per POSIX; add FIXME for -L, -P.
---
src/ln.c | 35 ++++++++++++++---------------------
1 files changed, 14 insertions(+), 21 deletions(-)
diff --git a/src/ln.c b/src/ln.c
index d9b9285..4c6ec8a 100644
--- a/src/ln.c
+++ b/src/ln.c
@@ -39,10 +39,6 @@
proper_name ("Mike Parker"), \
proper_name ("David MacKenzie")
-#ifndef ENABLE_HARD_LINK_TO_SYMLINK_WARNING
-# define ENABLE_HARD_LINK_TO_SYMLINK_WARNING 0
-#endif
-
/* In being careful not even to try to make hard links to directories,
we have to know whether link(2) follows symlinks. If it does, then
we have to *stat* the `source' to see if the resulting link would be
@@ -150,7 +146,12 @@ do_link (const char *source, const char *dest)
/* Use stat here instead of lstat.
On SVR4, link does not follow symlinks, so this check disallows
making hard links to symlinks that point to directories. Big deal.
- On other systems, link follows symlinks, so this check is right. */
+ On other systems, link follows symlinks, so this check is right.
+
+ FIXME - POSIX 2008 added the AT_SYMLINK_FOLLOW flag to linkat so
+ that we can specify either behavior, via the new options -L
+ (hard-link to symlinks) and -P (hard-link to the referent). Once
+ gnulib has a decent implementation, we should use it here. */
if (!symbolic_link)
{
if (STAT_LIKE_LINK (source, &source_stats) != 0)
@@ -159,14 +160,6 @@ do_link (const char *source, const char *dest)
return false;
}
- if (ENABLE_HARD_LINK_TO_SYMLINK_WARNING
- && S_ISLNK (source_stats.st_mode))
- {
- error (0, 0, _("%s: warning: making a hard link to a symbolic link\
- is not portable"),
- quote (source));
- }
-
if (S_ISDIR (source_stats.st_mode))
{
source_is_dir = true;
@@ -271,14 +264,14 @@ do_link (const char *source, const char *dest)
/* If the attempt to create a link failed and we are removing or
backing up destinations, unlink the destination and try again.
- POSIX 1003.1-2004 requires that ln -f A B must unlink B even on
- failure (e.g., when A does not exist). This is counterintuitive,
- and we submitted a defect report
- <http://www.opengroup.org/austin/mailarchives/ag-review/msg01794.html>
- (2004-06-24). If the committee does not fix the standard we'll
- have to change the behavior of ln -f, at least if POSIXLY_CORRECT
- is set. In the meantime ln -f A B will not unlink B unless the
- attempt to link A to B failed because B already existed.
+ On the surface, POSIX describes an algorithm that states that
+ 'ln -f A B' will call unlink() on B before ever attempting
+ link() on A. But strictly following this has the counterintuitive
+ effect of losing the contents of B, if A does not exist.
+ Fortunately, POSIX 2008 clarified that an application is free
+ to fail early if it can prove continuing onwards cannot succeed,
+ so we are justified in trying link() before blindly removing B,
+ and calling link() twice for a successful 'ln -f'.
Try to unlink DEST even if we may have backed it up successfully.
In some unusual cases (when DEST and DEST_BACKUP are hard-links
--
1.6.3.3.334.g916e1
- Re: snapshot in a few hours, (continued)
- Re: snapshot in a few hours, Jim Meyering, 2009/09/04
- Re: snapshot in a few hours, Eric Blake, 2009/09/04
- Re: snapshot in a few hours, Pádraig Brady, 2009/09/04
- Re: snapshot in a few hours, Jim Meyering, 2009/09/05
- one more fix for GNU/kFreeBSD, Petr Salinger, 2009/09/05
- Re: one more fix for GNU/kFreeBSD, Jim Meyering, 2009/09/05
- Re: snapshot in a few hours, Pádraig Brady, 2009/09/05
Re: snapshot in a few hours, Eric Blake, 2009/09/04