implement strnlen for systems that need it
PATCH v2 1/1 implement strnlen for systems that need it
Prior the Mac OS 10.7, the function strnlen() was not available. This patch implements strnlen() on Mac OS X versions that are below 10.7.
---
v2 changes:
- Simplified the code to make it static inline'ed
- Changed the type of count to size_t
libfdt/libfdt_env.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
libfdt/libfdt_env.h +29 -0
@@ -109,4 +109,33 @@ static inline fdt64_t cpu_to_fdt64(uint64_t x)#undef CPU_TO_FDT16#undef EXTRACT_BYTE +#ifdef __APPLE__ +#include <AvailabilityMacros.h> + +#define MAC_OS_X_VERSION_10_7 1070 + +/* strnlen() is not available on Mac OS < 10.7 */ +# if (MAC_OS_X_VERSION_MAX_ALLOWED <MAC_OS_X_VERSION_10_7 ) + +/* +* strnlen: returns the length of a string or max_count - which ever is smallest +* Input 1 string: the string whose size is to be determined +* Input 2 max_count: the maximum value returned by this function +* Output: length of the string or max_count (the smallest of the two) +*/ +static inline size_t strnlen (const char *string,size_t max_count) +{ +size_t count; +for (count =0 ; count < max_count; count++) { +if (string[count] =='\0' ) { +break ; + } + } +return count; +} + +#endif /* (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7) */ + +#endif /* __APPLE__ */ +#endif /* _LIBFDT_ENV_H */
Signature · 1 line
2.13.5 (Apple Git-94)
libfdt/libfdt_env.h static inline fdt64_t cpu_to_fdt64(uint64_t x) · line 134
Quoted 9 lines · John Arbuckle
libfdt/libfdt_env.h +9
-0+static inline size_t strnlen (const char *string,size_t max_count) +{ +size_t count; +for (count =0 ; count < max_count; count++) { +if (string[count] =='\0' ) { +break ; + } + } +return count;
Not to nitpick, but
const char *p = memchr(string, 0, max_count); return p ? max_count : p - string;
r~
Quoted 13 lines · Richard Henderson
libfdt/libfdt_env.h static inline fdt64_t cpu_to_fdt64(uint64_t x) · line 134
Quoted 9 lines · John Arbuckle
libfdt/libfdt_env.h +9
-0+static inline size_t strnlen (const char *string,size_t max_count) +{ +size_t count; +for (count =0 ; count < max_count; count++) { +if (string[count] =='\0' ) { +break ; + } + } +return count;Not to nitpick, but
Quoted 2 lines
const char *p = memchr(string, 0, max_count); return p ? max_count : p - string;
Richard's right, that's definitely a better implementation.
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Quoted 13 lines · Richard Henderson
libfdt/libfdt_env.h static inline fdt64_t cpu_to_fdt64(uint64_t x) · line 134
Quoted 9 lines · John Arbuckle
libfdt/libfdt_env.h +9
-0+static inline size_t strnlen (const char *string,size_t max_count) +{ +size_t count; +for (count =0 ; count < max_count; count++) { +if (string[count] =='\0' ) { +break ; + } + } +return count;Not to nitpick, but
Quoted 2 lines
const char *p = memchr(string, 0, max_count); return p ? max_count : p - string;
Am I misreading that, or do you have the ?: arms the wrong way around there?
thanks
-- PMM
Quoted 18 lines · Peter Maydell
Quoted 13 lines · Richard Henderson
libfdt/libfdt_env.h static inline fdt64_t cpu_to_fdt64(uint64_t x) · line 134
Quoted 9 lines · John Arbuckle
libfdt/libfdt_env.h +9
-0+static inline size_t strnlen (const char *string,size_t max_count) +{ +size_t count; +for (count =0 ; count < max_count; count++) { +if (string[count] =='\0' ) { +break ; + } + } +return count;Not to nitpick, but
Quoted 8 lines
Quoted 2 lines
const char *p =
memchr(string, 0, max_count);
return p ?max_count: p - string;Am I misreading that, or do you have the ?: arms the wrong way around there?
thanks
-- PMM
Yes. It should read:
return p ? p - string : max_count;
Quoted 17 lines · David Gibson
Quoted 13 lines · Richard Henderson
libfdt/libfdt_env.h static inline fdt64_t cpu_to_fdt64(uint64_t x) · line 134
Quoted 9 lines · John Arbuckle
libfdt/libfdt_env.h +9
-0+static inline size_t strnlen (const char *string,size_t max_count) +{ +size_t count; +for (count =0 ; count < max_count; count++) { +if (string[count] =='\0' ) { +break ; + } + } +return count;Not to nitpick, but
Quoted 4 lines
Quoted 2 lines
const char *p =
memchr(string, 0, max_count);
return p ?max_count: p - string;Richard's right, that's definitely a better implementation.
His implementation is smaller, but this one is even smaller. Plus it uses the familiar strlen() function:
size_t strnlen(const char *string, size_t max_count)
{
return strlen(string) < max_count ? strlen(string) : max_count;
}Quoted 7 lines
... this one is even smaller. Plus it uses the familiar
strlen()function:
size_tstrnlen(const char *string, size_t max_count){ return strlen(string) < max_count ? strlen(string) : max_count; }
Please do not use that implementation.
The major goal of strnlen is to avoid looking beyond &string[max_count]. strlen(string) looks all the way to the end, which may be very much longer than max_count; and which may cause SIGSEGV by running into a memory page that does not exist before the terminating '\0' is found.
[Besides, some compilers do not recognize that "strlen(string)"
need not be evaluated twice.]
Quoted 20 lines · Programmingkid
Quoted 20 lines · David Gibson
Quoted 16 lines · Richard Henderson
Review
Quoted 10 lines · John Arbuckle
(quoted diff) +9
-0+static inline size_t strnlen(const char *string, size_t max_count) +{ + size_t count; + for (count = 0; count < max_count; count++) { + if (string[count] == '\0') { + break; + } + } + return count;Not to nitpick, but
const char *p =
memchr(string, 0, max_count);
return p ?max_count: p - string;
Quoted 7 lines
Quoted 1 line
Richard's right, that's definitely a better implementation.
His implementation is smaller, but this one is even smaller. Plus it uses the familiar
strlen()function:
size_tstrnlen(const char *string, size_t max_count)
{
return strlen(string) <max_count? strlen(string) :max_count; }
That is not a proper implementation of strnlen(), which is not supposed to access any source-string bytes beyond max_count.
-- Ian
Quoted 32 lines · Ian Lepore
Quoted 20 lines · Programmingkid
Quoted 20 lines · David Gibson
Quoted 16 lines · Richard Henderson
Review
Quoted 10 lines · John Arbuckle
(quoted diff) +9
-0+static inline size_t strnlen(const char *string, size_t max_count) +{ + size_t count; + for (count = 0; count < max_count; count++) { + if (string[count] == '\0') { + break; + } + } + return count;Not to nitpick, but
const char *p =
memchr(string, 0, max_count);
return p ?max_count: p - string;Quoted 7 lines
Quoted 1 line
Richard's right, that's definitely a better implementation.
His implementation is smaller, but this one is even smaller. Plus it uses the familiar
strlen()function:
size_tstrnlen(const char *string, size_t max_count){ return strlen(string) < max_count ? strlen(string) : max_count; }
Quoted 4 lines
That is not a proper implementation of
strnlen(), which is not supposed to access any source-string bytes beyondmax_count.-- Ian
http://pubs.opengroup.org/onlinepubs/9699919799/functions/strlen.html
This specification document should help anyone who wants more info.
The first implementation using the loop would never access anything beyond max_count. My second implementation does go beyond max_count. The implementation using memchr() will probably live up the requirement so I guess it wins.
Thank you Ian for this information.
Quoted 17 lines · David Gibson
Quoted 13 lines · Richard Henderson
libfdt/libfdt_env.h static inline fdt64_t cpu_to_fdt64(uint64_t x) · line 134
Quoted 9 lines · John Arbuckle
libfdt/libfdt_env.h +9
-0+static inline size_t strnlen (const char *string,size_t max_count) +{ +size_t count; +for (count =0 ; count < max_count; count++) { +if (string[count] =='\0' ) { +break ; + } + } +return count;Not to nitpick, but
Quoted 4 lines
Quoted 2 lines
const char *p =
memchr(string, 0, max_count);
return p ?max_count: p - string;Richard's right, that's definitely a better implementation.
I was just wondering, what if we rewrote the code to use strlen() instead of strnlen(). Would that be an acceptable solution?
Quoted 17 lines · Programmingkid
Quoted 17 lines · David Gibson
Quoted 13 lines · Richard Henderson
Review
Quoted 9 lines · John Arbuckle
(quoted diff) +9
-0+static inline size_t strnlen(const char *string, size_t max_count) +{ + size_t count; + for (count = 0; count < max_count; count++) { + if (string[count] == '\0') { + break; + } + } + return count;Not to nitpick, but
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
const char *p =
memchr(string, 0, max_count);
return p ?max_count: p - string;Richard's right, that's definitely a better implementation.
I was just wondering, what if we rewrote the code to use
strlen()instead ofstrnlen(). Would that be an acceptable solution?
Only if you can do so safely - i.e. without accessing memory beyond what we're supposed to. I don't think you'll be able to do that without effectively re-implementing strnlen(), there's a reason I used it in the first place, after all.
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson