summaryrefslogtreecommitdiff
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
commit529f149bfeb4ded03d64240becad21e8c8f0b8b2 (patch)
treeb1072cea18880d111de0d484721c502e82ae78d6
parente1c9ac6bd91e9a96e40077cc16afa1fcabc8436f (diff)
* 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: svn+ssh://ci.ruby-lang.org/ruby/trunk@24585 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog10
-rw-r--r--configure.in4
-rw-r--r--dir.c45
3 files changed, 53 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 1632f1edcd..55f0dcb426 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Thu Aug 20 01:06:48 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * 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.
+
Wed Aug 19 11:32:43 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* enc/unicode.c (CodeRanges): initialized statically.
diff --git a/configure.in b/configure.in
index f881cd82f1..1e32b7db9c 100644
--- a/configure.in
+++ b/configure.in
@@ -750,6 +750,10 @@ when(*)
esac
case "$target_os" in
+when(solaris*)
+ AC_DEFINE(SIZEOF_STRUCT_DIRENT_TOO_SMALL, 1)
+ LIBS="-lm $LIBS"
+ ;;
when(nextstep*) ;;
when(openstep*) ;;
when(rhapsody*) ;;
diff --git a/dir.c b/dir.c
index c97c702dac..8d3c57f0f3 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;