From 8cd4c1f5a04dbace6a7622f5a34d5aecbf6ae8f8 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Fri, 6 Feb 2015 16:18:36 +0100 Subject: [PATCH] Add mkdtemp(3). --- libc/Makefile | 1 + libc/include/stdlib.h | 2 +- libc/stdlib/mkdtemp.cpp | 63 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 libc/stdlib/mkdtemp.cpp diff --git a/libc/Makefile b/libc/Makefile index 0e6093d7..5862f749 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -450,6 +450,7 @@ stdlib/clearenv.o \ stdlib/_Exit.o \ stdlib/exit.o \ stdlib/getenv.o \ +stdlib/mkdtemp.o \ stdlib/mkostemp.o \ stdlib/mkostemps.o \ stdlib/mkstemp.o \ diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 24da6f0d..183ce1c8 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -105,6 +105,7 @@ void* malloc(size_t); int mblen(const char*, size_t); size_t mbstowcs(wchar_t* __restrict, const char* __restrict, size_t); int mbtowc(wchar_t *__restrict, const char* __restrict, size_t); +char* mkdtemp(char*); int mkostemp(char*, int); int mkostemps(char*, int, int); int mkstemp(char*); @@ -161,7 +162,6 @@ long jrand48(unsigned short [3]); char* l64a(long); void lcong48(unsigned short [7]); long lrand48(void); -char* mkdtemp(char*); long mrand48(void); long nrand48(unsigned short[3]); int posix_memalign(void**, size_t, size_t); diff --git a/libc/stdlib/mkdtemp.cpp b/libc/stdlib/mkdtemp.cpp new file mode 100644 index 00000000..b16dec7d --- /dev/null +++ b/libc/stdlib/mkdtemp.cpp @@ -0,0 +1,63 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015. + + 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 . + + stdlib/mkdtemp.cpp + Make a unique temporary directory path and create it. + +*******************************************************************************/ + +#include +#include +#include +#include + +const uint32_t NUM_CHARACTERS = 10 + 26 + 26; + +static inline char random_character() +{ + uint32_t index = arc4random_uniform(NUM_CHARACTERS); + if ( index < 10 ) + return '0' + index; + if ( index < 10 + 26 ) + return 'a' + index - 10; + if ( index < 10 + 26 + 26 ) + return 'A' + index - (10 + 26); + __builtin_unreachable(); +} + +extern "C" char* mkdtemp(char* templ) +{ + size_t templ_length = strlen(templ); + if ( templ_length < 6 ) + return errno = EINVAL, (char*) NULL; + size_t xpos = templ_length - 6; + for ( size_t i = 0; i < 6; i++ ) + if ( templ[xpos + i] != 'X' ) + return errno = EINVAL, (char*) NULL; + + do + { + for ( size_t i = 0; i < 6; i++ ) + templ[xpos + i] = random_character(); + if ( mkdir(templ, 0700) == 0 ) + return templ; + } while ( errno == EEXIST ); + + return NULL; +}