[Bug #1919] sparc-solaris-2.10 $B$G(B 1.9.2-preview1 $B$,%S%k%I$G$-$J$$(B

e$B%A%1%C%He(B #1919 e$B$,99?7$5$l$^$7$?!#e(B (by Naohisa G.)

e$B%U%!%$%ke(B config.h e$BDI2Ce(B

Solaris e$B$Ne(B readdir_r e$B$K$D$$$FD4$Y$F$_$?$H$3$m!"e(B
“readdir_r considered harmful”
http://womble.decadentplace.org.uk/readdir_r-advisory.html
e$B$H$$$&J8>O$r8+$D$1$^$7$?!#$3$l$K$h$k$H!"e(B

On Linux (with glibc) and most versions of Unix, struct dirent
is large enough to hold maximum-length names from most filesystems,
so this is safe (though > wasteful). This is not true of Solaris
and BeOS, where the d_name member is an array of length 1.

e$B$H$N$3$H$G$7$?!#$I$&$d$ie(B Solaris e$B$G$O!“e(Bstruct dirent entry
e$B$N%a%b%j$re(B
e$B3NJ]$9$k:]!”%U%!%$%kL>$ND9$5$r9MN8$KF~$l$?==J,$JD9$5$r<+A0$G3NJ]$9$ke(B
e$BI,MW$,$"$k$h$&$G$9!#e(B

e$B$3$l$G$I$&$G$7$g$&$+!#e(B

config.h e$B$r<($9$N$rK:$l$F$$$^$7$?!#e(B
1.9.2-preview1e$B$N>l9g$Ne(Bconfig.he$B$re(Bredminee$B>e$K$FE:IU$7$^$9!#e(B
autoconf (e$B%P!<%8%g%se(B 2.61 e$B$r;HMQe(B)e$B$,<+F0E*$Ke(B
#define _POSIX_PTHREAD_SEMANTICS 1
e$B$rDI2C$7$F$/$l$F$$$?$h$&$G$9!#e(B

e$B%Q%C%A$bG0$N$?$a;n$7$^$7$?$,!"$d$O$j%@%a$G$7$?!#e(B
e$B$3$N>l9g$Ne(B config.h e$B$N<B<AE*$JJQ99E@$O!"E:IU$N$b$N$+$ie(B
#define _ALL_SOURCE 1
e$B$N9T$,H4$1$?$@$1$G$7$?!#e(B


http://redmine.ruby-lang.org/issues/show/1919

e$B8eF#$H$$$$$^$9!#<+8J%l%9$G$9!#e(B

On Tue, 11 Aug 2009 12:49:55 +0900
Naohisa G. wrote:

e$B$H$N$3$H$G$7$?!#$I$&$d$ie(B Solaris e$B$G$O!“e(Bstruct dirent entry e$B$N%a%b%j$re(B
e$B3NJ]$9$k:]!”%U%!%$%kL>$ND9$5$r9MN8$KF~$l$?==J,$JD9$5$r<+A0$G3NJ]$9$ke(B
e$BI,MW$,$"$k$h$&$G$9!#e(B

e$B$H$j$"$($:$O!"6&MQBN$K$7$FL5M}LpM}%a%b%j$r3NJ]$9$k$H!"e(Bmake
e$B$ODL$j!"e(B
make install e$B$G$-$^$7$?!#0J2<$K%Q%C%A$rE:IU$7$^$9!#e(B

e$B$h$j@5$7$/$O!">e5-J8>O$N$h$&$KKh2se(B fpathconf e$B$r8F$S=P$7$Fe(B
e$B%U%!%$%kL>$N:GBgD9$r<hF@$7!"$=$l$r85$K%a%b%j$r3NJ]$9$kI,MW$,e(B
e$B$"$k$N$@$H$O;W$$$^$9$,!"$H$j$"$($:$N%Q%C%A$G$9!#e(B

e$BAjJQ$o$i$:e(Bdle$B$N%F%9%H$O<:GT$7$^$9$,!"e(Bdle$B$K$D$$$F$O!"JL%A%1%C%H$re(B
e$B:n$j$?$$$H;W$$$^$9!#e(B

Index: dir.c

— dir.c (revision 24578)
+++ dir.c (working copy)
@@ -491,6 +491,39 @@

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 @@
{
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 @@
    {
    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 @@
    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;

Index: configure.in

— configure.in (revision 24578)
+++ configure.in (working copy)
@@ -750,6 +750,10 @@
esac

case “$target_os” in
+when(solaris*)

  • AC_DEFINE(SIZEOF_STRUCT_DIRENT_TOO_SMALL, 1)
  • LIBS="-lm $LIBS"
  • ;;
    when(nextstep*) ;;
    when(openstep*) ;;
    when(rhapsody*) ;;

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:39132] Re: [Bug #1919] sparc-solaris-2.10
e$B$Ge(B 1.9.2-preview1 e$B$,%S%k%I$G$-$J$$e(B”
on Wed, 19 Aug 2009 22:42:58 +0900, Naohisa GOTO
[email protected] writes:

|> Solaris e$B$Ne(B readdir_r e$B$K$D$$$FD4$Y$F$_$?$H$3$m!“e(B
|> “readdir_r considered harmful”
|> http://womble.decadentplace.org.uk/readdir_r-advisory.html
|> e$B$H$$$&J8>O$r8+$D$1$^$7$?!#$3$l$K$h$k$H!“e(B
|>
|> > On Linux (with glibc) and most versions of Unix, struct dirent
|> > is large enough to hold maximum-length names from most filesystems,
|> > so this is safe (though > wasteful). This is not true of Solaris
|> > and BeOS, where the d_name member is an array of length 1.
|>
|> e$B$H$N$3$H$G$7$?!#$I$&$d$ie(B Solaris e$B$G$O!“e(Bstruct dirent entry e$B$N%a%b%j$re(B
|> e$B3NJ]$9$k:]!”%U%!%$%kL>$ND9$5$r9MN8$KF~$l$?==J,$JD9$5$r<+A0$G3NJ]$9$ke(B
|> e$BI,MW$,$”$k$h$&$G$9!#e(B
|
|e$B$H$j$”$($:$O!"6&MQBN$K$7$FL5M}LpM}%a%b%j$r3NJ]$9$k$H!"e(Bmake e$B$ODL$j!"e(B
|make install e$B$G$-$^$7$?!#0J2<$K%Q%C%A$rE:IU$7$^$9!#e(B

e$B$"$j$,$H$&$4$6$$$^$9!#<h$j9~$_$^$9!#e(Bfpathconfe$B$r;H$C$?%Q%C%Ae(B
e$B$,Ds6!$5$l$l$P$=$l$b9MN8$7$^$9!#e(B