[libc] Add strchrnul()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
diff --git a/src/core/string.c b/src/core/string.c
index 2af19b7..68f0110 100644
--- a/src/core/string.c
+++ b/src/core/string.c
@@ -263,6 +263,22 @@
 }
 
 /**
+ * Find character within a string, or NUL terminator
+ *
+ * @v src		String
+ * @v character		Character to find
+ * @ret found		Found character, or terminating NUL if not found
+ */
+char * strchrnul ( const char *src, int character ) {
+	const uint8_t *src_bytes = ( ( const uint8_t * ) src );
+
+	for ( ; ; src_bytes++ ) {
+		if ( ( *src_bytes == character ) || ( ! *src_bytes ) )
+			return ( ( char * ) src_bytes );
+	}
+}
+
+/**
  * Find character within a string
  *
  * @v src		String
@@ -270,14 +286,12 @@
  * @ret found		Found character, or NULL if not found
  */
 char * strchr ( const char *src, int character ) {
-	const uint8_t *src_bytes = ( ( const uint8_t * ) src );
+	char *found;
 
-	for ( ; ; src_bytes++ ) {
-		if ( *src_bytes == character )
-			return ( ( char * ) src_bytes );
-		if ( ! *src_bytes )
-			return NULL;
-	}
+	found = strchrnul ( src, character );
+	if ( character != *( ( uint8_t * ) found ) )
+		return NULL;
+	return found;
 }
 
 /**
diff --git a/src/include/string.h b/src/include/string.h
index 3affe8e..6b43d8f 100644
--- a/src/include/string.h
+++ b/src/include/string.h
@@ -40,6 +40,7 @@
 			    size_t max ) __nonnull;
 extern size_t __pure strlen ( const char *src ) __nonnull;
 extern size_t __pure strnlen ( const char *src, size_t max ) __nonnull;
+extern char * __pure strchrnul ( const char *src, int character ) __nonnull;
 extern char * __pure strchr ( const char *src, int character ) __nonnull;
 extern char * __pure strrchr ( const char *src, int character ) __nonnull;
 extern char * __pure strstr ( const char *haystack,
diff --git a/src/tests/string_test.c b/src/tests/string_test.c
index 6662848..6b65992 100644
--- a/src/tests/string_test.c
+++ b/src/tests/string_test.c
@@ -70,6 +70,7 @@
 	ok ( *(strchr ( "Testing", 'e' )) == 'e' );
 	ok ( *(strchr ( "Testing", 'g' )) == 'g' );
 	ok ( strchr ( "Testing", 'x' ) == NULL );
+	ok ( *(strchr ( "Testing", '\0' )) == '\0' );
 
 	/* Test strrchr() */
 	ok ( strrchr ( "", 'a' ) == NULL );
@@ -77,6 +78,13 @@
 	ok ( *(strrchr ( "Haystack", 'k' )) == 'k' );
 	ok ( strrchr ( "Haystack", 'x' ) == NULL );
 
+	/* Test strchrnul() */
+	ok ( *(strchrnul ( "", 'x' )) == '\0' );
+	ok ( *(strchrnul ( "Nonstandard", 's' )) == 's' );
+	ok ( *(strchrnul ( "Nonstandard", 't' )) == 't' );
+	ok ( *(strchrnul ( "Nonstandard", 'x' )) == '\0' );
+	ok ( *(strchrnul ( "Nonstandard", '\0' )) == '\0' );
+
 	/* Test memchr() */
 	ok ( memchr ( "", '\0', 0 ) == NULL );
 	ok ( *((uint8_t *)memchr ( "post\0null", 'l', 9 )) == 'l' );