1 /* Create a hard link relative to open directories.
2 Copyright (C) 2009-2024 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 <https://www.gnu.org/licenses/>. */
17 /* written by Eric Blake */
30 #include "areadlink.h"
32 #include "eloop-threshold.h"
33 #include "filenamecat.h"
34 #include "openat-priv.h"
36 #if !HAVE_LINKAT || LINKAT_SYMLINK_NOTSUP
38 /* Create a link. If FILE1 is a symlink, either create a hardlink to
39 that symlink, or fake it by creating an identical symlink. */
40 # if LINK_FOLLOWS_SYMLINKS == 0
41 # define link_immediate link
44 link_immediate (char const *file1
, char const *file2
)
46 char *target
= areadlink (file1
);
49 /* A symlink cannot be modified in-place. Therefore, creating
50 an identical symlink behaves like a hard link to a symlink,
51 except for incorrect st_ino and st_nlink. However, we must
52 be careful of EXDEV. */
55 char *dir
= mdir_name (file2
);
62 if (lstat (file1
, &st1
) == 0 && stat (dir
, &st2
) == 0)
64 if (st1
.st_dev
== st2
.st_dev
)
66 int result
= symlink (target
, file2
);
81 return link (file1
, file2
);
83 # endif /* LINK_FOLLOWS_SYMLINKS == 0 */
85 /* Create a link. If FILE1 is a symlink, create a hardlink to the
86 canonicalized file. */
87 # if 0 < LINK_FOLLOWS_SYMLINKS
88 # define link_follow link
91 link_follow (char const *file1
, char const *file2
)
93 char *name
= (char *) file1
;
96 int i
= __eloop_threshold ();
98 /* Using realpath or canonicalize_file_name is too heavy-handed: we
99 don't need an absolute name, and we don't need to resolve
100 intermediate symlinks, just the basename of each iteration. */
101 while (i
-- && (target
= areadlink (name
)))
103 if (IS_ABSOLUTE_FILE_NAME (target
))
111 char *dir
= mdir_name (name
);
120 name
= mfile_name_concat (dir
, target
, NULL
);
135 if (!target
&& errno
!= EINVAL
)
141 result
= link (name
, file2
);
146 # endif /* 0 < LINK_FOLLOWS_SYMLINKS */
148 /* On Solaris, link() doesn't follow symlinks by default, but does so as soon
149 as a library or executable takes part in the program that has been compiled
150 with "c99" or "cc -xc99=all" or "cc ... /usr/lib/values-xpg4.o ...". */
151 # if LINK_FOLLOWS_SYMLINKS == -1
153 /* Reduce the penalty of link_immediate and link_follow by incorporating the
154 knowledge that link()'s behaviour depends on the __xpg4 variable. */
158 solaris_optimized_link_immediate (char const *file1
, char const *file2
)
161 return link (file1
, file2
);
162 return link_immediate (file1
, file2
);
166 solaris_optimized_link_follow (char const *file1
, char const *file2
)
169 return link (file1
, file2
);
170 return link_follow (file1
, file2
);
173 # define link_immediate solaris_optimized_link_immediate
174 # define link_follow solaris_optimized_link_follow
178 #endif /* !HAVE_LINKAT || LINKAT_SYMLINK_NOTSUP */
182 /* Create a link to FILE1, in the directory open on descriptor FD1, to FILE2,
183 in the directory open on descriptor FD2. If FILE1 is a symlink, FLAG
184 controls whether to dereference FILE1 first. If possible, do it without
185 changing the working directory. Otherwise, resort to using
186 save_cwd/fchdir, then rename/restore_cwd. If either the save_cwd or
187 the restore_cwd fails, then give a diagnostic and exit nonzero. */
190 linkat (int fd1
, char const *file1
, int fd2
, char const *file2
, int flag
)
192 if (flag
& ~AT_SYMLINK_FOLLOW
)
197 return at_func2 (fd1
, file1
, fd2
, file2
,
198 flag
? link_follow
: link_immediate
);
201 #else /* HAVE_LINKAT */
205 /* Create a link. If FILE1 is a symlink, create a hardlink to the
206 canonicalized file. */
209 linkat_follow (int fd1
, char const *file1
, int fd2
, char const *file2
)
211 char *name
= (char *) file1
;
214 int i
= __eloop_threshold ();
216 /* There is no realpathat. */
217 while (i
-- && (target
= areadlinkat (fd1
, name
)))
219 if (IS_ABSOLUTE_FILE_NAME (target
))
227 char *dir
= mdir_name (name
);
236 name
= mfile_name_concat (dir
, target
, NULL
);
251 if (!target
&& errno
!= EINVAL
)
257 result
= linkat (fd1
, name
, fd2
, file2
, 0);
264 /* Like linkat, but guarantee that AT_SYMLINK_FOLLOW works even on
265 older Linux kernels. */
268 rpl_linkat (int fd1
, char const *file1
, int fd2
, char const *file2
, int flag
)
270 if (flag
& ~AT_SYMLINK_FOLLOW
)
276 # if LINKAT_TRAILING_SLASH_BUG
277 /* Reject trailing slashes on non-directories. */
279 size_t len1
= strlen (file1
);
280 size_t len2
= strlen (file2
);
281 if ((len1
&& file1
[len1
- 1] == '/')
282 || (len2
&& file2
[len2
- 1] == '/'))
284 /* Let linkat() decide whether hard-linking directories is legal.
285 If fstatat() fails, then linkat() should fail for the same reason;
286 if fstatat() succeeds, require a directory. */
288 if (fstatat (fd1
, file1
, &st
, flag
? 0 : AT_SYMLINK_NOFOLLOW
))
290 if (!S_ISDIR (st
.st_mode
))
301 int result
= linkat (fd1
, file1
, fd2
, file2
, flag
);
302 # if LINKAT_SYMLINK_NOTSUP
303 /* OS X 10.10 has linkat() but it doesn't support
304 hardlinks to symlinks. Fallback to our emulation
306 if (result
== -1 && (errno
== ENOTSUP
|| errno
== EOPNOTSUPP
))
307 return at_func2 (fd1
, file1
, fd2
, file2
, link_immediate
);
312 /* Cache the information on whether the system call really works. */
314 static int have_follow_really
; /* 0 = unknown, 1 = yes, -1 = no */
315 if (0 <= have_follow_really
)
317 int result
= linkat (fd1
, file1
, fd2
, file2
, flag
);
318 if (!(result
== -1 && errno
== EINVAL
))
320 have_follow_really
= 1;
323 have_follow_really
= -1;
326 return linkat_follow (fd1
, file1
, fd2
, file2
);
329 #endif /* HAVE_LINKAT */