Add UtilMkdir() to recursively make directories

This commit is contained in:
Jordan Bancino 2022-11-17 22:57:29 +00:00
parent 9597894356
commit d26fad4619
4 changed files with 94 additions and 6 deletions

View file

@ -255,11 +255,23 @@ DbCreate(Db * db, char *prefix, char *key)
file = DbFileName(db, prefix, key);
if (UtilLastModified(file))
if (UtilLastModified(file) || UtilMkdir(prefix, 0750) < 0)
{
Free(file);
return NULL;
}
fp = fopen(file, "w");
Free(file);
if (!fp)
{
return NULL;
}
fprintf(fp, "{}");
fflush(fp);
fclose(fp);
return DbLock(db, prefix, key);
}
@ -380,7 +392,7 @@ finish:
return ref;
}
void
int
DbUnlock(Db * db, DbRef * ref)
{
FILE *fp;
@ -388,7 +400,7 @@ DbUnlock(Db * db, DbRef * ref)
if (!db || !ref)
{
return;
return 0;
}
pthread_mutex_lock(&db->lock);
@ -396,8 +408,8 @@ DbUnlock(Db * db, DbRef * ref)
file = DbFileName(db, ref->prefix, ref->key);
fp = fopen(file, "w");
if (!fp)
{ /* TODO: This seems dangerous */
return;
{
return 0;
}
JsonEncode(ref->json, fp);
@ -415,6 +427,8 @@ DbUnlock(Db * db, DbRef * ref)
pthread_mutex_destroy(&ref->lock);
Free(ref);
}
return 1;
}
HashMap *

View file

@ -66,6 +66,77 @@ UtilLastModified(char *path)
}
}
int
UtilMkdir(const char *dir, const mode_t mode)
{
char tmp[PATH_MAX];
char *p = NULL;
struct stat st;
size_t len;
len = strnlen(dir, PATH_MAX);
if (!len || len == PATH_MAX)
{
errno = ENAMETOOLONG;
return -1;
}
memcpy(tmp, dir, len);
tmp[len] = '\0';
if (tmp[len - 1] == '/')
{
tmp[len - 1] = '\0';
}
if (stat(tmp, &st) == 0 && S_ISDIR(st.st_mode))
{
return 0;
}
for (p = tmp + 1; *p; p++)
{
if (*p == '/')
{
*p = 0;
if (stat(tmp, &st) != 0)
{
if (mkdir(tmp, mode) < 0)
{
/* errno already set by mkdir() */
return -1;
}
}
else if (!S_ISDIR(st.st_mode))
{
errno = ENOTDIR;
return -1;
}
*p = '/';
}
}
if (stat(tmp, &st) != 0)
{
if (mkdir(tmp, mode) < 0)
{
/* errno already set by mkdir() */
return -1;
}
}
else if (!S_ISDIR(st.st_mode))
{
errno = ENOTDIR;
return -1;
}
return 0;
}
char *
UtilUtf8Encode(unsigned long utf8)
{

View file

@ -43,7 +43,7 @@ extern DbRef *
extern DbRef *
DbLock(Db *, char *, char *);
extern void
extern int
DbUnlock(Db *, DbRef *);
extern HashMap *

View file

@ -60,6 +60,9 @@ extern unsigned long
extern unsigned long
UtilLastModified(char *);
extern int
UtilMkdir(const char *, const mode_t);
/*
* Encode a single UTF-8 codepoint as a string buffer containing
* between 1 and 4 bytes. The string buffer is allocated on the heap,