Re: link -L/-P

2009-09-25 Thread Pádraig Brady
Eric Blake wrote:
 According to Pádraig Brady on 9/24/2009 5:13 PM:
 Eric Blake wrote:
 
 +  -L, --logical   make hard links to symbolic link 
 references\n\
 s/references/targets/ is a bit clearer to me?
 
 I thought about that, but we already specify:
 
 ln source target
 
 as the synopsis, so I didn't want to confuse target (the file being
 created) with target (the contents of the symlink being linked through).
 
 +  -P, --physical  make hard links directly to symblic links\n\
 s/symblic/symbolic/
 
 Thanks.  I folded that in, then added a patch to fix copy.c to use linkat
 (pushed).  I also noticed a cleanup for stdbuf while searching through
 instances of 'link (', although I haven't been able to test that yet,
 since stdbuf doesn't compile on cygwin.  I've pushed my work to:
 
 git pull git://repo.or.cz/coreutils/ericb.git master
 
 to make it easier to review.
 

You need to chmod a+x ln/hard-to-sym

Also your stdbuf cleanup needs the following.
(I was wary about passing NULL into access())

cheers,
Pádraig.

diff --git a/bootstrap.conf b/bootstrap.conf
index f648e22..475ed8f 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -43,6 +43,7 @@ gnulib_modules=
   acl
   alloca
   announce-gen
+  areadlink
   areadlink-with-size
   argmatch
   argv-iter
diff --git a/src/stdbuf.c b/src/stdbuf.c
index c33cdfa..383003c 100644
--- a/src/stdbuf.c
+++ b/src/stdbuf.c
@@ -28,6 +28,8 @@
 #include quote.h
 #include xstrtol.h
 #include c-ctype.h
+#include areadlink.h
+#include filenamecat.h

 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME stdbuf
@@ -154,8 +156,8 @@ set_program_path (const char *arg)
   path = xstrdup (path);
   for (dir = strtok (path, :); dir != NULL; dir = strtok (NULL, :))
 {
-  char *candidate = file_name_concat (dir, arg);
-  if (access (candidate, X_OK) == 0)
+  char *candidate = file_name_concat (dir, arg, NULL);
+  if (candidate  access (candidate, X_OK) == 0)
 {
   program_path = dir_name (candidate);
   free (candidate);




Re: link -L/-P

2009-09-25 Thread Jim Meyering
Eric Blake wrote:
 Eric Blake ebb9 at byu.net writes:

  I'd like to make a test release soon.  Maybe as soon as Friday.
  If you have something that you'd like included, please speak up.

 I'm nearly ready to post support for ln -P/-L, thanks to the pending addition
 of gnulib linkat().  That would be nice to have in the release.

 How does this look?

Looks fine.  Thanks!
One nit:

...
 diff --git a/doc/coreutils.texi b/doc/coreutils.texi
 index 0bfbd56..e7cf5ea 100644
 --- a/doc/coreutils.texi
 +++ b/doc/coreutils.texi
 @@ -8753,6 +8753,11 @@ link invocation
  not specified by @acronym{POSIX}, and the @command{link} command is
  more portable in practice.

 +If @var{filename} is a symbolic link, it is unspecified whether
 +...@var{linkname} will be a hard link to the symbolic link or to the
 +target of the symbolic link.  Use @command{ln -P} or @command{ln -L}
 +specify which behavior is desired.

s/^specify/to specify/




stdbuf enhancement (was: link -L/-P)

2009-09-25 Thread Eric Blake
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

According to Pádraig Brady on 9/25/2009 4:11 AM:
 
 You need to chmod a+x ln/hard-to-sym

Oops.  Yeah.  Serves me right for testing on cygwin 1.5 (cygwin 1.7 fixed
that bug, so that a script now has to be executable to run it).

 Also  path  in your -P description in coreutils.texi
 is causing doc/Makefile.am::check-texinfo to fail

s/path/file name/ fixed that.

 
 Also your stdbuf cleanup needs the following.
 (I was wary about passing NULL into access())

I should have used xreadlink, not areadlink, for ENOMEM.  But
file_name_concat guarantees non-NULL results (it calls xalloc-die on
ENOMEM, and there are no other failure paths), so there was no risk of
calling access(NULL).  Hmm, should we be using euidaccess instead of access?

Also, Jim, should we add a maintainer check that ensures we always use
[ax]readlink rather than raw readlink?

I've folded in your suggestions.  I pushed ln and copy.c changes to
master, but left stdbuf changes only on my own repo.

git pull git://repo.or.cz/coreutils/ericb.git master

- --
Don't work too hard, make some time for fun as well!

Eric Blake e...@byu.net
-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/

iEYEARECAAYFAkq8wz0ACgkQ84KuGfSFAYC8mQCgvvTDvYEyo9a+wS3Y9zE9Z+ZE
R7cAniLaXbQl92mCCw8K6Z2o3D36QUm+
=a82d
-END PGP SIGNATURE-
From 7a31f56455d10a9467bbb688093302875c9dff09 Mon Sep 17 00:00:00 2001
From: Eric Blake e...@byu.net
Date: Thu, 24 Sep 2009 17:18:47 -0600
Subject: [PATCH] stdbuf: improve path search

* src/stdbuf.c (set_program_path): Use gnulib methods for better
file name handling.
* bootstrap.conf (gnulib_modules): Add xreadlink.
---
 bootstrap.conf |1 +
 src/stdbuf.c   |   28 +++-
 2 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index f648e22..c9ce36f 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -236,6 +236,7 @@ gnulib_modules=
   xnanosleep
   xprintf
   xprintf-posix
+  xreadlink
   xstrtod
   xstrtoimax
   xstrtol
diff --git a/src/stdbuf.c b/src/stdbuf.c
index afb7821..05a6b9f 100644
--- a/src/stdbuf.c
+++ b/src/stdbuf.c
@@ -24,8 +24,10 @@

 #include system.h
 #include error.h
+#include filenamecat.h
 #include posixver.h
 #include quote.h
+#include xreadlink.h
 #include xstrtol.h
 #include c-ctype.h

@@ -145,34 +147,26 @@ set_program_path (const char *arg)
 }
   else
 {
-  char *path;
-  char tmppath[PATH_MAX + 1];
-  ssize_t len = readlink (/proc/self/exe, tmppath, sizeof (tmppath) - 1);
-  if (len  0)
-{
-  tmppath[len] = '\0';
-  program_path = dir_name (tmppath);
-}
+  char *path = xreadlink (/proc/self/exe);
+  if (path)
+program_path = dir_name (path);
   else if ((path = getenv (PATH)))
 {
   char *dir;
   path = xstrdup (path);
   for (dir = strtok (path, :); dir != NULL; dir = strtok (NULL, :))
 {
-  int req = snprintf (tmppath, sizeof (tmppath), %s/%s, dir, 
arg);
-  if (req = sizeof (tmppath))
-{
-  error (0, 0, _(path truncated when looking for %s),
- quote (arg));
-}
-  else if (access (tmppath, X_OK) == 0)
+  char *candidate = file_name_concat (dir, arg, NULL);
+  if (access (candidate, X_OK) == 0)
 {
-  program_path = dir_name (tmppath);
+  program_path = dir_name (candidate);
+  free (candidate);
   break;
 }
+  free (candidate);
 }
-  free (path);
 }
+  free (path);
 }
 }

-- 
1.6.5.rc1



link -L/-P (was: coreutils-7.7 beta release soon)

2009-09-24 Thread Eric Blake
Eric Blake ebb9 at byu.net writes:

  I'd like to make a test release soon.  Maybe as soon as Friday.
  If you have something that you'd like included, please speak up.
 
 I'm nearly ready to post support for ln -P/-L, thanks to the pending addition 
 of gnulib linkat().  That would be nice to have in the release.

How does this look?


From: Eric Blake e...@byu.net
Date: Thu, 24 Sep 2009 11:57:11 -0600
Subject: [PATCH] ln: add -L/-P options

* src/ln.c (STAT_LIKE_LINK): Delete.
(logical): New flag.
(long_options): Add -L, -P.
(usage): Mention them.
(main): Choose between them.
(do_link): Perform correct action.
* tests/ln/misc: Move hard-to-sym portion of test...
* tests/ln/hard-to-sym: ...into new test, and add more.
* tests/Makefile.am (TESTS): Run new test.
* NEWS: Document this.
* doc/coreutils.texi (link invocation, ln invocation): Likewise.
* bootstrap.conf (gnulib_modules): Add linkat.
---
 NEWS |7 
 bootstrap.conf   |1 +
 doc/coreutils.texi   |   49 +++---
 src/ln.c |   63 -
 tests/Makefile.am|1 +
 tests/ln/hard-to-sym |   82 ++
 tests/ln/misc|   23 --
 7 files changed, 169 insertions(+), 57 deletions(-)
 create mode 100644 tests/ln/hard-to-sym

diff --git a/NEWS b/NEWS
index 1571c9c..5060502 100644
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,13 @@ GNU coreutils NEWS-*- 
outline -*-
   last component (possibly via a dangling symlink) can be created,
   since mkdir will succeed in that case.

+** New features
+
+  ln now accepts the options --logical (-L) and --physical (-P),
+  added by POSIX 2008.  The default behavior is -P on systems like
+  GNU/Linux where link(2) creates hard links to symlinks, and -L on
+  BSD systems where link(2) follows symlinks.
+
 ** Improvements

   rm: rewrite to use gnulib's fts
diff --git a/bootstrap.conf b/bootstrap.conf
index d1dc128..f648e22 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -132,6 +132,7 @@ gnulib_modules=
   linebuffer
   link
   link-follow
+  linkat
   long-options
   lstat
   maintainer-makefile
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 0bfbd56..e7cf5ea 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -8753,6 +8753,11 @@ link invocation
 not specified by @acronym{POSIX}, and the @command{link} command is
 more portable in practice.

+If @var{filename} is a symbolic link, it is unspecified whether
+...@var{linkname} will be a hard link to the symbolic link or to the
+target of the symbolic link.  Use @command{ln -P} or @command{ln -L}
+specify which behavior is desired.
+
 @exitstatus


@@ -8808,8 +8813,10 @@ ln invocation
 original are indistinguishable.  Technically speaking, they share the
 same inode, and the inode contains all the information about a
 file---indeed, it is not incorrect to say that the inode @emph{is} the
-file.  On all existing implementations, you cannot make a hard link to
-a directory, and hard links cannot cross file system boundaries.  (These
+file.  Most systems prohibit making a hard link to
+a directory; on those where it is allowed, only the super-user can do
+so (and with caution, since creating a cycle will cause problems to many
+other utilities).  Hard links cannot cross file system boundaries.  (These
 restrictions are not mandated by @acronym{POSIX}, however.)

 @cindex dereferencing symbolic links
@@ -8821,9 +8828,13 @@ ln invocation
 reading, writing, and so on) are passed the symbolic link file, the
 kernel automatically @dfn{dereferences} the link and operates on the
 target of the link.  But some operations (e.g., removing) work on the
-link file itself, rather than on its target.  The owner, group, and
-mode of a symlink are not significant to file access performed through
-the link.  @xref{Symbolic Links,,,
+link file itself, rather than on its target.  The owner and group of a
+symlink are not significant to file access performed through
+the link, but do have implications on deleting a symbolic link from a
+directory with the restricted deletion bit set.  On the GNU system,
+the mode of a symlink has no significance and cannot be changed, but
+on some BSD systems, the mode can be changed and will affect whether
+the symlink will be traversed in file name resolution.  @xref{Symbolic Links,,,
 libc, The GNU C Library Reference Manual}.

 Symbolic links can contain arbitrary strings; a @dfn{dangling symlink}
@@ -8878,6 +8889,14 @@ ln invocation
 @cindex prompting, and @command{ln}
 Prompt whether to remove existing destination files.

+...@item -L
+...@itemx --logical
+...@opindex -L
+...@opindex --logical
+If @option{-s} is not in effect, and the source file is a symbolic
+link, create the hard link to the file referred to by the symbolic
+link, rather than the symbolic link itself.
+
 @item -n
 @itemx --no-dereference
 @opindex -n
@@ -8899,6 +8918,17 @@ ln 

Re: link -L/-P

2009-09-24 Thread Pádraig Brady
Eric Blake wrote:

 +  -L, --logical   make hard links to symbolic link references\n\

s/references/targets/ is a bit clearer to me?

 +  -P, --physical  make hard links directly to symblic links\n\

s/symblic/symbolic/

cheers,
Pádraig.




Re: link -L/-P

2009-09-24 Thread Eric Blake
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

According to Pádraig Brady on 9/24/2009 5:13 PM:
 Eric Blake wrote:
 
 +  -L, --logical   make hard links to symbolic link references\n\
 
 s/references/targets/ is a bit clearer to me?

I thought about that, but we already specify:

ln source target

as the synopsis, so I didn't want to confuse target (the file being
created) with target (the contents of the symlink being linked through).

 
 +  -P, --physical  make hard links directly to symblic links\n\
 
 s/symblic/symbolic/

Thanks.  I folded that in, then added a patch to fix copy.c to use linkat
(pushed).  I also noticed a cleanup for stdbuf while searching through
instances of 'link (', although I haven't been able to test that yet,
since stdbuf doesn't compile on cygwin.  I've pushed my work to:

git pull git://repo.or.cz/coreutils/ericb.git master

to make it easier to review.

- --
Don't work too hard, make some time for fun as well!

Eric Blake e...@byu.net
-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/

iEYEARECAAYFAkq8IOMACgkQ84KuGfSFAYBlfACgnj+WOzvLELCE56uQl+aqRbNA
IOMAnifSX9AxFgh+ugoSqb3CoJhXrIFg
=ETC+
-END PGP SIGNATURE-
From 4b9126696dfa293986640556960ef4bbf0be442b Mon Sep 17 00:00:00 2001
From: Eric Blake e...@byu.net
Date: Thu, 24 Sep 2009 17:11:26 -0600
Subject: [PATCH 1/2] cp, mv: use linkat to guarantee semantics

* src/copy.c (copy_internal): Use linkat, not link.
---
 src/copy.c |   29 +++--
 1 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/src/copy.c b/src/copy.c
index e3c5c52..49e620a 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1687,7 +1687,9 @@ copy_internal (char const *src_name, char const *dst_name,
 }
   else
 {
-  bool link_failed = (link (earlier_file, dst_name) != 0);
+  /* We want to guarantee that symlinks are not followed.  */
+  bool link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD,
+  dst_name, 0) != 0);

   /* If the link failed because of an existing destination,
  remove that file and then call link again.  */
@@ -1700,7 +1702,8 @@ copy_internal (char const *src_name, char const *dst_name,
 }
   if (x-verbose)
 printf (_(removed %s\n), quote (dst_name));
-  link_failed = (link (earlier_file, dst_name) != 0);
+  link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD,
+ dst_name, 0) != 0);
 }

   if (link_failed)
@@ -1990,25 +1993,15 @@ 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.  */
+  /* cp, invoked with `--link --no-dereference', should not follow the
+ link; we guarantee this with gnulib's linkat module (on systems
+ where link(2) follows the link, gnulib creates a symlink with
+ identical contents, which is good enough for our purposes).  */
   else if (x-hard_link
-(!LINK_FOLLOWS_SYMLINKS
-   || !S_ISLNK (src_mode)
+(!S_ISLNK (src_mode)
|| x-dereference != DEREF_NEVER))
 {
-  if (link (src_name, dst_name))
+   if (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, 0))
 {
   error (0, errno, _(cannot create link %s), quote (dst_name));
   goto un_backup;
-- 
1.6.5.rc1


From d7b4703e46ef2b377704f56dac6e57f0648637d4 Mon Sep 17 00:00:00 2001
From: Eric Blake e...@byu.net
Date: Thu, 24 Sep 2009 17:18:47 -0600
Subject: [PATCH 2/2] stdbuf: improve path search

* src/stdbuf.c (set_program_path): use gnulib methods for better
file name handling.
---
 src/stdbuf.c |   26 +-
 1 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/src/stdbuf.c b/src/stdbuf.c
index afb7821..c33cdfa 100644
--- a/src/stdbuf.c
+++ b/src/stdbuf.c
@@ -145,34 +145,26 @@ set_program_path (const char *arg)
 }
   else
 {
-  char *path;
-  char tmppath[PATH_MAX + 1];
-