mirror of
https://git.zap.org.au/git/trader.git
synced 2024-09-01 17:14:15 -04:00
Create parent directories if required during mkdir
This commit is contained in:
parent
28e7cc450c
commit
90a815afbb
29
src/fileio.c
29
src/fileio.c
@ -444,7 +444,6 @@ bool save_game (int num)
|
|||||||
char *codeset;
|
char *codeset;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
char *prev_locale;
|
char *prev_locale;
|
||||||
struct stat statbuf;
|
|
||||||
int i, j, x, y;
|
int i, j, x, y;
|
||||||
unsigned int crypt_key;
|
unsigned int crypt_key;
|
||||||
unsigned int *crypt_key_p;
|
unsigned int *crypt_key_p;
|
||||||
@ -466,25 +465,19 @@ bool save_game (int num)
|
|||||||
// Create the data directory, if needed
|
// Create the data directory, if needed
|
||||||
data_dir = data_directory();
|
data_dir = data_directory();
|
||||||
if (data_dir != NULL) {
|
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;
|
saved_errno = errno;
|
||||||
if (saved_errno == EEXIST && stat(data_dir, &statbuf) == 0
|
txdlgbox(MAX_DLG_LINES, 60, 7, WCENTER, attr_error_window,
|
||||||
&& S_ISDIR(statbuf.st_mode)) {
|
attr_error_title, attr_error_highlight, attr_error_normal,
|
||||||
; // Do nothing: directory already exists
|
0, attr_error_waitforkey, _(" Game Not Saved "),
|
||||||
} else {
|
_("Game %d could not be saved to disk.\n\n"
|
||||||
// Data directory could not be created
|
"^{Directory %s: %s^}"), num, data_dir,
|
||||||
txdlgbox(MAX_DLG_LINES, 60, 7, WCENTER, attr_error_window,
|
strerror(saved_errno));
|
||||||
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(buf);
|
||||||
free(encbuf);
|
free(encbuf);
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
63
src/utils.c
63
src/utils.c
@ -967,7 +967,7 @@ size_t b64encode (const void *restrict in, size_t inlen,
|
|||||||
|
|
||||||
if (padding > 0) {
|
if (padding > 0) {
|
||||||
assert(count + 2 < outlen);
|
assert(count + 2 < outlen);
|
||||||
for (; padding < 3; padding++) {
|
for ( ; padding < 3; padding++) {
|
||||||
*u_out++ = SCRAMBLE_PAD_CHAR;
|
*u_out++ = SCRAMBLE_PAD_CHAR;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -1067,6 +1067,67 @@ ssize_t b64decode (const void *restrict in, size_t inlen,
|
|||||||
// These functions are documented in the file "utils.h"
|
// 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
|
// xmalloc: Allocate a new block of memory, with checking
|
||||||
|
|
||||||
|
14
src/utils.h
14
src/utils.h
@ -324,6 +324,20 @@ extern char *unscramble (char *restrict dest, const char *restrict src,
|
|||||||
* Miscellaneous function prototypes *
|
* 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
|
Function: xmalloc - Allocate a new block of memory, with checking
|
||||||
Parameters: size - Size of new block of memory in bytes
|
Parameters: size - Size of new block of memory in bytes
|
||||||
|
Loading…
Reference in New Issue
Block a user