[BZ #12713]
* sysdeps/unix/sysv/linux/getcwd.c: If getcwd syscall report
ENAMETOOLONG use generic getcwd.
- * sysdeps/posix/getcwd.c: Add support to use openat.
+ * sysdeps/posix/getcwd.c: Add support to use openat. Make usable
+ in rtld. Use *stat64.
* sysdeps/unix/sysv/linux/Makefile [subdir=elf] (sysdep-rtld-routines):
- Add dl-getcwd.
+ Add dl-getcwd, dl-openat64, dl-opendir, dl-fxstatat64.
* sysdeps/unix/sysv/linux/dl-getcwd.c: New file.
- * include/sys/stat.h: Define __fstatat macro.
+ * sysdeps/unix/sysv/linux/dl-openat64.c: New file.
+ * sysdeps/unix/sysv/linux/dl-opendir.c: New file.
+ * sysdeps/unix/sysv/linux/dl-fxstat64.c: New file.
+ * include/sys/stat.h: Define __fstatat, __lstat64, __fstat64, and
+ __fstatat64 macros.
* include/dirent.h: Add libc_hidden_proto for rewinddir.
* dirent/rewinddir.c: Add libc_hidden_def.
* sysdeps/mach/hurd/rewinddir.c: Likewise.
- * sysdeps/unix/rewinddir.c: Likewise.
+ * sysdeps/unix/rewinddir.c: Likewise. Don't do locking outside libc.
* include/dirent.h (__alloc_dir): Add flags parameter.
* sysdeps/unix/fdopendir.c (__fdopendir): Pass flags to __alloc_dir.
#define lstat(fname, buf) __lxstat (_STAT_VER, fname, buf)
#define __lstat(fname, buf) __lxstat (_STAT_VER, fname, buf)
#define lstat64(fname, buf) __lxstat64 (_STAT_VER, fname, buf)
+#define __lstat64(fname, buf) __lxstat64 (_STAT_VER, fname, buf)
#define stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
#define fstat64(fd, buf) __fxstat64 (_STAT_VER, fd, buf)
+#define __fstat64(fd, buf) __fxstat64 (_STAT_VER, fd, buf)
#define fstat(fd, buf) __fxstat (_STAT_VER, fd, buf)
#define __fstat(fd, buf) __fxstat (_STAT_VER, fd, buf)
#define __fstatat(dfd, fname, buf, flag) \
__fxstatat (_STAT_VER, dfd, fname, buf, flag)
+#define __fstatat64(dfd, fname, buf, flag) \
+ __fxstatat64 (_STAT_VER, dfd, fname, buf, flag)
#endif
# include <sys/param.h>
#endif
-#if defined _LIBC && !defined NOT_IN_libc
+#if defined _LIBC
# include <not-cancel.h>
#else
-# define openat_not_cancel_3(dfd, name, mode) openat (dfd, name, mode)
+# define openat64_not_cancel_3(dfd, name, mode) openat64 (dfd, name, mode)
# define close_not_cancel_no_status(fd) close (fd)
#endif
#endif
#ifndef __GNU_LIBRARY__
-# define __lstat stat
+# define __lstat64 stat64
#endif
\f
#ifndef _LIBC
#endif
#ifdef __ASSUME_ATFCTS
-# define have_openat 1
-#else
-static int have_openat = 0;
+# define __have_atfcts 1
+#elif defined NOT_IN_libc && defined IS_IN_rtld
+static int __rtld_have_atfcts;
+# define __have_atfcts __rtld_have_atfcts
#endif
/* Get the pathname of the current working directory, and put it in SIZE
char *pathp = path + allocated;
*--pathp = '\0';
- struct stat st;
- if (__lstat (".", &st) < 0)
+ struct stat64 st;
+ if (__lstat64 (".", &st) < 0)
goto lose;
dev_t thisdev = st.st_dev;
ino_t thisino = st.st_ino;
- if (__lstat ("/", &st) < 0)
+ if (__lstat64 ("/", &st) < 0)
goto lose;
dev_t rootdev = st.st_dev;
ino_t rootino = st.st_ino;
while (!(thisdev == rootdev && thisino == rootino))
{
- if (have_openat >= 0)
+ if (__have_atfcts >= 0)
{
int mode = O_RDONLY;
#ifdef O_CLOEXEC
mode |= O_CLOEXEC;
#endif
- fd = openat_not_cancel_3 (fd, "..", mode);
+ fd = openat64_not_cancel_3 (fd, "..", mode);
}
else
fd = -1;
if (fd >= 0)
{
fd_needs_closing = true;
- if (__fstat (fd, &st) < 0)
+ if (__fstat64 (fd, &st) < 0)
goto lose;
}
#ifndef __ASSUME_ATFCTS
else if (errno == ENOSYS)
{
- have_openat = -1;
+ __have_atfcts = -1;
/* Look at the parent directory. */
if (dotp == dotlist)
dotp -= 3;
/* Figure out if this directory is a mount point. */
- if (__lstat (dotp, &st) < 0)
+ if (__lstat64 (dotp, &st) < 0)
goto lose;
}
#endif
bool mount_point = dotdev != thisdev;
/* Search for the last directory. */
- if (have_openat >= 0)
+ if (__have_atfcts >= 0)
dirstream = __fdopendir (fd);
#ifndef __ASSUME_ATFCTS
else
/* When we've iterated through all directory entries
without finding one with a matching d_ino, rewind the
stream and consider each name again, but this time, using
- lstat. This is necessary in a chroot on at least one
+ lstat64. This is necessary in a chroot on at least one
system. */
if (use_d_ino)
{
if (use_d_ino && !mount_point && (ino_t) d->d_ino != thisino)
continue;
- if (have_openat >= 0)
+ if (__have_atfcts >= 0)
{
- /* We don't fail here if we cannot stat() a directory entry.
+ /* We don't fail here if we cannot stat64() a directory entry.
This can happen when (network) filesystems fail. If this
entry is in fact the one we are looking for we will find
out soon as we reach the end of the directory without
having found anything. */
- if (__fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
+ if (__fstatat64 (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
continue;
}
#ifndef __ASSUME_ATFCTS
name[dotlist + dotsize - dotp] = '/';
strcpy (&name[dotlist + dotsize - dotp + 1], d->d_name);
# endif
- /* We don't fail here if we cannot stat() a directory entry.
+ /* We don't fail here if we cannot stat64() a directory entry.
This can happen when (network) filesystems fail. If this
entry is in fact the one we are looking for we will find
out soon as we reach the end of the directory without
having found anything. */
- if (__lstat (name, &st) < 0)
+ if (__lstat64 (name, &st) < 0)
continue;
}
#endif
#include <dirstream.h>
/* Rewind DIRP to the beginning of the directory. */
-/* XXX should be __rewinddir ? */
void
rewinddir (dirp)
DIR *dirp;
{
+#ifndef NOT_IN_libc
__libc_lock_lock (dirp->lock);
+#endif
(void) __lseek (dirp->fd, (off_t) 0, SEEK_SET);
dirp->filepos = 0;
dirp->offset = 0;
dirp->size = 0;
+#ifndef NOT_IN_libc
__libc_lock_unlock (dirp->lock);
+#endif
}
libc_hidden_def (rewinddir)
endif
ifeq ($(subdir),elf)
-sysdep-rtld-routines += dl-brk dl-sbrk dl-getcwd
+sysdep-rtld-routines += dl-brk dl-sbrk dl-getcwd dl-openat64 dl-opendir \
+ dl-fxstatat64
CPPFLAGS-lddlibc4 += -DNOT_IN_libc
endif
--- /dev/null
+/* In this implementation we do not really care whether the call fails
+ because of missing kernel support since we do not even call the
+ function in this case. */
+#undef __ASSUME_ATFCTS
+#define __ASSUME_ATFCTS 1
+#include "fxstatat64.c"
--- /dev/null
+/* Copyright (C) 2011 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gmain.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sysdep.h>
+
+
+int
+openat64 (dfd, file, oflag)
+ int dfd;
+ const char *file;
+ int oflag;
+{
+ assert ((oflag & O_CREAT) == 0);
+
+#ifdef __NR_openat
+ return INLINE_SYSCALL (openat, 3, dfd, file, oflag | O_LARGEFILE);
+#else
+ __set_errno (ENOSYS);
+ return -1;
+#endif
+}
--- /dev/null
+/* In this implementation we do not really care whether the opened
+ file descriptor has the CLOEXEC bit set. The only call happens
+ long before there is a call to fork or exec. */
+#undef __ASSUME_O_CLOEXEC
+#define __ASSUME_O_CLOEXEC 1
+#include <opendir.c>
return buf;
}
- // XXX This should not be necessary but the full getcwd implementation
- // drags in too much for the current build proces of ld.so to handle
-#ifndef NOT_IN_libc
/* The system call cannot handle paths longer than a page.
Neither can the magic symlink in /proc/self. Just use the
generic implementation right away. */
return result;
}
-#endif
# if __ASSUME_GETCWD_SYSCALL
/* It should never happen that the `getcwd' syscall failed because
}
weak_alias (__getcwd, getcwd)
- // XXX This should not be necessary but the full getcwd implementation
- // drags in too much for the current build proces of ld.so to handle
-#ifndef NOT_IN_libc
/* Get the code for the generic version. */
#define GETCWD_RETURN_TYPE static char * internal_function
#define __getcwd generic_getcwd
#include <sysdeps/posix/getcwd.c>
-#endif