1
0
mirror of https://git.zap.org.au/git/trader.git synced 2024-07-07 15:54:14 -04:00

Create parent directories if required during mkdir

This commit is contained in:
John Zaitseff 2021-01-12 09:48:05 +11:00
parent 28e7cc450c
commit 90a815afbb
3 changed files with 87 additions and 19 deletions

View File

@ -444,7 +444,6 @@ bool save_game (int num)
char *codeset;
int saved_errno;
char *prev_locale;
struct stat statbuf;
int i, j, x, y;
unsigned int crypt_key;
unsigned int *crypt_key_p;
@ -466,25 +465,19 @@ bool save_game (int num)
// Create the data directory, if needed
data_dir = data_directory();
if (data_dir != NULL) {
if (mkdir(data_dir, S_IRWXU | S_IRWXG | S_IRWXO) != 0) {
if (xmkdir(data_dir, S_IRWXU | S_IRWXG | S_IRWXO) != 0) {
// Data directory could not be created
saved_errno = errno;
if (saved_errno == EEXIST && stat(data_dir, &statbuf) == 0
&& S_ISDIR(statbuf.st_mode)) {
; // Do nothing: directory already exists
} else {
// Data directory could not be created
txdlgbox(MAX_DLG_LINES, 60, 7, WCENTER, attr_error_window,
attr_error_title, attr_error_highlight,
attr_error_normal, 0, attr_error_waitforkey,
_(" Game Not Saved "),
_("Game %d could not be saved to disk.\n\n"
"^{Directory %s: %s^}"), num, data_dir,
strerror(saved_errno));
txdlgbox(MAX_DLG_LINES, 60, 7, WCENTER, attr_error_window,
attr_error_title, attr_error_highlight, attr_error_normal,
0, attr_error_waitforkey, _(" Game Not Saved "),
_("Game %d could not be saved to disk.\n\n"
"^{Directory %s: %s^}"), num, data_dir,
strerror(saved_errno));
free(buf);
free(encbuf);
return false;
}
free(buf);
free(encbuf);
return false;
}
}

View File

@ -967,7 +967,7 @@ size_t b64encode (const void *restrict in, size_t inlen,
if (padding > 0) {
assert(count + 2 < outlen);
for (; padding < 3; padding++) {
for ( ; padding < 3; padding++) {
*u_out++ = SCRAMBLE_PAD_CHAR;
count++;
}
@ -1067,6 +1067,67 @@ ssize_t b64decode (const void *restrict in, size_t inlen,
// These functions are documented in the file "utils.h"
/***********************************************************************/
// xmkdir: Check and create directory with its parents
int xmkdir (const char *pathname, mode_t mode)
{
const char *dirsep = DIRSEP;
struct stat statbuf;
char *pathcopy;
char *pcomp, *pend;
int ret;
assert(strlen(dirsep) == 1);
if (pathname == NULL || *pathname == '\0') {
errno = ENOENT; // As documented by POSIX
return -1;
}
// Check that pathname already exists and is a directory
if (stat(pathname, &statbuf) == 0) {
if (S_ISDIR(statbuf.st_mode)) {
return 0;
} else {
errno = ENOTDIR;
return -1;
}
}
// Try creating the directory
ret = mkdir(pathname, mode);
if (ret == 0 || (errno != ENOENT && errno != ENOTDIR)) {
return ret;
}
// Try creating directory components, except the last, one by one
pathcopy = xstrdup(pathname);
pcomp = pend = pathcopy;
for ( ; *pend != '\0'; pend++) {
if (*pend == dirsep[0] && pcomp != pend) {
*pend = '\0';
ret = mkdir(pathcopy, mode);
if (ret != 0 && errno != EEXIST) {
free(pathcopy);
return ret;
}
*pend = dirsep[0];
pcomp = pend + 1;
}
}
// Try creating the last directory component
ret = mkdir(pathcopy, mode);
free(pathcopy);
return ret;
}
/***********************************************************************/
// xmalloc: Allocate a new block of memory, with checking

View File

@ -324,6 +324,20 @@ extern char *unscramble (char *restrict dest, const char *restrict src,
* Miscellaneous function prototypes *
************************************************************************/
/*
Function: xmkdir - Check and create directory with its parents
Parameters: pathname - Directory to create
mode - Mode for any new directories
Returns: int - 0 on success, -1 if an error occurred
This function checks whether pathname exists and is a directory: if so,
0 is returned. Otherwise, it creates the directory and any parents
that do not already exist. If an error occurs, -1 is returned and
errno is set appropriately.
*/
extern int xmkdir (const char *pathname, mode_t mode);
/*
Function: xmalloc - Allocate a new block of memory, with checking
Parameters: size - Size of new block of memory in bytes