Fixed GfParms::safeFOpen silently failing to create parent dir under Windows (mkdir('D:') doesn't work)
Added new tgf::GfFileGetDirName git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@3402 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: 30d29e36415a484e4f92352ea5ed95e4be8ab567 Former-commit-id: ae28668b7d4dd31548e7c35f73218736e8384f28
This commit is contained in:
parent
534eb01eb1
commit
c6e970d545
3 changed files with 60 additions and 17 deletions
|
@ -36,12 +36,64 @@
|
|||
#include "tgf.h"
|
||||
|
||||
|
||||
/** Get the path-name of the directory containing a file
|
||||
@ingroup file
|
||||
@param pszFileName path-name of the file
|
||||
@return Path-name of the directory, allocated on the heap (the caller must free it).
|
||||
*/
|
||||
char* GfFileGetDirName(const char* pszFileName)
|
||||
{
|
||||
// Allocate and initialize the target string
|
||||
char* pszDirName = strdup(pszFileName);
|
||||
|
||||
// Replace '\\' by '/' under Windows
|
||||
#ifdef WIN32
|
||||
for (int i = 0; pszDirName[i]; i++)
|
||||
if (pszDirName[i] == '\\')
|
||||
pszDirName[i] = '/';
|
||||
#endif
|
||||
|
||||
// Search for the last '/'.
|
||||
char *lastSlash = strrchr(pszDirName, '/');
|
||||
|
||||
// If found, we've got the end of the directory name.
|
||||
if (lastSlash)
|
||||
{
|
||||
// But keep the '/' if it is the first one of an absolute path-name.
|
||||
if (lastSlash != pszDirName)
|
||||
#ifdef WIN32
|
||||
if (*(lastSlash-1) != ':')
|
||||
#endif
|
||||
*lastSlash = '\0';
|
||||
}
|
||||
|
||||
// If no '/' found, empty directory name.
|
||||
else
|
||||
*pszDirName = '\0';
|
||||
|
||||
//GfLogDebug("GfFileGetDirName(%s) = %s\n", pszFileName, pszDirName);
|
||||
|
||||
// That's all.
|
||||
return pszDirName;
|
||||
}
|
||||
|
||||
/** Check if a file exists
|
||||
@ingroup file
|
||||
@param pszName Path-name of the file
|
||||
@return true if the file exists, false otherwise.
|
||||
*/
|
||||
bool GfFileExists(const char* pszName)
|
||||
{
|
||||
struct stat st;
|
||||
return stat(pszName, &st) ? false : true;
|
||||
}
|
||||
|
||||
/** Copy a file to a target path-name
|
||||
@ingroup file
|
||||
@param pszSrcName Source file path-name
|
||||
@param pszSrcName Target file path-name for the copy
|
||||
@return true upon success, false otherwise.
|
||||
*/
|
||||
bool GfFileCopy(const char* pszSrcName, const char* pszTgtName)
|
||||
{
|
||||
static const size_t maxBufSize = 1024;
|
||||
|
@ -54,6 +106,7 @@ bool GfFileCopy(const char* pszSrcName, const char* pszTgtName)
|
|||
|
||||
// Create the target local directory (and parents) if not already done
|
||||
// (first, we have to deduce its path from the target file path-name).
|
||||
// TODO: Use GfFileGetDirName
|
||||
strncpy(buf, pszTgtName, strlen(pszTgtName)+1);
|
||||
#ifdef WIN32
|
||||
for (int i = 0; i < maxBufSize && buf[i] != '\0'; i++)
|
||||
|
|
|
@ -3743,25 +3743,14 @@ safeFOpen(const char *fileName, const char *mode)
|
|||
return file;
|
||||
}
|
||||
|
||||
// TODO: Make things simpler by using GfDirCreate (takes care of parent dirs).
|
||||
// Otherwise, try and create parent dirs in case it is the cause of the error :
|
||||
// - search the fileName for directory level separators (\\ or /) and create each directory.
|
||||
// - directories' permissions are set to 700=u+rwx on UNIX-like systems.
|
||||
// - the only error we silently ignore from mkdir is when the dir already exists.
|
||||
char *mname = strdup(fileName);
|
||||
for(int i = 0; mname[i] != '\0'; i++) {
|
||||
if(i > 0 && (mname[i] == '\\' || mname[i] == '/')) {
|
||||
const char slash = mname[i];
|
||||
mname[i] = '\0';
|
||||
if(mkdir(mname) == -1 && errno != EEXIST) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mname[i] = slash;
|
||||
}//if i
|
||||
}//for i
|
||||
char *pszDirName = GfFileGetDirName(fileName);
|
||||
if (GfDirCreate(pszDirName) != GF_DIR_CREATED)
|
||||
GfLogWarning("Failed to create parent dir(s) of %s\n", fileName);
|
||||
free(pszDirName);
|
||||
|
||||
free(mname);
|
||||
// And finally try again to open the file.
|
||||
return fopen(fileName, mode);
|
||||
|
||||
}//safeFOpen
|
||||
|
||||
|
|
|
@ -262,6 +262,7 @@ TGF_API void GfDirFreeList(tFList *list, tfDirfreeUserData freeUserData, bool fr
|
|||
* File management *
|
||||
************************/
|
||||
|
||||
TGF_API char* GfFileGetDirName(const char* pszFileName);
|
||||
TGF_API bool GfFileExists(const char* pszName);
|
||||
TGF_API bool GfFileCopy(const char* pszSrcName, const char* pszTgtName);
|
||||
|
||||
|
|
Loading…
Reference in a new issue