1 /* Create a hard link relative to open directories.
2 Copyright (C) 2009 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* written by Eric Blake */
28 #include "areadlink.h"
30 #include "filenamecat.h"
31 #include "openat-priv.h"
34 # include <sys/param.h>
38 # define MAXSYMLINKS SYMLOOP_MAX
40 # define MAXSYMLINKS 20
44 /* Create a link. If FILE1 is a symlink, either create a hardlink to
45 that symlink, or fake it by creating an identical symlink. */
46 #if LINK_FOLLOWS_SYMLINKS == 0
47 # define link_immediate link
50 link_immediate (char const *file1, char const *file2)
52 char *target = areadlink (file1);
55 /* A symlink cannot be modified in-place. Therefore, creating
56 an identical symlink behaves like a hard link to a symlink,
57 except for incorrect st_ino and st_nlink. However, we must
58 be careful of EXDEV. */
61 char *dir = mdir_name (file2);
68 if (lstat (file1, &st1) == 0 && stat (dir, &st2) == 0)
70 if (st1.st_dev == st2.st_dev)
72 int result = symlink (target, file2);
73 int saved_errno = errno;
89 return link (file1, file2);
93 /* Create a link. If FILE1 is a symlink, create a hardlink to the
94 canonicalized file. */
95 #if 0 < LINK_FOLLOWS_SYMLINKS
96 # define link_follow link
99 link_follow (char const *file1, char const *file2)
101 char *name = (char *) file1;
106 /* Using realpath or canonicalize_file_name is too heavy-handed: we
107 don't need an absolute name, and we don't need to resolve
108 intermediate symlinks, just the basename of each iteration. */
109 while (i-- && (target = areadlink (name)))
111 if (IS_ABSOLUTE_FILE_NAME (target))
119 char *dir = mdir_name (name);
128 name = mfile_name_concat (dir, target, NULL);
143 if (!target && errno != EINVAL)
147 int saved_errno = errno;
153 result = link (name, file2);
156 int saved_errno = errno;
164 /* Create a link to FILE1, in the directory open on descriptor FD1, to FILE2,
165 in the directory open on descriptor FD2. If FILE1 is a symlink, FLAG
166 controls whether to dereference FILE1 first. If possible, do it without
167 changing the working directory. Otherwise, resort to using
168 save_cwd/fchdir, then rename/restore_cwd. If either the save_cwd or
169 the restore_cwd fails, then give a diagnostic and exit nonzero. */
172 linkat (int fd1, char const *file1, int fd2, char const *file2, int flag)
174 if (flag & ~AT_SYMLINK_FOLLOW)
179 return at_func2 (fd1, file1, fd2, file2,
180 flag ? link_follow : link_immediate);