mirror of
https://git.zap.org.au/git/trader.git
synced 2024-12-04 14:46:45 -05: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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
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) {
|
||||
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
|
||||
|
||||
|
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 *
|
||||
************************************************************************/
|
||||
|
||||
/*
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user