summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pp.c18
-rw-r--r--reentr.c9
-rw-r--r--reentr.h4
-rw-r--r--reentr.pl19
4 files changed, 37 insertions, 13 deletions
diff --git a/pp.c b/pp.c
index 37277e4f11..524ed243fa 100644
--- a/pp.c
+++ b/pp.c
@@ -3418,6 +3418,24 @@ PP(pp_crypt)
sv_utf8_downgrade(tsv, FALSE);
tmps = SvPVX(tsv);
}
+# ifdef USE_ITHREADS
+# ifdef HAS_CRYPT_R
+ if (!PL_reentrant_buffer->_crypt_struct_buffer) {
+ /* This should be threadsafe because in ithreads there is only
+ * one thread per interpreter. If this would not be true,
+ * we would need a mutex to protect this malloc. */
+ PL_reentrant_buffer->_crypt_struct_buffer =
+ (struct crypt_data *)safemalloc(sizeof(struct crypt_data));
+#if defined(__GLIBC__) || defined(__EMX__)
+ if (PL_reentrant_buffer->_crypt_struct_buffer) {
+ PL_reentrant_buffer->_crypt_struct_buffer->initialized = 0;
+ /* work around glibc-2.2.5 bug */
+ PL_reentrant_buffer->_crypt_struct_buffer->current_saltbits = 0;
+ }
+ }
+#endif
+# endif /* HAS_CRYPT_R */
+# endif /* USE_ITHREADS */
# ifdef FCRYPT
sv_setpv(TARG, fcrypt(tmps, SvPV(right, n_a)));
# else
diff --git a/reentr.c b/reentr.c
index a2f1a19681..3b2a39a491 100644
--- a/reentr.c
+++ b/reentr.c
@@ -146,10 +146,8 @@ Perl_reentrant_init(pTHX) {
New(31338, PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
#endif /* HAS_ASCTIME_R */
#ifdef HAS_CRYPT_R
-#if defined(__GLIBC__) || defined(__EMX__)
- PL_reentrant_buffer->_crypt_struct.initialized = 0;
- /* work around glibc-2.2.5 bug */
- PL_reentrant_buffer->_crypt_struct.current_saltbits = 0;
+#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
+ PL_reentrant_buffer->_crypt_struct_buffer = 0;
#endif
#endif /* HAS_CRYPT_R */
#ifdef HAS_CTIME_R
@@ -230,6 +228,9 @@ Perl_reentrant_free(pTHX) {
Safefree(PL_reentrant_buffer->_asctime_buffer);
#endif /* HAS_ASCTIME_R */
#ifdef HAS_CRYPT_R
+#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
+ Safefree(PL_reentrant_buffer->_crypt_struct_buffer);
+#endif
#endif /* HAS_CRYPT_R */
#ifdef HAS_CTIME_R
Safefree(PL_reentrant_buffer->_ctime_buffer);
diff --git a/reentr.h b/reentr.h
index f5337c4393..f4f9f25cba 100644
--- a/reentr.h
+++ b/reentr.h
@@ -604,7 +604,7 @@ typedef struct {
#if CRYPT_R_PROTO == REENTRANT_PROTO_B_CCD
CRYPTD* _crypt_data;
#else
- struct crypt_data _crypt_struct;
+ struct crypt_data *_crypt_struct_buffer;
#endif
#endif /* HAS_CRYPT_R */
#ifdef HAS_CTIME_R
@@ -781,7 +781,7 @@ typedef struct {
#ifdef HAS_CRYPT_R
# undef crypt
# if !defined(crypt) && CRYPT_R_PROTO == REENTRANT_PROTO_B_CCS
-# define crypt(a, b) crypt_r(a, b, &PL_reentrant_buffer->_crypt_struct)
+# define crypt(a, b) crypt_r(a, b, PL_reentrant_buffer->_crypt_struct_buffer)
# endif
# if !defined(crypt) && CRYPT_R_PROTO == REENTRANT_PROTO_B_CCD
# define crypt(a, b) crypt_r(a, b, &PL_reentrant_buffer->_crypt_data)
diff --git a/reentr.pl b/reentr.pl
index d96cb3ab06..4429bc4cb7 100644
--- a/reentr.pl
+++ b/reentr.pl
@@ -453,14 +453,17 @@ EOF
#if CRYPT_R_PROTO == REENTRANT_PROTO_B_CCD
$seend{$func} _${func}_data;
#else
- $seent{$func} _${func}_struct;
+ $seent{$func} *_${func}_struct_buffer;
#endif
EOF
push @init, <<EOF;
-#if defined(__GLIBC__) || defined(__EMX__)
- PL_reentrant_buffer->_${func}_struct.initialized = 0;
- /* work around glibc-2.2.5 bug */
- PL_reentrant_buffer->_${func}_struct.current_saltbits = 0;
+#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
+ PL_reentrant_buffer->_${func}_struct_buffer = 0;
+#endif
+EOF
+ push @free, <<EOF;
+#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
+ Safefree(PL_reentrant_buffer->_${func}_struct_buffer);
#endif
EOF
pushssif $endif;
@@ -661,9 +664,11 @@ EOF
$_ eq 'D' ?
"&PL_reentrant_buffer->_${genfunc}_data" :
$_ eq 'S' ?
- ($func =~ /^readdir/ ?
+ ($func =~ /^readdir\d*$/ ?
"PL_reentrant_buffer->_${genfunc}_struct" :
- "&PL_reentrant_buffer->_${genfunc}_struct" ) :
+ $func =~ /^crypt$/ ?
+ "PL_reentrant_buffer->_${genfunc}_struct_buffer" :
+ "&PL_reentrant_buffer->_${genfunc}_struct") :
$_ eq 'T' && $func eq 'drand48' ?
"&PL_reentrant_buffer->_${genfunc}_double" :
$_ =~ /^[ilt]$/ && $func eq 'random' ?