1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

(scm_readdir): Use readdir_r when available, for thread safety.

This commit is contained in:
Kevin Ryde 2004-04-18 00:39:16 +00:00
parent 9fa6c11903
commit 9be808d8c9

View file

@ -803,6 +803,11 @@ SCM_DEFINE (scm_opendir, "opendir", 1, 0, 0,
#undef FUNC_NAME #undef FUNC_NAME
/* FIXME: The glibc manual has a portability note that readdir_r may not
null-terminate its return string. The circumstances outlined for this
are not clear, nor is it clear what should be done about it. Lets worry
about this if/when someone can figure it out. */
SCM_DEFINE (scm_readdir, "readdir", 1, 0, 0, SCM_DEFINE (scm_readdir, "readdir", 1, 0, 0,
(SCM port), (SCM port),
"Return (as a string) the next directory entry from the directory stream\n" "Return (as a string) the next directory entry from the directory stream\n"
@ -817,12 +822,28 @@ SCM_DEFINE (scm_readdir, "readdir", 1, 0, 0,
SCM_MISC_ERROR ("Directory ~S is not open.", scm_list_1 (port)); SCM_MISC_ERROR ("Directory ~S is not open.", scm_list_1 (port));
errno = 0; errno = 0;
SCM_SYSCALL (rdent = readdir ((DIR *) SCM_CELL_WORD_1 (port))); {
if (errno != 0) #if HAVE_READDIR_R
SCM_SYSERROR; /* On Solaris 2.7, struct dirent only contains "char d_name[1]" and one is
expected to provide a buffer of "sizeof(struct dirent) + NAME_MAX"
bytes. The glibc 2.3.2 manual notes this sort of thing too, and
advises "offsetof(struct dirent,d_name) + NAME_MAX + 1". Either should
suffice, we give both to be certain. */
union {
struct dirent ent;
char pad1 [sizeof(struct dirent) + NAME_MAX];
char pad2 [offsetof (struct dirent, d_name) + NAME_MAX + 1];
} u;
SCM_SYSCALL (readdir_r ((DIR *) SCM_CELL_WORD_1 (port), &u.ent, &rdent));
#else
SCM_SYSCALL (rdent = readdir ((DIR *) SCM_CELL_WORD_1 (port)));
#endif
if (errno != 0)
SCM_SYSERROR;
return (rdent ? scm_mem2string (rdent->d_name, NAMLEN (rdent)) return (rdent ? scm_mem2string (rdent->d_name, NAMLEN (rdent))
: SCM_EOF_VAL); : SCM_EOF_VAL);
}
} }
#undef FUNC_NAME #undef FUNC_NAME