summaryrefslogtreecommitdiffstats
path: root/dir.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-19 16:10:06 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-19 16:10:06 +0000
commitb19265cb49d5b8824f9198f3aa36c6c91cd512a8 (patch)
treeb1072cea18880d111de0d484721c502e82ae78d6 /dir.c
parent2f3c6a440c0d4a917c7b2cfa8fffc82d925e4b7e (diff)
downloadruby-b19265cb49d5b8824f9198f3aa36c6c91cd512a8.tar.gz
ruby-b19265cb49d5b8824f9198f3aa36c6c91cd512a8.tar.xz
ruby-b19265cb49d5b8824f9198f3aa36c6c91cd512a8.zip
* dir.c (DEFINE_STRUCT_DIRENT): use union to allocate sufficient
memory space for Solaris. a patch from Naohisa GOTO <ngoto at gen-info.osaka-u.ac.jp> in [ruby-dev:39132]. [ruby-dev:39062] * configure.in (SIZEOF_STRUCT_DIRENT_TOO_SMALL): Solaris dirent check. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@24585 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'dir.c')
-rw-r--r--dir.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/dir.c b/dir.c
index c97c702da..8d3c57f0f 100644
--- a/dir.c
+++ b/dir.c
@@ -491,6 +491,39 @@ dir_path(VALUE dir)
# define IF_HAVE_READDIR_R(something) /* nothing */
#endif
+#if defined SIZEOF_STRUCT_DIRENT_TOO_SMALL
+# include <limits.h>
+# define NAME_MAX_FOR_STRUCT_DIRENT 255
+# if defined NAME_MAX
+# if NAME_MAX_FOR_STRUCT_DIRENT < NAME_MAX
+# undef NAME_MAX_FOR_STRUCT_DIRENT
+# define NAME_MAX_FOR_STRUCT_DIRENT NAME_MAX
+# endif
+# endif
+# if defined _POSIX_NAME_MAX
+# if NAME_MAX_FOR_STRUCT_DIRENT < _POSIX_NAME_MAX
+# undef NAME_MAX_FOR_STRUCT_DIRENT
+# define NAME_MAX_FOR_STRUCT_DIRENT _POSIX_NAME_MAX
+# endif
+# endif
+# if defined _XOPEN_NAME_MAX
+# if NAME_MAX_FOR_STRUCT_DIRENT < _XOPEN_NAME_MAX
+# undef NAME_MAX_FOR_STRUCT_DIRENT
+# define NAME_MAX_FOR_STRUCT_DIRENT _XOPEN_NAME_MAX
+# endif
+# endif
+# define DEFINE_STRUCT_DIRENT \
+ union { \
+ struct dirent dirent; \
+ char dummy[offsetof(struct dirent, d_name) + \
+ NAME_MAX_FOR_STRUCT_DIRENT + 1]; \
+ }
+# define STRUCT_DIRENT(entry) ((entry).dirent)
+#else
+# define DEFINE_STRUCT_DIRENT struct dirent
+# define STRUCT_DIRENT(entry) (entry)
+#endif
+
/*
* call-seq:
* dir.read => string or nil
@@ -508,11 +541,11 @@ dir_read(VALUE dir)
{
struct dir_data *dirp;
struct dirent *dp;
- IF_HAVE_READDIR_R(struct dirent entry);
+ IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
GetDIR(dir, dirp);
errno = 0;
- if (READDIR(dirp->dir, dirp->enc, &entry, dp)) {
+ if (READDIR(dirp->dir, dirp->enc, &STRUCT_DIRENT(entry), dp)) {
return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc);
}
else if (errno == 0) { /* end of stream */
@@ -546,12 +579,12 @@ dir_each(VALUE dir)
{
struct dir_data *dirp;
struct dirent *dp;
- IF_HAVE_READDIR_R(struct dirent entry);
+ IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
RETURN_ENUMERATOR(dir, 0, 0);
GetDIR(dir, dirp);
rewinddir(dirp->dir);
- while (READDIR(dirp->dir, dirp->enc, &entry, dp)) {
+ while (READDIR(dirp->dir, dirp->enc, &STRUCT_DIRENT(entry), dp)) {
rb_yield(rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc));
if (dirp->dir == NULL) dir_closed();
}
@@ -1270,11 +1303,11 @@ glob_helper(
if (magical || recursive) {
struct dirent *dp;
DIR *dirp;
- IF_HAVE_READDIR_R(struct dirent entry);
+ IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
dirp = do_opendir(*path ? path : ".", flags);
if (dirp == NULL) return 0;
- while (READDIR(dirp, enc, &entry, dp)) {
+ while (READDIR(dirp, enc, &STRUCT_DIRENT(entry), dp)) {
char *buf = join_path(path, dirsep, dp->d_name);
enum answer new_isdir = UNKNOWN;