diff options
author | Jan Dubois <jand@activestate.com> | 2010-10-25 15:50:27 -0700 |
---|---|---|
committer | Jan Dubois <jand@activestate.com> | 2010-10-25 15:59:49 -0700 |
commit | 60b22aca14742ead2388ca3c7bb4b542a2d9a4b1 (patch) | |
tree | 16381f46b798b66e9e1507ba4aff1c54d2488c7d /sv.c | |
parent | 0936ef8b60a303fb904c7a44b7e4f55e8191503c (diff) | |
download | perl-60b22aca14742ead2388ca3c7bb4b542a2d9a4b1.tar.gz |
Implement DIR* cloning on Windows
There doesn't seem to be a mechanism to clone FileFind handles on
Windows. Therefore this implementation just reads all remaining
entries into a cache buffer and closes the handle. All further
readdir() requests will be fulfilled from the cache buffer, in both
the original and the new interpreter.
This fixes bug 75154 on Windows (all tests in t/op/threads-dirh.t pass).
This commit also changes the return value of win32_telldir() to -1
for directory handles that have been read until the end. The previous
return value was (NULL - dirp->start), which technically is not
valid C code.
API change alert: Perl_dirp_dup() gets an additional CLONE_PARAMS
parameter in this change (like all the other Perl_*_dup() functions).
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 25 |
1 files changed, 17 insertions, 8 deletions
@@ -11009,10 +11009,11 @@ Perl_fp_dup(pTHX_ PerlIO *const fp, const char type, CLONE_PARAMS *const param) /* duplicate a directory handle */ DIR * -Perl_dirp_dup(pTHX_ DIR *const dp) +Perl_dirp_dup(pTHX_ DIR *const dp, CLONE_PARAMS *const param) { -#ifdef HAS_FCHDIR DIR *ret; + +#ifdef HAS_FCHDIR DIR *pwd; register const Direntry_t *dirent; char smallbuf[256]; @@ -11022,15 +11023,20 @@ Perl_dirp_dup(pTHX_ DIR *const dp) #endif PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_DIRP_DUP; -#ifdef HAS_FCHDIR if (!dp) return (DIR*)NULL; + /* look for it in the table first */ ret = (DIR*)ptr_table_fetch(PL_ptr_table, dp); if (ret) return ret; +#ifdef HAS_FCHDIR + + PERL_UNUSED_ARG(param); + /* create anew */ /* open the current directory (so we can switch back) */ @@ -11098,14 +11104,17 @@ Perl_dirp_dup(pTHX_ DIR *const dp) if (name && name != smallbuf) Safefree(name); +#endif + +#ifdef WIN32 + ret = win32_dirp_dup(dp, param); +#endif /* pop it in the pointer table */ - ptr_table_store(PL_ptr_table, dp, ret); + if (ret) + ptr_table_store(PL_ptr_table, dp, ret); return ret; -#else - return (DIR*)NULL; -#endif } /* duplicate a typeglob */ @@ -11661,7 +11670,7 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) IoFMT_GV(dstr) = gv_dup(IoFMT_GV(dstr), param); IoBOTTOM_GV(dstr) = gv_dup(IoBOTTOM_GV(dstr), param); if (IoDIRP(dstr)) { - IoDIRP(dstr) = dirp_dup(IoDIRP(dstr)); + IoDIRP(dstr) = dirp_dup(IoDIRP(dstr), param); } else { NOOP; /* IoDIRP(dstr) is already a copy of IoDIRP(sstr) */ |