summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-07-20 13:36:52 -0400
committerMike Frysinger <vapier@gentoo.org>2009-07-20 13:36:52 -0400
commitfd72e3042517f3c95ab2d707e1074f4d393b5f9a (patch)
tree37928d802bfb8cfd55ea49dcb16fe03091093e65
parent91f91bcb3abda3780347d681c3bef6201b9ca60f (diff)
first pass at implementing *at funcs
Tested basic functionality with coreutils and things seem to work. At least gives us a basis to jump from. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--include/dirent.h10
-rw-r--r--include/fcntl.h15
-rw-r--r--include/features.h51
-rw-r--r--include/stdio.h5
-rw-r--r--include/sys/stat.h34
-rw-r--r--include/sys/time.h2
-rw-r--r--libc/misc/dirent/opendir.c68
-rw-r--r--libc/sysdeps/linux/common/faccessat.c16
-rw-r--r--libc/sysdeps/linux/common/fchmodat.c16
-rw-r--r--libc/sysdeps/linux/common/fchownat.c16
-rw-r--r--libc/sysdeps/linux/common/fstatat.c27
-rw-r--r--libc/sysdeps/linux/common/fstatat64.c31
-rw-r--r--libc/sysdeps/linux/common/futimesat.c16
-rw-r--r--libc/sysdeps/linux/common/linkat.c16
-rw-r--r--libc/sysdeps/linux/common/mkdirat.c16
-rw-r--r--libc/sysdeps/linux/common/mkfifoat.c19
-rw-r--r--libc/sysdeps/linux/common/mknodat.c25
-rw-r--r--libc/sysdeps/linux/common/openat.c18
-rw-r--r--libc/sysdeps/linux/common/openat64.c25
-rw-r--r--libc/sysdeps/linux/common/readlinkat.c16
-rw-r--r--libc/sysdeps/linux/common/renameat.c16
-rw-r--r--libc/sysdeps/linux/common/symlinkat.c16
-rw-r--r--libc/sysdeps/linux/common/unlinkat.c16
-rw-r--r--libc/sysdeps/linux/common/utimensat.c16
24 files changed, 457 insertions, 49 deletions
diff --git a/include/dirent.h b/include/dirent.h
index d4fc5c7d9..a9ff465f6 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -135,6 +135,14 @@ typedef struct __dirstream DIR;
extern DIR *opendir (__const char *__name) __nonnull ((1));
libc_hidden_proto(opendir)
+#ifdef __USE_XOPEN2K8
+/* Same as opendir, but open the stream on the file descriptor FD.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern DIR *fdopendir (int __fd);
+#endif
+
/* Close the directory stream DIRP.
Return 0 if successful, -1 if not.
@@ -216,7 +224,7 @@ extern void seekdir (DIR *__dirp, long int __pos) __THROW __nonnull ((1));
extern long int telldir (DIR *__dirp) __THROW __nonnull ((1));
#endif
-#if defined __USE_BSD || defined __USE_MISC
+#if defined __USE_BSD || defined __USE_MISC || defined __XOPEN_2K8
/* Return the file descriptor used by DIRP. */
extern int dirfd (DIR *__dirp) __THROW __nonnull ((1));
diff --git a/include/fcntl.h b/include/fcntl.h
index 5d0e4aa82..a6001c0ff 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -56,13 +56,16 @@ __BEGIN_DECLS
# define SEEK_END 2 /* Seek from end of file. */
#endif /* XPG */
-#if 0 /*def __USE_GNU*/
+#ifdef __USE_ATFILE
# define AT_FDCWD -100 /* Special value used to indicate
- openat should use the current
- working directory. */
+ the *at functions should use the
+ current working directory. */
# define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
# define AT_REMOVEDIR 0x200 /* Remove directory instead of
unlinking file. */
+# define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
+# define AT_EACCESS 0x200 /* Test access permitted for
+ effective IDs, not real IDs. */
#endif
/* Do the file control operation described by CMD on FD.
@@ -107,11 +110,11 @@ extern int open64 (__const char *__file, int __oflag, ...) __nonnull ((1));
libc_hidden_proto(open64)
#endif
-#if 0 /*def __USE_GNU*/
-/* Similar to OPEN but a relative path name is interpreted relative to
+#ifdef __USE_ATFILE
+/* Similar to `open' but a relative path name is interpreted relative to
the directory for which FD is a descriptor.
- NOTE: some other OPENAT implementation support additional functionality
+ NOTE: some other `openat' implementation support additional functionality
through this interface, especially using the O_XATTR flag. This is not
yet supported here.
diff --git a/include/features.h b/include/features.h
index 1b401497d..16ed44cba 100644
--- a/include/features.h
+++ b/include/features.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1993,1995-2003,2004,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1993,1995-2006,2007,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -58,9 +58,10 @@
if >=199309L, add IEEE Std 1003.1b-1993;
if >=199506L, add IEEE Std 1003.1c-1995;
if >=200112L, all of IEEE 1003.1-2004
+ if >=200809L, all of IEEE 1003.1-2008
_XOPEN_SOURCE Includes POSIX and XPG things. Set to 500 if
Single Unix conformance is wanted, to 600 for the
- upcoming sixth revision.
+ sixth revision, to 700 for the seventh revision.
_XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions.
_LARGEFILE_SOURCE Some more functions for correct standard I/O.
_LARGEFILE64_SOURCE Additional functionality from LFS for large files.
@@ -77,7 +78,7 @@
The `-ansi' switch to the GNU C compiler defines __STRICT_ANSI__.
If none of these are defined, the default is to have _SVID_SOURCE,
_BSD_SOURCE, and _POSIX_SOURCE set to one and _POSIX_C_SOURCE set to
- 199506L. If more than one of these are defined, they accumulate.
+ 200112L. If more than one of these are defined, they accumulate.
For example __STRICT_ANSI__, _POSIX_SOURCE and _POSIX_C_SOURCE
together give you ISO C, 1003.1, and 1003.2, but nothing else.
@@ -85,6 +86,7 @@
header files to decide what to declare or define:
__USE_ISOC99 Define ISO C99 things.
+ __USE_ISOC95 Define ISO C90 AMD1 (C95) things.
__USE_POSIX Define IEEE Std 1003.1 things.
__USE_POSIX2 Define IEEE Std 1003.2 things.
__USE_POSIX199309 Define IEEE Std 1003.1, and .1b things.
@@ -93,6 +95,7 @@
__USE_XOPEN_EXTENDED Define X/Open Unix things.
__USE_UNIX98 Define Single Unix V2 things.
__USE_XOPEN2K Define XPG6 things.
+ __USE_XOPEN2K8 Define XPG7 things.
__USE_LARGEFILE Define correct standard I/O things.
__USE_LARGEFILE64 Define LFS things with separate names.
__USE_FILE_OFFSET64 Define 64bit interface as default.
@@ -119,6 +122,7 @@
/* Undefine everything, so we get a clean slate. */
#undef __USE_ISOC99
+#undef __USE_ISOC95
#undef __USE_POSIX
#undef __USE_POSIX2
#undef __USE_POSIX199309
@@ -127,6 +131,7 @@
#undef __USE_XOPEN_EXTENDED
#undef __USE_UNIX98
#undef __USE_XOPEN2K
+#undef __USE_XOPEN2K8
#undef __USE_LARGEFILE
#undef __USE_LARGEFILE64
#undef __USE_FILE_OFFSET64
@@ -179,9 +184,9 @@
# undef _POSIX_SOURCE
# define _POSIX_SOURCE 1
# undef _POSIX_C_SOURCE
-# define _POSIX_C_SOURCE 199506L
+# define _POSIX_C_SOURCE 200809L
# undef _XOPEN_SOURCE
-# define _XOPEN_SOURCE 600
+# define _XOPEN_SOURCE 700
# undef _XOPEN_SOURCE_EXTENDED
# define _XOPEN_SOURCE_EXTENDED 1
# ifdef __UCLIBC_HAS_LFS__
@@ -215,6 +220,12 @@
# define __USE_ISOC99 1
#endif
+/* This is to enable the ISO C90 Amendment 1:1995 extension. */
+#if (defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE \
+ || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199409L))
+# define __USE_ISOC95 1
+#endif
+
/* If none of the ANSI/POSIX macros are defined, use POSIX.1 and POSIX.2
(and IEEE Std 1003.1b-1993 unless _XOPEN_SOURCE is defined). */
#if ((!defined __STRICT_ANSI__ || (_XOPEN_SOURCE - 0) >= 500) && \
@@ -222,9 +233,14 @@
# define _POSIX_SOURCE 1
# if defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 500
# define _POSIX_C_SOURCE 2
-# else
+# elif defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 600
# define _POSIX_C_SOURCE 199506L
+# elif defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 700
+# define _POSIX_C_SOURCE 200112L
+# else
+# define _POSIX_C_SOURCE 200809L
# endif
+# define __USE_POSIX_IMPLICITLY 1
#endif
#if defined _POSIX_SOURCE || _POSIX_C_SOURCE >= 1 || defined _XOPEN_SOURCE
@@ -245,6 +261,14 @@
#if (_POSIX_C_SOURCE - 0) >= 200112L
# define __USE_XOPEN2K 1
+# undef __USE_ISOC99
+# define __USE_ISOC99 1
+#endif
+
+#if (_POSIX_C_SOURCE - 0) >= 200809L
+# define __USE_XOPEN2K8 1
+# undef _ATFILE_SOURCE
+# define _ATFILE_SOURCE 1
#endif
#ifdef _XOPEN_SOURCE
@@ -255,6 +279,9 @@
# undef _LARGEFILE_SOURCE
# define _LARGEFILE_SOURCE 1
# if (_XOPEN_SOURCE - 0) >= 600
+# if (_XOPEN_SOURCE - 0) >= 700
+# define __USE_XOPEN2K8 1
+# endif
# define __USE_XOPEN2K 1
# undef __USE_ISOC99
# define __USE_ISOC99 1
@@ -321,7 +348,7 @@
#ifdef __UCLIBC_HAS_WCHAR__
/* wchar_t uses ISO 10646-1 (2nd ed., published 2000-09-15) / Unicode 3.1. */
-# define __STDC_ISO_10646__ 200009L
+#define __STDC_ISO_10646__ 200009L
#endif
/* There is an unwholesomely huge amount of code out there that depends on the
@@ -380,10 +407,8 @@
* uclibc itself is usually built without __USE_EXTERN_INLINES,
* remove "&& !defined __OPTIMIZE_SIZE__" part to do otherwise.
*/
-#if __GNUC_PREREQ (2, 7) \
- && defined __OPTIMIZE__ \
- && !defined __OPTIMIZE_SIZE__ \
- && !defined __NO_INLINE__ \
+#if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \
+ && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__ \
&& (defined __extern_inline || defined __GNUC_GNU_INLINE__)
# define __USE_EXTERN_INLINES 1
#endif
@@ -422,10 +447,6 @@ uClibc was built without large file support enabled.
# define __USE_LARGEFILE64 1
#endif
-/* uClibc does not support *at interfaces. */
-#undef _ATFILE_SOURCE
-#undef __USE_ATFILE
-
#ifdef _LIBC
# include <libc-internal.h>
#endif
diff --git a/include/stdio.h b/include/stdio.h
index 9336fe3cc..3c86f256b 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -148,6 +148,11 @@ libc_hidden_proto(remove)
extern int rename (__const char *__old, __const char *__new) __THROW;
__END_NAMESPACE_STD
+#ifdef __USE_ATFILE
+/* Rename file OLD relative to OLDFD to NEW relative to NEWFD. */
+extern int renameat (int __oldfd, __const char *__old, int __newfd,
+ __const char *__new) __THROW;
+#endif
__BEGIN_NAMESPACE_STD
/* Create a temporary file and open it read/write.
diff --git a/include/sys/stat.h b/include/sys/stat.h
index b2c87ddd5..d84ace5a2 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1992,1995-2004,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1995-2004, 2005, 2006, 2007, 2009
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -27,11 +28,12 @@
#include <bits/types.h> /* For __mode_t and __dev_t. */
-#if defined __USE_XOPEN || defined __USE_MISC
+#if defined __USE_XOPEN || defined __USE_XOPEN2K || defined __USE_MISC \
+ || defined __USE_ATFILE
# if defined __USE_XOPEN || defined __USE_XOPEN2K
# define __need_time_t
# endif
-# ifdef __USE_MISC
+# if defined __USE_MISC || defined __USE_ATFILE
# define __need_timespec
# endif
# include <time.h> /* For time_t resp. timespec. */
@@ -251,12 +253,14 @@ extern int __REDIRECT_NTH (fstatat, (int __fd, __const char *__restrict __file,
# endif
# endif
+# ifdef __USE_LARGEFILE64
extern int fstatat64 (int __fd, __const char *__restrict __file,
struct stat64 *__restrict __buf, int __flag)
__THROW __nonnull ((2, 3));
+# endif
#endif
-#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K
# ifndef __USE_FILE_OFFSET64
/* Get file attributes about FILE and put them in BUF.
If FILE is a symbolic link, do not follow it. */
@@ -303,7 +307,8 @@ extern int fchmod (int __fd, __mode_t __mode) __THROW;
#ifdef __USE_ATFILE
/* Set file access permissions of FILE relative to
the directory FD is open on. */
-extern int fchmodat (int __fd, __const char *__file, __mode_t mode, int __flag)
+extern int fchmodat (int __fd, __const char *__file, __mode_t __mode,
+ int __flag)
__THROW __nonnull ((2)) __wur;
#endif /* Use ATFILE. */
@@ -339,14 +344,15 @@ extern int mkdirat (int __fd, __const char *__path, __mode_t __mode)
extern int mknod (__const char *__path, __mode_t __mode, __dev_t __dev)
__THROW __nonnull ((1));
libc_hidden_proto(mknod)
-#endif
-#ifdef __USE_ATFILE
+# ifdef __USE_ATFILE
/* Like mknod, create a new device file with permission bits MODE and
device number DEV. But interpret relative PATH names relative to
the directory associated with FD. */
extern int mknodat (int __fd, __const char *__path, __mode_t __mode,
__dev_t __dev) __THROW __nonnull ((2));
+libc_hidden_proto(mknodat)
+# endif
#endif
@@ -361,7 +367,21 @@ extern int mkfifo (__const char *__path, __mode_t __mode)
extern int mkfifoat (int __fd, __const char *__path, __mode_t __mode)
__THROW __nonnull ((2));
#endif
+
+#ifdef __USE_ATFILE
+/* Set file access and modification times relative to directory file
+ descriptor. */
+extern int utimensat (int __fd, __const char *__path,
+ __const struct timespec __times[2],
+ int __flags)
+ __THROW __nonnull ((2));
+#endif
+#ifdef __USE_XOPEN2K8
+/* Set file access and modification times of the file associated with FD. */
+extern int futimens (int __fd, __const struct timespec __times[2]) __THROW;
+#endif
+
/* on uClibc we have unversioned struct stat and mknod.
* bits/stat.h is filled with wrong info, so we undo it here. */
#undef _STAT_VER
diff --git a/include/sys/time.h b/include/sys/time.h
index a6388e454..33f5873ee 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -153,7 +153,7 @@ extern int lutimes (__const char *__file, __const struct timeval __tvp[2])
extern int futimes (int __fd, __const struct timeval __tvp[2]) __THROW;
#endif
-#if 0 /*def __USE_GNU*/
+#ifdef __USE_GNU
/* Change the access time of FILE relative to FD to TVP[0] and the
modification time of FILE to TVP[1]. If TVP is a null pointer, use
the current time instead. Returns 0 on success, -1 on errors. */
diff --git a/libc/misc/dirent/opendir.c b/libc/misc/dirent/opendir.c
index 50e4082da..fa07d0052 100644
--- a/libc/misc/dirent/opendir.c
+++ b/libc/misc/dirent/opendir.c
@@ -12,14 +12,55 @@
#include <unistd.h>
#include <sys/dir.h>
#include <sys/stat.h>
+#include <dirent.h>
#include "dirstream.h"
-/* libc_hidden_proto(opendir) */
-/* libc_hidden_proto(open) */
-/* libc_hidden_proto(fcntl) */
-/* libc_hidden_proto(close) */
-/* libc_hidden_proto(stat) */
-/* libc_hidden_proto(fstat) */
+static DIR *fd_to_DIR(int fd, __blksize_t size)
+{
+ DIR *ptr;
+
+ ptr = malloc(sizeof(*ptr));
+ if (!ptr)
+ return NULL;
+
+ ptr->dd_fd = fd;
+ ptr->dd_nextloc = ptr->dd_size = ptr->dd_nextoff = 0;
+ ptr->dd_max = size;
+ if (ptr->dd_max < 512)
+ ptr->dd_max = 512;
+
+ ptr->dd_buf = calloc(1, ptr->dd_max);
+ if (!ptr->dd_buf) {
+ free(ptr);
+ return NULL;
+ }
+ __pthread_mutex_init(&ptr->dd_lock, NULL);
+
+ return ptr;
+}
+
+DIR *fdopendir(int fd)
+{
+ int flags;
+ struct stat st;
+
+ if (fstat(fd, &st))
+ return NULL;
+ if (!S_ISDIR(st.st_mode)) {
+ __set_errno(ENOTDIR);
+ return NULL;
+ }
+
+ flags = fcntl(fd, F_GETFL);
+ if (flags == -1)
+ return NULL;
+ if ((flags & O_ACCMODE) == O_WRONLY) {
+ __set_errno(EINVAL);
+ return NULL;
+ }
+
+ return fd_to_DIR(fd, st.st_blksize);
+}
/* opendir just makes an open() call - it return NULL if it fails
* (open sets errno), otherwise it returns a DIR * pointer.
@@ -61,23 +102,12 @@ close_and_ret:
__set_errno(saved_errno);
return NULL;
}
- if (!(ptr = malloc(sizeof(*ptr))))
- goto nomem_close_and_ret;
- ptr->dd_fd = fd;
- ptr->dd_nextloc = ptr->dd_size = ptr->dd_nextoff = 0;
- ptr->dd_max = statbuf.st_blksize;
- if (ptr->dd_max < 512)
- ptr->dd_max = 512;
-
- if (!(ptr->dd_buf = calloc(1, ptr->dd_max))) {
- free(ptr);
-nomem_close_and_ret:
+ ptr = fd_to_DIR(fd, statbuf.st_blksize);
+ if (!ptr) {
close(fd);
__set_errno(ENOMEM);
- return NULL;
}
- __pthread_mutex_init(&(ptr->dd_lock), NULL);
return ptr;
}
libc_hidden_def(opendir)
diff --git a/libc/sysdeps/linux/common/faccessat.c b/libc/sysdeps/linux/common/faccessat.c
new file mode 100644
index 000000000..09ca129a2
--- /dev/null
+++ b/libc/sysdeps/linux/common/faccessat.c
@@ -0,0 +1,16 @@
+/*
+ * faccessat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifdef __NR_faccessat
+_syscall4(int, faccessat, int, fd, const char *, file, int, type, int, flag)
+#else
+/* should add emulation with faccess() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/fchmodat.c b/libc/sysdeps/linux/common/fchmodat.c
new file mode 100644
index 000000000..7d4dd4e2c
--- /dev/null
+++ b/libc/sysdeps/linux/common/fchmodat.c
@@ -0,0 +1,16 @@
+/*
+ * fchmodat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/stat.h>
+
+#ifdef __NR_fchmodat
+_syscall4(int, fchmodat, int, fd, const char *, file, mode_t, mode, int, flag)
+#else
+/* should add emulation with fchmod() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/fchownat.c b/libc/sysdeps/linux/common/fchownat.c
new file mode 100644
index 000000000..707164d1f
--- /dev/null
+++ b/libc/sysdeps/linux/common/fchownat.c
@@ -0,0 +1,16 @@
+/*
+ * fchownat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifdef __NR_fchownat
+_syscall5(int, fchownat, int, fd, const char *, file, uid_t, owner, gid_t, group, int, flag)
+#else
+/* should add emulation with fchown() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c
new file mode 100644
index 000000000..149c1890d
--- /dev/null
+++ b/libc/sysdeps/linux/common/fstatat.c
@@ -0,0 +1,27 @@
+/*
+ * fstatat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include "xstatconv.h"
+
+#ifdef __NR_fstatat64
+int fstatat(int fd, const char *file, struct stat *buf, int flag)
+{
+ int ret;
+ struct kernel_stat kbuf;
+
+ ret = INLINE_SYSCALL(fstatat64, 4, fd, file, &kbuf, flag);
+ if (ret == 0)
+ __xstat_conv(&kbuf, buf);
+
+ return ret;
+}
+#else
+/* should add emulation with fstat() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c
new file mode 100644
index 000000000..5ae1fadba
--- /dev/null
+++ b/libc/sysdeps/linux/common/fstatat64.c
@@ -0,0 +1,31 @@
+/*
+ * fstatat64() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include "xstatconv.h"
+
+#ifdef __UCLIBC_HAS_LFS__
+
+#ifdef __NR_fstatat64
+int fstatat64(int fd, const char *file, struct stat64 *buf, int flag)
+{
+ int ret;
+ struct kernel_stat64 kbuf;
+
+ ret = INLINE_SYSCALL(fstatat64, 4, fd, file, &kbuf, flag);
+ if (ret == 0)
+ __xstat64_conv(&kbuf, buf);
+
+ return ret;
+}
+#else
+/* should add emulation with fstat64() and /proc/self/fd/ ... */
+#endif
+
+#endif
diff --git a/libc/sysdeps/linux/common/futimesat.c b/libc/sysdeps/linux/common/futimesat.c
new file mode 100644
index 000000000..bd73eae7e
--- /dev/null
+++ b/libc/sysdeps/linux/common/futimesat.c
@@ -0,0 +1,16 @@
+/*
+ * futimesat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/time.h>
+
+#ifdef __NR_futimesat
+_syscall3(int, futimesat, int, fd, const char *, file, const struct timeval *, tvp)
+#else
+/* should add emulation with futimes() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/linkat.c b/libc/sysdeps/linux/common/linkat.c
new file mode 100644
index 000000000..9abe9ec71
--- /dev/null
+++ b/libc/sysdeps/linux/common/linkat.c
@@ -0,0 +1,16 @@
+/*
+ * linkat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifdef __NR_linkat
+_syscall5(int, linkat, int, fromfd, const char *, from, int, tofd, const char *, to, int, flags)
+#else
+/* should add emulation with link() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/mkdirat.c b/libc/sysdeps/linux/common/mkdirat.c
new file mode 100644
index 000000000..4da9468e1
--- /dev/null
+++ b/libc/sysdeps/linux/common/mkdirat.c
@@ -0,0 +1,16 @@
+/*
+ * mkdirat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/stat.h>
+
+#ifdef __NR_mkdirat
+_syscall3(int, mkdirat, int, fd, const char *, path, mode_t, mode)
+#else
+/* should add emulation with mkdir() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/mkfifoat.c b/libc/sysdeps/linux/common/mkfifoat.c
new file mode 100644
index 000000000..e442fe22f
--- /dev/null
+++ b/libc/sysdeps/linux/common/mkfifoat.c
@@ -0,0 +1,19 @@
+/*
+ * mkfifoat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/stat.h>
+
+#ifdef __NR_mknodat
+int mkfifoat(int fd, const char *path, mode_t mode)
+{
+ return mknodat(fd, path, mode | S_IFIFO, 0);
+}
+#else
+/* should add emulation with mkfifo() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/mknodat.c b/libc/sysdeps/linux/common/mknodat.c
new file mode 100644
index 000000000..93b9e6e75
--- /dev/null
+++ b/libc/sysdeps/linux/common/mknodat.c
@@ -0,0 +1,25 @@
+/*
+ * mknodat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/stat.h>
+
+#ifdef __NR_mknodat
+int mknodat(int fd, const char *path, mode_t mode, dev_t dev)
+{
+ unsigned long long int k_dev;
+
+ /* We must convert the value to dev_t type used by the kernel. */
+ k_dev = (dev) & ((1ULL << 32) - 1);
+
+ return INLINE_SYSCALL(mknodat, 4, fd, path, mode, (unsigned int)k_dev);
+}
+libc_hidden_def(mknodat)
+#else
+/* should add emulation with mknod() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/openat.c b/libc/sysdeps/linux/common/openat.c
new file mode 100644
index 000000000..33bd606a1
--- /dev/null
+++ b/libc/sysdeps/linux/common/openat.c
@@ -0,0 +1,18 @@
+/*
+ * openat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define openat __xx_openat
+#include <sys/syscall.h>
+#include <fcntl.h>
+#undef openat
+
+#ifdef __NR_openat
+_syscall4(int, openat, int, fd, const char *, file, int, oflag, mode_t, mode)
+#else
+/* should add emulation with open() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/openat64.c b/libc/sysdeps/linux/common/openat64.c
new file mode 100644
index 000000000..75711aad6
--- /dev/null
+++ b/libc/sysdeps/linux/common/openat64.c
@@ -0,0 +1,25 @@
+/*
+ * openat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define openat64 __xx_openat
+#include <sys/syscall.h>
+#include <fcntl.h>
+#undef openat64
+
+#ifdef __UCLIBC_HAS_LFS__
+
+#ifdef __NR_openat
+int openat64(int fd, const char *file, int oflag, mode_t mode)
+{
+ return openat(fd, file, oflag | O_LARGEFILE, mode);
+}
+#else
+/* should add emulation with open() and /proc/self/fd/ ... */
+#endif
+
+#endif
diff --git a/libc/sysdeps/linux/common/readlinkat.c b/libc/sysdeps/linux/common/readlinkat.c
new file mode 100644
index 000000000..d0a98e115
--- /dev/null
+++ b/libc/sysdeps/linux/common/readlinkat.c
@@ -0,0 +1,16 @@
+/*
+ * readlinkat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifdef __NR_readlinkat
+_syscall4(ssize_t, readlinkat, int, fd, const char *, path, char *, buf, size_t, len)
+#else
+/* should add emulation with readlink() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/renameat.c b/libc/sysdeps/linux/common/renameat.c
new file mode 100644
index 000000000..a898f7b86
--- /dev/null
+++ b/libc/sysdeps/linux/common/renameat.c
@@ -0,0 +1,16 @@
+/*
+ * renameat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <stdio.h>
+
+#ifdef __NR_renameat
+_syscall4(int, renameat, int, oldfd, const char *, old, int, newfd, const char *, new)
+#else
+/* should add emulation with rename() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/symlinkat.c b/libc/sysdeps/linux/common/symlinkat.c
new file mode 100644
index 000000000..6381b3319
--- /dev/null
+++ b/libc/sysdeps/linux/common/symlinkat.c
@@ -0,0 +1,16 @@
+/*
+ * symlinkat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifdef __NR_symlinkat
+_syscall3(int, symlinkat, const char *, from, int, tofd, const char *, to)
+#else
+/* should add emulation with symlink() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/unlinkat.c b/libc/sysdeps/linux/common/unlinkat.c
new file mode 100644
index 000000000..0eaf2b670
--- /dev/null
+++ b/libc/sysdeps/linux/common/unlinkat.c
@@ -0,0 +1,16 @@
+/*
+ * unlinkat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifdef __NR_unlinkat
+_syscall3(int, unlinkat, int, fd, const char *, file, int, flag)
+#else
+/* should add emulation with unlink() and /proc/self/fd/ ... */
+#endif
diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c
new file mode 100644
index 000000000..3c5af8586
--- /dev/null
+++ b/libc/sysdeps/linux/common/utimensat.c
@@ -0,0 +1,16 @@
+/*
+ * utimensat() for uClibc
+ *
+ * Copyright (C) 2009 Analog Devices Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/stat.h>
+
+#ifdef __NR_utimensat
+_syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags)
+#else
+/* should add emulation with utimens() and /proc/self/fd/ ... */
+#endif