forked from lda/telodendria
Add UtilMkdir() to recursively make directories
This commit is contained in:
parent
9597894356
commit
d26fad4619
4 changed files with 94 additions and 6 deletions
24
src/Db.c
24
src/Db.c
|
@ -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 *
|
||||
|
|
71
src/Util.c
71
src/Util.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -43,7 +43,7 @@ extern DbRef *
|
|||
extern DbRef *
|
||||
DbLock(Db *, char *, char *);
|
||||
|
||||
extern void
|
||||
extern int
|
||||
DbUnlock(Db *, DbRef *);
|
||||
|
||||
extern HashMap *
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue