summaryrefslogtreecommitdiff
path: root/reentr.c
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2020-03-11 12:24:33 -0600
committerKarl Williamson <khw@cpan.org>2020-03-18 14:29:46 -0600
commit5baa389e84c8348c7335cd8e58d1a2f6f917f7e4 (patch)
tree9c680609ae48e379e7f855f03d4b9613d664682c /reentr.c
parent5f47881659a0e7bfbe5db3cda32beec498c07696 (diff)
downloadperl-5baa389e84c8348c7335cd8e58d1a2f6f917f7e4.tar.gz
reentr.c: Handle getspnam()
This has never worked to increase the buffer size if necessary. Apparently the default has always been big enough. But this commit fixes it to retry if too small. I don't think there is a way to write tests for this. getspnam is called only as a small part of pp_gpwent, and is not part of the API, and is called only when run as root. I did test it on my box, with gdb, starting with a buffer size of 1, and single stepping and observing that it works as I expected.
Diffstat (limited to 'reentr.c')
-rw-r--r--reentr.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/reentr.c b/reentr.c
index ede96a9d18..10c2d88655 100644
--- a/reentr.c
+++ b/reentr.c
@@ -381,6 +381,16 @@ Perl_reentrant_retry(const char *f, ...)
#endif
if (key == 0) {
+
+#ifdef HAS_GETSPNAM_R
+
+ /* This is a #define as has no corresponding keyword */
+ if (strEQ(f, "getspnam")) {
+ key = KEY_getspnam;
+ }
+
+#endif
+
}
else if (key < 0) {
key = -key;
@@ -510,9 +520,9 @@ Perl_reentrant_retry(const char *f, ...)
# endif
# ifdef USE_PWENT_BUFFER
- case KEY_getpwnam:
- case KEY_getpwuid:
- case KEY_getpwent:
+ case KEY_getpwnam:
+ case KEY_getpwuid:
+ case KEY_getpwent:
{
# ifdef PERL_REENTRANT_MAXSIZE
@@ -551,6 +561,31 @@ Perl_reentrant_retry(const char *f, ...)
break;
# endif
+# ifdef USE_SPENT_BUFFER
+
+ case KEY_getspnam:
+ {
+ char * name;
+
+# ifdef PERL_REENTRANT_MAXSIZE
+ if (PL_reentrant_buffer->_spent_size <=
+ PERL_REENTRANT_MAXSIZE / 2)
+
+# endif
+ RenewDouble(PL_reentrant_buffer->_spent_buffer,
+ &PL_reentrant_buffer->_spent_size, char);
+ switch (key) {
+ case KEY_getspnam:
+ name = va_arg(ap, char *);
+ retptr = getspnam(name); break;
+ default:
+ SETERRNO(ERANGE, LIB_INVARG);
+ break;
+ }
+ }
+ break;
+
+# endif
# ifdef USE_PROTOENT_BUFFER
case KEY_getprotobyname: