diff -r 3ecddf168f1f Modules/posixmodule.c --- a/Modules/posixmodule.c Tue Nov 29 00:53:09 2011 +0100 +++ b/Modules/posixmodule.c Thu Dec 01 23:27:21 2011 +0100 @@ -2079,6 +2079,80 @@ } #endif /* HAVE_LINK */ +#if ! defined(MS_WINDOWS) || !defined(PYOS_OS2) || defined(HAVE_OPENDIR) +/* Helper function for readdir_r(). + + Taken from http://womble.decadent.org.uk/readdir_r-advisory.html, + written by Ben Hutchings , modified for Python + by Thouis (Ray) Jones , and distributed under + following license: + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following condition: + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ + +#ifdef HAVE_LIMITS_H +#include +#endif + +#ifdef STDC_HEADERS +#include +#endif + +/* Calculate the required buffer size (in bytes) for directory * + * entries read from the given directory handle. Return -1 if this * + * this cannot be done. * + * * + * This code does not trust values of NAME_MAX that are less than * + * 255, since some systems (including at least HP-UX) incorrectly * + * define it to be a smaller value. * + * * + * If you use autoconf, include fpathconf and dirfd in your * + * AC_CHECK_FUNCS list. Otherwise use some other method to detect * + * and use them where available. */ + +#define HAVE_DIRENT_BUF_SIZE +size_t dirent_buf_size(DIR * dirp) +{ + long name_max; + size_t name_end; +# if defined(HAVE_FPATHCONF) && defined(HAVE_DIRFD) \ + && defined(_PC_NAME_MAX) + name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); + if (name_max == -1) +# if defined(NAME_MAX) + name_max = (NAME_MAX> 255) ? NAME_MAX : 255; +# else + return (size_t)(-1); +# endif +# else +# if defined(NAME_MAX) + name_max = (NAME_MAX> 255) ? NAME_MAX : 255; +# else +# undef HAVE_DIRENT_BUF_SIZE + return (size_t)(-1); +# endif +# endif + name_end = (size_t)offsetof(struct dirent, d_name) + name_max + 1; + return (name_end> sizeof(struct dirent) + ? name_end : sizeof(struct dirent)); +} + +#endif /* which os */ + PyDoc_STRVAR(posix_listdir__doc__, "listdir(path) -> list_of_strings\n\n\ @@ -2322,7 +2396,8 @@ char *name = NULL; PyObject *d, *v; DIR *dirp; - struct dirent *ep; + struct dirent *ep, *buf = NULL; + size_t de_size = -1; int arg_is_unicode = 1; errno = 0; @@ -2345,11 +2420,34 @@ PyMem_Free(name); return NULL; } + +#ifdef HAVE_DIRENT_BUF_SIZE + de_size = dirent_buf_size(dirp); + /* We don't error if size == -1, as we will switch below between + readdir / readdir_r on whether buf != NULL */ + if (de_size != -1) { + buf = (struct dirent *) malloc(de_size); + if (buf == NULL) { + /* don't error, just switch to readdir below. */ + ; + } + } +#endif + for (;;) { errno = 0; - Py_BEGIN_ALLOW_THREADS - ep = readdir(dirp); - Py_END_ALLOW_THREADS + + if (buf == NULL) { + ep = readdir(dirp); + } else { + Py_BEGIN_ALLOW_THREADS + errno = readdir_r(dirp, buf, &ep); + Py_END_ALLOW_THREADS + if (errno) { + ep = NULL; + } + } + if (ep == NULL) { if (errno == 0) { break; @@ -2358,6 +2456,7 @@ closedir(dirp); Py_END_ALLOW_THREADS Py_DECREF(d); + free(buf); return posix_error_with_allocated_filename(name); } } @@ -2401,6 +2500,7 @@ closedir(dirp); Py_END_ALLOW_THREADS PyMem_Free(name); + free(buf); return d; diff -r 3ecddf168f1f configure.in --- a/configure.in Tue Nov 29 00:53:09 2011 +0100 +++ b/configure.in Thu Dec 01 23:27:21 2011 +0100 @@ -1370,8 +1370,8 @@ AC_HEADER_STDC AC_CHECK_HEADERS(asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \ fcntl.h grp.h \ -ieeefp.h io.h langinfo.h libintl.h ncurses.h poll.h process.h pthread.h \ -shadow.h signal.h stdint.h stropts.h termios.h thread.h \ +ieeefp.h io.h langinfo.h libintl.h limits.h ncurses.h poll.h process.h pthread.h \ +shadow.h signal.h stddef.h stdint.h stropts.h termios.h thread.h \ unistd.h utime.h \ sys/audioio.h sys/bsdtty.h sys/epoll.h sys/event.h sys/file.h sys/loadavg.h \ sys/lock.h sys/mkdev.h sys/modem.h \ @@ -2720,7 +2720,7 @@ # checks for library functions AC_CHECK_FUNCS(alarm setitimer getitimer bind_textdomain_codeset chown \ - clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ + clock confstr ctermid dirp execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ initgroups kill killpg lchmod lchown lstat mkfifo mknod mktime \

AltStyle によって変換されたページ (->オリジナル) /