Browse Source

symlink: Use symlinkat if arch does not have the symlink syscall

Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Markos Chandras 11 years ago
parent
commit
81b480369b

+ 1 - 0
include/unistd.h

@@ -909,6 +909,7 @@ libc_hidden_proto(readlink)
 /* Like symlink but a relative path in TO is interpreted relative to TOFD.  */
 extern int symlinkat (const char *__from, int __tofd,
 		      const char *__to) __THROW __nonnull ((1, 3)) __wur;
+libc_hidden_proto(symlinkat)
 
 /* Like readlink but a relative PATH is interpreted relative to FD.  */
 extern ssize_t readlinkat (int __fd, const char *__restrict __path,

+ 1 - 1
libc/sysdeps/linux/common/stubs.c

@@ -403,7 +403,7 @@ make_stub(swapoff)
 make_stub(swapon)
 #endif
 
-#ifndef __NR_symlink
+#if !defined __NR_symlink && !defined __NR_symlinkat
 make_stub(symlink)
 #endif
 

+ 14 - 2
libc/sysdeps/linux/common/symlink.c

@@ -8,8 +8,20 @@
  */
 
 #include <sys/syscall.h>
-
-#if defined __NR_symlink && (defined __USE_BSD || defined __USE_UNIX98 || defined __USE_XOPEN2K)
+#if defined __USE_BSD || defined __USE_UNIX98 || defined __USE_XOPEN2K
 # include <unistd.h>
+
+# if defined __NR_symlinkat && !defined __NR_symlink
+#  include <fcntl.h>
+int symlink(const char *oldpath, const char *newpath)
+{
+	return symlinkat(oldpath, AT_FDCWD, newpath);
+}
+
+# elif defined(__NR_symlink)
+
 _syscall2(int, symlink, const char *, oldpath, const char *, newpath)
+
+# endif
+
 #endif

+ 1 - 0
libc/sysdeps/linux/common/symlinkat.c

@@ -11,6 +11,7 @@
 
 #ifdef __NR_symlinkat
 _syscall3(int, symlinkat, const char *, from, int, tofd, const char *, to)
+libc_hidden_def(symlinkat)
 #else
 /* should add emulation with symlink() and /proc/self/fd/ ... */
 #endif