diff --git a/libc/Makefile b/libc/Makefile
index 4b20911c..202b188b 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -210,6 +210,7 @@ string/strdup.o \
string/strerror_l.o \
string/strerror.o \
string/strerror_r.o \
+string/stresep.o \
string/strlcat.o \
string/strlcpy.o \
string/strlen.o \
diff --git a/libc/include/string.h b/libc/include/string.h
index e618e6f6..e55bc1f1 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -129,6 +129,7 @@ int ffsl(long int);
void* memrchr(const void*, int, size_t);
/* TODO: strcasecmp_l */
char* strchrnul(const char* str, int c);
+char* stresep(char**, const char*, int);
size_t strlcat(char* __restrict, const char* __restrict, size_t);
size_t strlcpy(char* __restrict, const char* __restrict, size_t);
/* TODO: strncasecmp_l */
diff --git a/libc/string/stresep.cpp b/libc/string/stresep.cpp
new file mode 100644
index 00000000..432f0ca3
--- /dev/null
+++ b/libc/string/stresep.cpp
@@ -0,0 +1,63 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2014.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ string/stresep.cpp
+ Extract a token from a string while handling escape characters.
+
+*******************************************************************************/
+
+#include
+
+extern "C" char* stresep(char** string_ptr, const char* delim, int escape)
+{
+ char* token = *string_ptr;
+ if ( !token )
+ return NULL;
+ size_t consumed_length = 0;
+ size_t token_length = 0;
+ bool escaped = false;
+ while ( true )
+ {
+ char c = token[consumed_length++];
+ bool true_nul = c == '\0';
+ if ( !escaped && escape && (unsigned char) c == (unsigned char) escape )
+ {
+ escaped = true;
+ continue;
+ }
+ if ( !escaped && c != '\0' )
+ {
+ for ( size_t i = 0; delim[i]; i++ )
+ {
+ if ( c != delim[i] )
+ {
+ c = '\0';
+ break;
+ }
+ }
+ }
+ token[token_length++] = c;
+ escaped = false;
+ if ( c == '\0' )
+ {
+ *string_ptr = true_nul ? (char*) NULL : token + consumed_length;
+ return token;
+ }
+ }
+}