From 9ccdebcd96cfbdea122752d1b6bd45f507f4c7c5 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 22 May 2026 22:21:54 +0300 Subject: [PATCH] LibC: Implement/fix mk{,o}stemp{,s} --- userspace/libraries/LibC/include/stdlib.h | 6 +- userspace/libraries/LibC/stdlib.cpp | 78 +++++++++++++++-------- 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/userspace/libraries/LibC/include/stdlib.h b/userspace/libraries/LibC/include/stdlib.h index 3e1acb47..aecf2854 100644 --- a/userspace/libraries/LibC/include/stdlib.h +++ b/userspace/libraries/LibC/include/stdlib.h @@ -75,8 +75,8 @@ int mblen(const char* s, size_t n); size_t mbstowcs(wchar_t* __restrict pwcs, const char* __restrict s, size_t n); int mbtowc(wchar_t* __restrict pwc, const char* __restrict s, size_t n); char* mkdtemp(char* _template); -char* mktemp(char* _template); int mkstemp(char* _template); +int mkostemp(char* _template, int flags); long mrand48(void); long nrand48(unsigned short xsubi[3]); int posix_memalign(void** memptr, size_t alignment, size_t size); @@ -109,6 +109,10 @@ int unsetenv(const char* name); size_t wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n); int wctomb(char* s, wchar_t wchar); +char* mktemp(char* _template); +int mkstemps(char* _template, int suffixlen); +int mkostemps(char* _template, int suffixlen, int flags); + __END_DECLS #endif diff --git a/userspace/libraries/LibC/stdlib.cpp b/userspace/libraries/LibC/stdlib.cpp index 9a0e5c50..265dd4ef 100644 --- a/userspace/libraries/LibC/stdlib.cpp +++ b/userspace/libraries/LibC/stdlib.cpp @@ -475,31 +475,36 @@ int system(const char* command) return stat_val; } -static size_t temp_template_count_x(const char* _template) +static void randomize_temp(char* buffer) { - const size_t len = strlen(_template); - for (size_t i = 0; i < len; i++) - if (_template[len - i - 1] != 'X') - return i; - return len; + // FIXME: don't use rand() + const uint32_t value = rand() & 0xFFFFFF; + sprintf(buffer, "%06x", value); } -static void generate_temp_template(char* _template, size_t x_count) +static char* validate_temp_template(char* _template, int suffixlen) { - const size_t len = strlen(_template); - for (size_t i = 0; i < x_count; i++) + const size_t length = strlen(_template); + if (suffixlen < 0 || length < static_cast(suffixlen + 6)) { - const uint8_t nibble = rand() & 0xF; - _template[len - i - 1] = (nibble < 10) - ? ('0' + nibble) - : ('a' + nibble - 10); + errno = EINVAL; + return nullptr; } + + char* xptr = _template + length - suffixlen - 6; + if (memcmp(xptr, "XXXXXX", 6) != 0) + { + errno = EINVAL; + return nullptr; + } + + return xptr; } char* mktemp(char* _template) { - const size_t x_count = temp_template_count_x(_template); - if (x_count < 6) + char* xptr = validate_temp_template(_template, 0); + if (xptr == nullptr) { errno = EINVAL; _template[0] = '\0'; @@ -508,18 +513,22 @@ char* mktemp(char* _template) for (;;) { - generate_temp_template(_template, x_count); + randomize_temp(xptr); struct stat st; - if (stat(_template, &st) == 0) + if (stat(_template, &st) == -1) + { + if (errno != ENOENT) + _template[0] = '\0'; return _template; + } } } char* mkdtemp(char* _template) { - const size_t x_count = temp_template_count_x(_template); - if (x_count < 6) + char* xptr = validate_temp_template(_template, 0); + if (xptr == nullptr) { errno = EINVAL; return nullptr; @@ -527,8 +536,7 @@ char* mkdtemp(char* _template) for (;;) { - generate_temp_template(_template, x_count); - + randomize_temp(xptr); if (mkdir(_template, S_IRUSR | S_IWUSR | S_IXUSR) != -1) return _template; if (errno != EEXIST) @@ -538,8 +546,26 @@ char* mkdtemp(char* _template) int mkstemp(char* _template) { - const size_t x_count = temp_template_count_x(_template); - if (x_count < 6) + return mkostemps(_template, 0, 0); +} + +int mkostemp(char* _template, int flags) +{ + return mkostemps(_template, 0, flags); +} + +int mkstemps(char* _template, int suffixlen) +{ + return mkostemps(_template, suffixlen, 0); +} + +int mkostemps(char* _template, int suffixlen, int flags) +{ + flags &= O_APPEND | O_CLOEXEC | O_SYNC; + flags |= O_RDWR | O_CREAT | O_EXCL; + + char* xptr = validate_temp_template(_template, suffixlen); + if (xptr == nullptr) { errno = EINVAL; return -1; @@ -547,10 +573,8 @@ int mkstemp(char* _template) for (;;) { - generate_temp_template(_template, x_count); - - int fd = open(_template, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (fd != -1) + randomize_temp(xptr); + if (int fd = open(_template, flags, 0600); fd != -1) return fd; if (errno != EEXIST) return -1;