libc: Add mktemp() and mkdtemp(), along with a test for mktemp
This commit is contained in:
parent
b2fb740d99
commit
da182f1c2f
@ -120,7 +120,10 @@ extern "C"
|
||||
size_t mbstowcs(wchar_t* dest, const char* src,
|
||||
size_t n); // Not implemented.
|
||||
|
||||
char* mktemp(char* base); // Not implemented.
|
||||
/* Generate a unique filename from the template string str. The last 6 bytes of str must be 'XXXXXX', and they will
|
||||
* be replaced with random characters. This function is deprecated due to race conditions; between the name being
|
||||
* generated and creating a file with that name, that filename could have already been used. */
|
||||
__lc_is_deprecated char* mktemp(char* str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <luna.h>
|
||||
#include <luna/syscall.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
@ -188,8 +190,52 @@ extern "C"
|
||||
NOT_IMPLEMENTED("mbstowcs");
|
||||
}
|
||||
|
||||
char* mktemp(char*)
|
||||
static void gentemp(char* startptr)
|
||||
{
|
||||
NOT_IMPLEMENTED("mktemp");
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
startptr[i] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"[rand() % 63];
|
||||
}
|
||||
}
|
||||
|
||||
char* mktemp(char* str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
if (len < 6)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
char* startptr = str + (len - 6);
|
||||
if (strncmp(startptr, "XXXXXX", 6))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
do {
|
||||
gentemp(startptr);
|
||||
} while (access(str, F_OK) == 0);
|
||||
return str;
|
||||
}
|
||||
|
||||
char* mkdtemp(char* str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
if (len < 6)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
char* startptr = str + (len - 6);
|
||||
if (strncmp(startptr, "XXXXXX", 6))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
do {
|
||||
gentemp(startptr);
|
||||
} while (mkdir(str, 0700) < 0 && errno == EEXIST);
|
||||
if (errno) return NULL;
|
||||
return str;
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ DESTDIR := $(LUNA_ROOT)/initrd/bin
|
||||
build:
|
||||
@mkdir -p $(TESTDIR)/bin
|
||||
$(LUNA_ROOT)/tools/sync-libc.sh
|
||||
$(CC) $(TESTDIR)/string.c $(TESTDIR)/stdlib.c $(TESTDIR)/Test.c -I$(LUNA_ROOT)/tests -o $(TESTDIR)/bin/test-libc -Wall -Wextra -Wno-stringop-overread -Werror
|
||||
$(CC) $(TESTDIR)/string.c $(TESTDIR)/stdlib.c $(TESTDIR)/Test.c -I$(LUNA_ROOT)/tests -o $(TESTDIR)/bin/test-libc -Wall -Wextra -Wno-deprecated-declarations -Wno-stringop-overread -Werror
|
||||
|
||||
install:
|
||||
$(LUNA_ROOT)/tools/clean.sh
|
||||
|
@ -24,6 +24,7 @@ DEFINE_TEST(atoll);
|
||||
DEFINE_TEST(srand);
|
||||
DEFINE_TEST(malloc);
|
||||
DEFINE_TEST(calloc);
|
||||
DEFINE_TEST(mktemp);
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -51,4 +52,5 @@ int main()
|
||||
RUN_TEST(srand);
|
||||
RUN_TEST(malloc);
|
||||
RUN_TEST(calloc);
|
||||
RUN_TEST(mktemp);
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#include "Test.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
DEFINE_TEST(atoi)
|
||||
{
|
||||
@ -136,5 +138,29 @@ DEFINE_TEST(calloc)
|
||||
|
||||
free(ptr);
|
||||
|
||||
TEST_SUCCESS();
|
||||
}
|
||||
|
||||
DEFINE_TEST(mktemp)
|
||||
{
|
||||
START_TEST(mktemp);
|
||||
|
||||
char template[] = "/tmp/file.XXXXXX";
|
||||
|
||||
const char* template2 = "/tmp/file.XXXXXX";
|
||||
|
||||
char* ptr = mktemp(template);
|
||||
|
||||
EXPECT_NOT_EQ(ptr, NULL); // mktemp only fails if we give it an invalid template.
|
||||
|
||||
int rc = access(ptr, F_OK);
|
||||
|
||||
EXPECT_NOT_EQ(rc, 0); // FIXME: This could actually happen, since that's why mktemp is deprecated.
|
||||
// Another process could create the file between generating the name and actually using it.
|
||||
|
||||
rc = strcmp(ptr, template2);
|
||||
|
||||
EXPECT_NOT_EQ(rc, 0);
|
||||
|
||||
TEST_SUCCESS();
|
||||
}
|
Loading…
Reference in New Issue
Block a user