Add emkdirs() and emkdirsn()

This commit is contained in:
Andrew Bettison 2013-04-04 17:37:49 +10:30
parent 4be43b76d5
commit 65f6e88e67
4 changed files with 53 additions and 31 deletions

View File

@ -53,5 +53,5 @@ int form_serval_instance_path(char *buf, size_t bufsiz, const char *path)
}
int create_serval_instance_dir() {
return mkdirs(serval_instancepath(), 0700);
return emkdirs(serval_instancepath(), 0700);
}

72
os.c
View File

@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define __SERVALDNA_OS_INLINE
#include "os.h"
#include "str.h"
#include "log.h"
#include <sys/types.h>
@ -35,39 +36,56 @@ int mkdirs(const char *path, mode_t mode)
return mkdirsn(path, strlen(path), mode);
}
int emkdirs(const char *path, mode_t mode)
{
if (mkdirs(path, mode) == -1)
return WHYF_perror("mkdirs(%s,%o)", alloca_str_toprint(path), mode);
return 0;
}
int emkdirsn(const char *path, size_t len, mode_t mode)
{
if (mkdirsn(path, len, mode) == -1)
return WHYF_perror("mkdirsn(%s,%lu,%o)", alloca_toprint(-1, path, len), (unsigned long)len, mode);
return 0;
}
/* This variant must not log anything, because it is used by the logging subsystem itself!
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
int mkdirsn(const char *path, size_t len, mode_t mode)
{
if (len == 0)
return WHY("Bug: empty path");
char *pathfrag = alloca(len + 1);
strncpy(pathfrag, path, len);
pathfrag[len] = '\0';
if (mkdir(pathfrag, mode) != -1)
return 0;
if (errno == EEXIST) {
DIR *d = opendir(pathfrag);
if (!d) {
WHY_perror("opendir");
return WHYF("cannot access %s", pathfrag);
}
closedir(d);
return 0;
}
if (errno == ENOENT) {
const char *lastsep = path + len - 1;
while (lastsep != path && *--lastsep != '/')
;
while (lastsep != path && *--lastsep == '/')
;
if (lastsep != path) {
if (mkdirsn(path, lastsep - path + 1, mode) == -1)
return -1;
if (mkdir(pathfrag, mode) != -1)
errno = EINVAL;
else {
char *pathfrag = alloca(len + 1);
strncpy(pathfrag, path, len);
pathfrag[len] = '\0';
if (mkdir(pathfrag, mode) != -1)
return 0;
if (errno == EEXIST) {
DIR *d = opendir(pathfrag);
if (d) {
closedir(d);
return 0;
}
}
else if (errno == ENOENT) {
const char *lastsep = path + len - 1;
while (lastsep != path && *--lastsep != '/')
;
while (lastsep != path && *--lastsep == '/')
;
if (lastsep != path) {
if (mkdirsn(path, lastsep - path + 1, mode) == -1)
return -1;
if (mkdir(pathfrag, mode) != -1)
return 0;
}
}
}
WHY_perror("mkdir");
return WHYF("cannot mkdir %s", pathfrag);
return -1;
}
int urandombytes(unsigned char *buf, unsigned long long len)

4
os.h
View File

@ -69,8 +69,12 @@ __SERVALDNA_OS_INLINE void bcopy(void *src, void *dst, size_t len) {
}
#endif
/* The "e" variants log the error before returning -1.
*/
int mkdirs(const char *path, mode_t mode);
int emkdirs(const char *path, mode_t mode);
int mkdirsn(const char *path, size_t len, mode_t mode);
int emkdirsn(const char *path, size_t len, mode_t mode);
void srandomdev();
int urandombytes(unsigned char *buf, unsigned long long len);

View File

@ -84,7 +84,7 @@ int form_rhizome_import_path(char * buf, size_t bufsiz, const char *fmt, ...)
int create_rhizome_datastore_dir()
{
if (config.debug.rhizome) DEBUGF("mkdirs(%s, 0700)", rhizome_datastore_path());
return mkdirs(rhizome_datastore_path(), 0700);
return emkdirs(rhizome_datastore_path(), 0700);
}
int create_rhizome_import_dir()
@ -93,7 +93,7 @@ int create_rhizome_import_dir()
if (!form_rhizome_import_path(dirname, sizeof dirname, NULL))
return -1;
if (config.debug.rhizome) DEBUGF("mkdirs(%s, 0700)", dirname);
return mkdirs(dirname, 0700);
return emkdirs(dirname, 0700);
}
sqlite3 *rhizome_db=NULL;
@ -1618,4 +1618,4 @@ int rhizome_is_bar_interesting(unsigned char *bar){
RETURN(ret);
OUT();
}
}