summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDagfinn Ilmari Mannsåker <ilmari@ilmari.org>2017-10-21 20:05:17 +0100
committerDagfinn Ilmari Mannsåker <ilmari@ilmari.org>2017-10-21 20:05:17 +0100
commitaefb3fa072c057c13029faf2c7044bca8e0cc344 (patch)
tree9da4f463295151cce28cc409e69eebf2c73dcf5f
parentb961752cf64eb09f62d550c34bc311c4447339c7 (diff)
downloadperl-aefb3fa072c057c13029faf2c7044bca8e0cc344.tar.gz
Provide fallback strnlen implementation
-rw-r--r--embed.fnc4
-rw-r--r--metaconfig.h1
-rw-r--r--perl.h6
-rw-r--r--proto.h5
-rw-r--r--util.c30
5 files changed, 45 insertions, 1 deletions
diff --git a/embed.fnc b/embed.fnc
index 71b308733d..16b678c671 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -3038,6 +3038,10 @@ Apnod |Size_t |my_strlcat |NULLOK char *dst|NULLOK const char *src|Size_t size
Apnod |Size_t |my_strlcpy |NULLOK char *dst|NULLOK const char *src|Size_t size
#endif
+#ifndef HAS_STRNLEN
+Apnod |Size_t |my_strnlen |NN const char *str|Size_t maxlen
+#endif
+
#ifndef HAS_MKSTEMP
pno |int |my_mkstemp |NN char *templte
#endif
diff --git a/metaconfig.h b/metaconfig.h
index 2bc226abe5..eea007328c 100644
--- a/metaconfig.h
+++ b/metaconfig.h
@@ -22,7 +22,6 @@
* HAS_MBRTOWC
* HAS_MEMRCHR
* HAS_NANOSLEEP
- * HAS_STRNLEN
* HAS_STRTOLD_L
* I_WCHAR
*/
diff --git a/perl.h b/perl.h
index 2063175974..f9b1ec32e5 100644
--- a/perl.h
+++ b/perl.h
@@ -1479,6 +1479,12 @@ EXTERN_C char *crypt(const char *, const char *);
# define my_strlcpy Perl_my_strlcpy
#endif
+#ifdef HAS_STRNLEN
+# define my_strnlen strnlen
+#else
+# define my_strnlen Perl_my_strnlen
+#endif
+
/*
The IV type is supposed to be long enough to hold any integral
value or a pointer.
diff --git a/proto.h b/proto.h
index 70c1a63fec..4459d1076d 100644
--- a/proto.h
+++ b/proto.h
@@ -3858,6 +3858,11 @@ PERL_CALLCONV Size_t Perl_my_strlcat(char *dst, const char *src, Size_t size);
#if !defined(HAS_STRLCPY)
PERL_CALLCONV Size_t Perl_my_strlcpy(char *dst, const char *src, Size_t size);
#endif
+#if !defined(HAS_STRNLEN)
+PERL_CALLCONV Size_t Perl_my_strnlen(const char *str, Size_t maxlen);
+#define PERL_ARGS_ASSERT_MY_STRNLEN \
+ assert(str)
+#endif
#if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE) && defined(F_FREESP)
PERL_CALLCONV I32 Perl_my_chsize(pTHX_ int fd, Off_t length)
__attribute__warn_unused_result__;
diff --git a/util.c b/util.c
index 087c918faa..244d9368a8 100644
--- a/util.c
+++ b/util.c
@@ -5480,6 +5480,36 @@ Perl_my_strlcpy(char *dst, const char *src, Size_t size)
}
#endif
+/*
+=for apidoc my_strnlen
+
+The C library C<strnlen> if available, or a Perl implementation of it.
+
+C<my_strnlen()> computes the length of the string, up to C<maxlen>
+characters. It will will never attempt to address more than C<maxlen>
+characters, making it suitable for use with strings that are not
+guaranteed to be NUL-terminated.
+
+=cut
+
+Description stolen from http://man.openbsd.org/strnlen.3,
+implementation stolen from PostgreSQL.
+*/
+#ifndef HAS_STRNLEN
+Size_t
+Perl_my_strnlen(const char *str, Size_t maxlen)
+{
+ const char *p = str;
+
+ PERL_ARGS_ASSERT_MY_STRNLEN;
+
+ while(maxlen-- && *p)
+ p++;
+
+ return p - str;
+}
+#endif
+
#if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_MSC_VER < 1400) && (WINVER < 0x0500)
/* VC7 or 7.1, building with pre-VC7 runtime libraries. */
long _ftol( double ); /* Defined by VC6 C libs. */