diff options
author | Jim Meyering <jim@meyering.net> | 1999-11-07 10:50:11 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 1999-11-07 10:50:11 +0000 |
commit | 6e8ec1114f5d26b725861d8d204bb5e1bd118ea6 (patch) | |
tree | e576080a024f1d6204c14d19e93dd6bc0d90c0de /src/ln.c | |
parent | 6cdbe935853fed5685087813f07fe689b4077ff7 (diff) | |
download | coreutils-6e8ec1114f5d26b725861d8d204bb5e1bd118ea6.tar.xz |
Allow hard links to symlinks on systems that support it.
(STAT_LIKE_LINK): Define.
(do_link): Use STAT_LIKE_LINK, rather than bare `stat', and perform
the extra lstat only on systems where LINK_FOLLOWS_SYMLINKS.
Diffstat (limited to 'src/ln.c')
-rw-r--r-- | src/ln.c | 26 |
1 files changed, 23 insertions, 3 deletions
@@ -49,6 +49,20 @@ int link (); /* Some systems don't declare this anywhere. */ int symlink (); #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 + to a directory. Otherwise, we have to use *lstat* so that we allow + users to make hard links to symlinks-that-point-to-directories. */ + +#if LINK_FOLLOWS_SYMLINKS +# define STAT_LIKE_LINK(File, Stat_buf) \ + stat (File, Stat_buf) +#else +# define STAT_LIKE_LINK(File, Stat_buf) \ + lstat (File, Stat_buf) +#endif + /* Construct a string NEW_DEST by concatenating DEST, a slash, and basename(SOURCE) in alloca'd memory. Don't modify DEST or SOURCE. */ @@ -144,17 +158,23 @@ do_link (const char *source, const char *dest) On other systems, link follows symlinks, so this check is right. */ if (!symbolic_link) { - if (stat (source, &source_stats) != 0) + if (STAT_LIKE_LINK (source, &source_stats) != 0) { +#if LINK_FOLLOWS_SYMLINKS /* This still could be a legitimate request: if SOURCE is a dangling symlink. */ - if (errno != ENOENT - || lstat (source, &source_stats) != 0) + if (errno == ENOENT && lstat (source, &source_stats) == 0) + { + /* FIXME: Consider giving a warning that this is not portable. */ + } + else +#endif { error (0, errno, "%s", source); return 1; } } + if (!hard_dir_link && S_ISDIR (source_stats.st_mode)) { error (0, 0, _("%s: hard link not allowed for directory"), source); |