From f0e3e2cfef611574d5a35bb2d9adfb9605e4d6f7 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Fri, 6 Feb 2015 16:03:24 +0100 Subject: [PATCH] Add mkostemps(3) family. --- libc/Makefile | 3 ++ libc/include/stdlib.h | 5 ++- libc/stdlib/mkostemp.cpp | 30 ++++++++++++++++++ libc/stdlib/mkostemps.cpp | 66 +++++++++++++++++++++++++++++++++++++++ libc/stdlib/mkstemp.cpp | 39 ++--------------------- libc/stdlib/mkstemps.cpp | 30 ++++++++++++++++++ 6 files changed, 136 insertions(+), 37 deletions(-) create mode 100644 libc/stdlib/mkostemp.cpp create mode 100644 libc/stdlib/mkostemps.cpp create mode 100644 libc/stdlib/mkstemps.cpp diff --git a/libc/Makefile b/libc/Makefile index 7b27a8c9..0e6093d7 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -450,7 +450,10 @@ stdlib/clearenv.o \ stdlib/_Exit.o \ stdlib/exit.o \ stdlib/getenv.o \ +stdlib/mkostemp.o \ +stdlib/mkostemps.o \ stdlib/mkstemp.o \ +stdlib/mkstemps.o \ stdlib/mktemp.o \ stdlib/on_exit.o \ stdlib/rand.o \ diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 253c8e5c..24da6f0d 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015. This file is part of the Sortix C Library. @@ -105,7 +105,10 @@ 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); +int mkostemp(char*, int); +int mkostemps(char*, int, int); int mkstemp(char*); +int mkstemps(char*, int); #if !defined(__is_sortix_libc) /* not a warning inside libc */ __attribute__((__warning__("mktemp() is racy, use mkstemp()"))) #endif diff --git a/libc/stdlib/mkostemp.cpp b/libc/stdlib/mkostemp.cpp new file mode 100644 index 00000000..c0bd77fe --- /dev/null +++ b/libc/stdlib/mkostemp.cpp @@ -0,0 +1,30 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 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/mkostemp.cpp + Make a unique temporary file path and open it. + +*******************************************************************************/ + +#include + +extern "C" int mkostemp(char* templ, int flags) +{ + return mkostemps(templ, 0, flags); +} diff --git a/libc/stdlib/mkostemps.cpp b/libc/stdlib/mkostemps.cpp new file mode 100644 index 00000000..66751638 --- /dev/null +++ b/libc/stdlib/mkostemps.cpp @@ -0,0 +1,66 @@ +/******************************************************************************* + + 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/mkostemps.cpp + Make a unique temporary file path and open 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" int mkostemps(char* templ, int suffixlen, int flags) +{ + size_t templ_length = strlen(templ); + if ( templ_length < 6 || + suffixlen < 0 || + templ_length - 6 < (size_t) suffixlen ) + return errno = EINVAL, -1; + size_t xpos = templ_length - (6 + suffixlen); + for ( size_t i = 0; i < 6; i++ ) + if ( templ[xpos + i] != 'X' ) + return errno = EINVAL, -1; + + flags &= ~O_ACCMODE; + int fd; + do + { + for ( size_t i = 0; i < 6; i++ ) + templ[xpos + i] = random_character(); + } while ( (fd = open(templ, flags | O_RDWR | O_EXCL | O_CREAT, 0600)) < 0 && + (errno == EEXIST) ); + + return fd; +} diff --git a/libc/stdlib/mkstemp.cpp b/libc/stdlib/mkstemp.cpp index 9af4fe15..9c491620 100644 --- a/libc/stdlib/mkstemp.cpp +++ b/libc/stdlib/mkstemp.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2013, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015. This file is part of the Sortix C Library. @@ -18,46 +18,13 @@ along with the Sortix C Library. If not, see . stdlib/mkstemp.cpp - Make a unique temporary filepath and opens it. + Make a unique temporary file path and open it. *******************************************************************************/ -#include -#include #include -#include - -const uint32_t NUM_CHARACTERS = 10 + 26 + 26; - -static inline char get_character(uint32_t index) -{ - 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" int mkstemp(char* templ) { - size_t templ_length = strlen(templ); - for ( size_t i = 0; i < 6; i++ ) - { - if ( templ_length - i == 0 ) - return errno = EINVAL, -1; - if ( templ[templ_length - i - 1] != 'X' ) - return errno = EINVAL, -1; - } - - int fd; - do - { - for ( size_t i = templ_length - 6; i < templ_length; i++ ) - templ[i] = get_character(arc4random_uniform(NUM_CHARACTERS)); - } while ( (fd = open(templ, O_RDWR | O_EXCL | O_CREAT, 0600)) < 0 && - (errno == EEXIST) ); - - return fd; + return mkostemps(templ, 0, 0); } diff --git a/libc/stdlib/mkstemps.cpp b/libc/stdlib/mkstemps.cpp new file mode 100644 index 00000000..34b694b7 --- /dev/null +++ b/libc/stdlib/mkstemps.cpp @@ -0,0 +1,30 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 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/mkstemps.cpp + Make a unique temporary file path and open it. + +*******************************************************************************/ + +#include + +extern "C" int mkstemps(char* templ, int suffixlen) +{ + return mkostemps(templ, suffixlen, 0); +}