#include #include #include #include #include #include #include #include #include #include #include #include #include char* escape_directory(char* unescaped_directory) { // The maximum possible length of the path after adding escape // characters is double the length of the unescaped path, when all characters // need to be escaped. Then add one for the null. size_t unescaped_length = strlen(unescaped_directory); char* escaped_directory = malloc(2*unescaped_length + 1); // Now, we start to do the escaping. Start with the first character. size_t escaped_position = 0; char* unescaped_character = unescaped_directory; do { switch (*unescaped_character) { case ':': case '\\': case ',': // If the character needs to be escaped, then add a backslash escaped_directory[escaped_position++] = '\\'; default: // Then, add the character itself escaped_directory[escaped_position++] = *unescaped_character; } // The original path should be null-terminated, so use this to decide when // to finish. } while ('\0' != *(unescaped_character++)); // To be neat and tidy, realloc the escaped path to use only the needed space escaped_directory = realloc(escaped_directory, escaped_position); return escaped_directory; } void append_string(char** lhs, char* rhs) { // Work out what the length of the combined string is, and reallocate to match size_t final_length = strlen(*lhs) + strlen(rhs) + 1; *lhs = realloc(*lhs, final_length); // Finally, concatenate the rhs on the end strncat(*lhs, rhs, final_length); } char* allocate_stack(size_t size) { // Allocate memory that is read/write, page-aligned, and various other // things that you can find in the mmap(2) man page. return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); }