Skip to contentSkip to conversation

fdt_ro.c: implement strnlen

PATCH In review John Arbuckle 3 participants 6 messages Oct 18, 2017 – Oct 19, 2017

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fdt_ro.c: implement strnlen

Implement the strnlen() function if it isn't implemented.

---
 libfdt/fdt_ro.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
libfdt/fdt_ro.c +24 -0
index 3d00d2e..a7986fb 100644
@@ -55,6 +55,30 @@
 
 #include "libfdt_internal.h"
 
+/* if the current environment does not define strnlen */
+#ifndef strnlen
+
+/* This eliminates the missing prototype warning */
+int strnlen(const char *string, int max_count);
+
+/*
+ * strnlen: return the length of a string or max_count
+ * which ever is shortest
+ */
+
+int strnlen(const char *string, int max_count)
+{
+    int count;
+    for(count = 0; count < max_count; count++) {
+        if (string[count] == '\0') {
+            break;
+        }
+    }
+    return count;
+}
+
+#endif /* strnlen */
+
 static int _fdt_nodename_eq(const void *fdt, int offset,
 			    const char *s, int len)
 {
Signature · 1 line
2.13.5 (Apple Git-94)
#1 lore raw
Quoted 3 lines · John Arbuckle

Implement the strnlen() function if it isn't implemented.

Nice idea, but this won't work.

Quoted 9 lines
---
 libfdt/fdt_ro.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
libfdt/fdt_ro.c +0 -0
index 3d00d2e..a7986fb 100644

libfdt/fdt_ro.c line 59

Quoted 5 lines
libfdt/fdt_ro.c +2 -0
@@ -55,6 +55,30 @@
 
 #include "libfdt_internal.h"
 
+/* if the current environment does not define strnlen */
+#ifndef strnlen

This will only trigger if strnlen is defined as a macro. The C library (or other environment) *might* do that, but there's no guarantee, whether or not it defines strnlen as a function. With extra complications if the compiler has a strnlen builtin like gcc.

libfdt/fdt_ro.c line 69

Quoted 10 lines
libfdt/fdt_ro.c +10 -0
+
+/* This eliminates the missing prototype warning */
+int strnlen(const char *string, int max_count);
+
+/*
+ * strnlen: return the length of a string or max_count
+ * which ever is shortest
+ */
+
+int strnlen(const char *string, int max_count)

Also strnlen is supposed to take and return size_t, not int.

Quoted 5 lines
libfdt/fdt_ro.c +5 -0
+{
+    int count;
+    for(count = 0; count < max_count; count++) {
+        if (string[count] == '\0') {
+            break;

libfdt/fdt_ro.c line 84

Quoted 10 lines
libfdt/fdt_ro.c +7 -0
+        }
+    }
+    return count;
+}
+
+#endif /* strnlen */
+
 static int _fdt_nodename_eq(const void *fdt, int offset,
 			    const char *s, int len)
 {

In any case, this sort of compatibility munging is the job of libfdt_env.h. It's purpose is to provide all the external things that libfdt needs - there's not that many of them and strnlen() is one. The included libfdt_env.h is intended for POSIXy userspace environments, which should already include strnlen() in string.h.

If your environment does not provide strnlen(), you probably need your own version of libfdt_env.h, which will need to define it.

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
#2 lore raw
Quoted 22 lines · David Gibson
Quoted 3 lines · John Arbuckle

Implement the strnlen() function if it isn't implemented.

Nice idea, but this won't work.

Quoted 12 lines

---
libfdt/fdt_ro.c | 24 ++++++++++++++++++++++++

1 file changed, 24 insertions(+)
libfdt/fdt_ro.c +0 -0
index 3d00d2e..a7986fb 100644
@@ -55,6 +55,30 @@
 
 #include "libfdt_internal.h"
 
Quoted 7 lines

libfdt/fdt_ro.c line 59

Quoted 2 lines
libfdt/fdt_ro.c +2 -0
+/* if the current environment does not define strnlen */
+#ifndef strnlen

This will only trigger if strnlen is defined as a macro. The C library (or other environment) *might* do that, but there's no guarantee, whether or not it defines strnlen as a function. With extra complications if the compiler has a strnlen builtin like gcc.

:(

Quoted 4 lines
Quoted 4 lines
libfdt/fdt_ro.c +4 -0
+
+/* This eliminates the missing prototype warning */
+int strnlen(const char *string, int max_count);
+
Quoted 8 lines

libfdt/fdt_ro.c line 69

Quoted 6 lines
libfdt/fdt_ro.c +6 -0
+/*
+ * strnlen: return the length of a string or max_count
+ * which ever is shortest
+ */
+
+int strnlen(const char *string, int max_count)

Also strnlen is supposed to take and return size_t, not int.

Will change this.

Quoted 14 lines
Quoted 14 lines
libfdt/fdt_ro.c +12 -0
+{
+    int count;
+    for(count = 0; count < max_count; count++) {
+        if (string[count] == '\0') {
+            break;
+        }
+    }
+    return count;
+}
+
+#endif /* strnlen */
+
 static int _fdt_nodename_eq(const void *fdt, int offset,
Quoted 8 lines

libfdt/fdt_ro.c line 84

Quoted 2 lines
libfdt/fdt_ro.c +0 -0
 			    const char *s, int len)
 {

In any case, this sort of compatibility munging is the job of libfdt_env.h. It's purpose is to provide all the external things that libfdt needs - there's not that many of them and strnlen() is one. The included libfdt_env.h is intended for POSIXy userspace environments, which should already include strnlen() in string.h.

QEMU supports Mac OS 10.5 and higher. The strnlen() function might have been added to Mac OS X in version 10.7. libfdt prevents QEMU from compiling on Mac OS X because of the missing strnlen() function. This issue needs to be resolved. If libfdt_env.h is where you want a fix located, would something like this be good:

#ifdef __APPLE__

#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
	size_t strnlen(const char *string, int max_count)
	{
		... // pretend this is implemented
	}

#endif

#endif

#3 lore raw
Quoted 70 lines · Programmingkid
Quoted 22 lines · David Gibson
Quoted 3 lines · John Arbuckle

Implement the strnlen() function if it isn't implemented.

Nice idea, but this won't work.

Quoted 12 lines

---
libfdt/fdt_ro.c | 24 ++++++++++++++++++++++++

1 file changed, 24 insertions(+)
libfdt/fdt_ro.c +0 -0
index 3d00d2e..a7986fb 100644
@@ -55,6 +55,30 @@
 
 #include "libfdt_internal.h"
 
Quoted 7 lines

libfdt/fdt_ro.c line 59

Quoted 2 lines
libfdt/fdt_ro.c +2 -0
+/* if the current environment does not define strnlen */
+#ifndef strnlen

This will only trigger if strnlen is defined as a macro. The C library (or other environment) *might* do that, but there's no guarantee, whether or not it defines strnlen as a function. With extra complications if the compiler has a strnlen builtin like gcc.

:(

Quoted 4 lines
Quoted 4 lines
libfdt/fdt_ro.c +4 -0
+
+/* This eliminates the missing prototype warning */
+int strnlen(const char *string, int max_count);
+
Quoted 8 lines

libfdt/fdt_ro.c line 69

Quoted 6 lines
libfdt/fdt_ro.c +6 -0
+/*
+ * strnlen: return the length of a string or max_count
+ * which ever is shortest
+ */
+
+int strnlen(const char *string, int max_count)

Also strnlen is supposed to take and return size_t, not int.

Will change this.

Quoted 14 lines
Quoted 14 lines
libfdt/fdt_ro.c +12 -0
+{
+    int count;
+    for(count = 0; count < max_count; count++) {
+        if (string[count] == '\0') {
+            break;
+        }
+    }
+    return count;
+}
+
+#endif /* strnlen */
+
 static int _fdt_nodename_eq(const void *fdt, int offset,
Quoted 8 lines

libfdt/fdt_ro.c line 84

Quoted 2 lines
libfdt/fdt_ro.c +0 -0
 			    const char *s, int len)
 {

In any case, this sort of compatibility munging is the job of libfdt_env.h. It's purpose is to provide all the external things that libfdt needs - there's not that many of them and strnlen() is one. The included libfdt_env.h is intended for POSIXy userspace environments, which should already include strnlen() in string.h.

Quoted 2 lines

QEMU supports Mac OS 10.5 and higher. The strnlen() function might have been added to Mac OS X in version 10.7.

Wow. No strnlen() in MacOS until that recently, that's pretty shit.

Quoted 8 lines

libfdt prevents QEMU
from compiling on Mac OS X because of the missing strnlen() function. This issue needs to be resolved. If libfdt_env.h is where you want a fix located, would something like this be good:

#ifdef __APPLE__

Quoted 8 lines
#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
	size_t strnlen(const char *string, int max_count)
	{
		... // pretend this is implemented
	}

#endif

#endif

I'm not sure I'd go as far as to call it "good" - it's kinda ugly - but it would be an acceptable solution (as long as max_count is changed to size_t as well, of course).

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
#4 lore raw
Quoted 5 lines · David Gibson
Quoted 2 lines · Programmingkid

QEMU supports Mac OS 10.5 and higher. The strnlen() function might have been added to Mac OS X in version 10.7.

Wow. No strnlen() in MacOS until that recently, that's pretty shit.

It's pretty poor, but the 10.7 release date was 2011, five years ago now, and it's been out of security-fix support for 2 or 3 years.

thanks
-- PMM

#5 lore raw
In reply to David Gibson
Quoted 94 lines · David Gibson
Quoted 70 lines · Programmingkid
Quoted 22 lines · David Gibson
Quoted 3 lines · John Arbuckle

Implement the strnlen() function if it isn't implemented.

Nice idea, but this won't work.

Quoted 12 lines

---
libfdt/fdt_ro.c | 24 ++++++++++++++++++++++++

1 file changed, 24 insertions(+)
libfdt/fdt_ro.c +0 -0
index 3d00d2e..a7986fb 100644
@@ -55,6 +55,30 @@
 
 #include "libfdt_internal.h"
 
Quoted 7 lines

libfdt/fdt_ro.c line 59

Quoted 2 lines
libfdt/fdt_ro.c +2 -0
+/* if the current environment does not define strnlen */
+#ifndef strnlen

This will only trigger if strnlen is defined as a macro. The C library (or other environment) *might* do that, but there's no guarantee, whether or not it defines strnlen as a function. With extra complications if the compiler has a strnlen builtin like gcc.

:(

Quoted 4 lines
Quoted 4 lines
libfdt/fdt_ro.c +4 -0
+
+/* This eliminates the missing prototype warning */
+int strnlen(const char *string, int max_count);
+
Quoted 8 lines

libfdt/fdt_ro.c line 69

Quoted 6 lines
libfdt/fdt_ro.c +6 -0
+/*
+ * strnlen: return the length of a string or max_count
+ * which ever is shortest
+ */
+
+int strnlen(const char *string, int max_count)

Also strnlen is supposed to take and return size_t, not int.

Will change this.

Quoted 14 lines
Quoted 14 lines
libfdt/fdt_ro.c +12 -0
+{
+    int count;
+    for(count = 0; count < max_count; count++) {
+        if (string[count] == '\0') {
+            break;
+        }
+    }
+    return count;
+}
+
+#endif /* strnlen */
+
 static int _fdt_nodename_eq(const void *fdt, int offset,
Quoted 8 lines

libfdt/fdt_ro.c line 84

Quoted 2 lines
libfdt/fdt_ro.c +0 -0
 			    const char *s, int len)
 {

In any case, this sort of compatibility munging is the job of libfdt_env.h. It's purpose is to provide all the external things that libfdt needs - there's not that many of them and strnlen() is one. The included libfdt_env.h is intended for POSIXy userspace environments, which should already include strnlen() in string.h.

Quoted 2 lines

QEMU supports Mac OS 10.5 and higher. The strnlen() function might have been added to Mac OS X in version 10.7.

Wow. No strnlen() in MacOS until that recently, that's pretty shit.

Quoted 15 lines

libfdt prevents QEMU
from compiling on Mac OS X because of the missing strnlen() function. This issue needs to be resolved. If libfdt_env.h is where you want a fix located, would something like this be good:

#ifdef __APPLE__

#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
	size_t strnlen(const char *string, int max_count)
	{
		... // pretend this is implemented
	}

#endif

Quoted 5 lines
Quoted 1 line

#endif

I'm not sure I'd go as far as to call it "good" - it's kinda ugly - but it would be an acceptable solution (as long as max_count is changed to size_t as well, of course).

Yes, you are right. It is an eye sore. Libfdt is part of the Device Tree Compiler toolchain. This toolchain is something that can exist independently of QEMU. Someone could download the Device Tree Compiler toolchain and try to build it on Mac OS 10.5. This project doesn't have a configuration script but it does have a makefile. What I am thinking is add a target to the makefile that adds the strnlen() function to the toolchain if the user is building on anything less than Mac OS 10.7. The Makefile.libfdt file in the libfdt folder looks like a good place to put this code. This might be better looking. Thoughts?