Skip to content

Commit

Permalink
Fix Linux getcwd for long paths
Browse files Browse the repository at this point in the history
The getcwd syscall (so far?) can only handle path up to one page
in size.  There is no limit about directory hierarchy depth, though,
and the POSIX getcwd is supposed to handle this.  In that case fall
back to the generic getcwd.

Additionally, optimize the generic getcwd to use openat when possible
to change the asymptotic performance from O(N^2) to O(n).
  • Loading branch information
Ulrich Drepper committed May 8, 2011
1 parent 28377d1 commit 7fb90fb
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 146 deletions.
13 changes: 13 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
2011-05-08 Ulrich Drepper <drepper@gmail.com>

[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/unix/sysv/linux/Makefile [subdir=elf] (sysdep-rtld-routines):
Add dl-getcwd.
* sysdeps/unix/sysv/linux/dl-getcwd.c: New file.
* include/sys/stat.h: Define __fstatat macro.
* 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.

* include/dirent.h (__alloc_dir): Add flags parameter.
* sysdeps/unix/fdopendir.c (__fdopendir): Pass flags to __alloc_dir.
* sysdeps/unix/opendir.c (__opendir): Pass 0 in new parameter to
Expand Down
6 changes: 3 additions & 3 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2011-5-7
GNU C Library NEWS -- history of user-visible changes. 2011-5-8
Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
See the end for copying conditions.

Expand All @@ -23,8 +23,8 @@ Version 2.14
* The following bugs are resolved with this release:

11724, 12393, 12420, 12445, 12454, 12460, 12469, 12489, 12509, 12510,
12518, 12583, 12587, 12597, 12631, 12650, 12653, 12655, 12685, 12714,
12717, 12723, 12734
12518, 12583, 12587, 12597, 12631, 12650, 12653, 12655, 12685, 12713,
12714, 12717, 12723, 12734

Version 2.13

Expand Down
3 changes: 2 additions & 1 deletion dirent/rewinddir.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1995, 1996, 1997, 2011 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
Expand Down Expand Up @@ -29,6 +29,7 @@ rewinddir (dirp)
__set_errno (ENOSYS);
/* No way to indicate failure. */
}
libc_hidden_def (rewinddir)


stub_warning (rewinddir)
Expand Down
2 changes: 2 additions & 0 deletions include/dirent.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ extern DIR *__alloc_dir (int fd, bool close_fd, int flags,
const struct stat64 *statp)
internal_function;

libc_hidden_proto (rewinddir)

#endif
2 changes: 2 additions & 0 deletions include/sys/stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ libc_hidden_proto (__fxstatat64)
#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)
#endif
4 changes: 2 additions & 2 deletions sysdeps/mach/hurd/rewinddir.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
/* Copyright (C) 1994, 1997, 2011 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
Expand All @@ -22,10 +22,10 @@
#include <unistd.h>

/* Rewind DIRP to the beginning of the directory. */
/* XXX should be __rewinddir ? */
void
rewinddir (dirp)
DIR *dirp;
{
seekdir (dirp, (off_t) 0L);
}
libc_hidden_def (rewinddir)
Loading

0 comments on commit 7fb90fb

Please sign in to comment.