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 mbstowcs(wchar_t* dest, const char* src,
|
||||||
size_t n); // Not implemented.
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include <luna.h>
|
#include <luna.h>
|
||||||
#include <luna/syscall.h>
|
#include <luna/syscall.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -188,8 +190,52 @@ extern "C"
|
|||||||
NOT_IMPLEMENTED("mbstowcs");
|
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:
|
build:
|
||||||
@mkdir -p $(TESTDIR)/bin
|
@mkdir -p $(TESTDIR)/bin
|
||||||
$(LUNA_ROOT)/tools/sync-libc.sh
|
$(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:
|
install:
|
||||||
$(LUNA_ROOT)/tools/clean.sh
|
$(LUNA_ROOT)/tools/clean.sh
|
||||||
|
@ -24,6 +24,7 @@ DEFINE_TEST(atoll);
|
|||||||
DEFINE_TEST(srand);
|
DEFINE_TEST(srand);
|
||||||
DEFINE_TEST(malloc);
|
DEFINE_TEST(malloc);
|
||||||
DEFINE_TEST(calloc);
|
DEFINE_TEST(calloc);
|
||||||
|
DEFINE_TEST(mktemp);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -51,4 +52,5 @@ int main()
|
|||||||
RUN_TEST(srand);
|
RUN_TEST(srand);
|
||||||
RUN_TEST(malloc);
|
RUN_TEST(malloc);
|
||||||
RUN_TEST(calloc);
|
RUN_TEST(calloc);
|
||||||
|
RUN_TEST(mktemp);
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
#include "Test.h"
|
#include "Test.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
DEFINE_TEST(atoi)
|
DEFINE_TEST(atoi)
|
||||||
{
|
{
|
||||||
@ -138,3 +140,27 @@ DEFINE_TEST(calloc)
|
|||||||
|
|
||||||
TEST_SUCCESS();
|
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