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

View file

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

View file

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