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() { 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 #define __SERVALDNA_OS_INLINE
#include "os.h" #include "os.h"
#include "str.h"
#include "log.h" #include "log.h"
#include <sys/types.h> #include <sys/types.h>
@ -35,39 +36,56 @@ int mkdirs(const char *path, mode_t mode)
return mkdirsn(path, strlen(path), 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) int mkdirsn(const char *path, size_t len, mode_t mode)
{ {
if (len == 0) if (len == 0)
return WHY("Bug: empty path"); errno = EINVAL;
char *pathfrag = alloca(len + 1); else {
strncpy(pathfrag, path, len); char *pathfrag = alloca(len + 1);
pathfrag[len] = '\0'; strncpy(pathfrag, path, len);
if (mkdir(pathfrag, mode) != -1) pathfrag[len] = '\0';
return 0; if (mkdir(pathfrag, mode) != -1)
if (errno == EEXIST) { return 0;
DIR *d = opendir(pathfrag); if (errno == EEXIST) {
if (!d) { DIR *d = opendir(pathfrag);
WHY_perror("opendir"); if (d) {
return WHYF("cannot access %s", pathfrag); closedir(d);
}
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)
return 0; 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 -1;
return WHYF("cannot mkdir %s", pathfrag);
} }
int urandombytes(unsigned char *buf, unsigned long long len) 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 #endif
/* The "e" variants log the error before returning -1.
*/
int mkdirs(const char *path, mode_t mode); 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 mkdirsn(const char *path, size_t len, mode_t mode);
int emkdirsn(const char *path, size_t len, mode_t mode);
void srandomdev(); void srandomdev();
int urandombytes(unsigned char *buf, unsigned long long len); 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() int create_rhizome_datastore_dir()
{ {
if (config.debug.rhizome) DEBUGF("mkdirs(%s, 0700)", rhizome_datastore_path()); 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() int create_rhizome_import_dir()
@ -93,7 +93,7 @@ int create_rhizome_import_dir()
if (!form_rhizome_import_path(dirname, sizeof dirname, NULL)) if (!form_rhizome_import_path(dirname, sizeof dirname, NULL))
return -1; return -1;
if (config.debug.rhizome) DEBUGF("mkdirs(%s, 0700)", dirname); if (config.debug.rhizome) DEBUGF("mkdirs(%s, 0700)", dirname);
return mkdirs(dirname, 0700); return emkdirs(dirname, 0700);
} }
sqlite3 *rhizome_db=NULL; sqlite3 *rhizome_db=NULL;
@ -1618,4 +1618,4 @@ int rhizome_is_bar_interesting(unsigned char *bar){
RETURN(ret); RETURN(ret);
OUT(); OUT();
} }