Support drive letters and UNC paths on some non-Windows platforms.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3045 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -32,6 +32,9 @@ Documentation:
|
||||
in the directory. "/a/../b" will always be functionally equivalent to
|
||||
"/b", even when "/a" is a symlink.
|
||||
|
||||
Testing:
|
||||
- Test mounting an UNC directory
|
||||
|
||||
Bugs:
|
||||
- 'openDir(repository, "dir/")' will have the trailing '/'
|
||||
in the dirHandle, which will cause problems.
|
||||
|
||||
@@ -238,12 +238,12 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint,
|
||||
uio_MountInfo *mountInfo;
|
||||
uio_MountTree *mountTree;
|
||||
uio_PDirHandle *pRootHandle;
|
||||
#ifdef WIN32
|
||||
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||
char *unixPath;
|
||||
|
||||
unixPath = dosToUnixPath(inPath);
|
||||
inPath = unixPath;
|
||||
#endif
|
||||
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||
|
||||
if (inPath[0] == '/')
|
||||
inPath++;
|
||||
@@ -252,9 +252,9 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint,
|
||||
&endDirHandle, &endInPath);
|
||||
if (*endInPath != '\0') {
|
||||
// Path inside the filesystem to mount does not exist.
|
||||
#ifdef WIN32
|
||||
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||
uio_free(unixPath);
|
||||
#endif
|
||||
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||
uio_PDirHandle_unref(endDirHandle);
|
||||
uio_PRoot_unrefMount(pRoot);
|
||||
if (handle)
|
||||
@@ -266,10 +266,10 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint,
|
||||
dirName = uio_malloc(endInPath - inPath + 1);
|
||||
memcpy(dirName, inPath, endInPath - inPath);
|
||||
dirName[endInPath - inPath] = '\0';
|
||||
#ifdef WIN32
|
||||
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||
// InPath is a copy with the paths fixed.
|
||||
uio_free(unixPath);
|
||||
#endif
|
||||
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||
mountInfo = uio_MountInfo_new(fsType, NULL, endDirHandle, dirName,
|
||||
autoMount, NULL, flags);
|
||||
uio_repositoryAddMount(destRep, mountInfo,
|
||||
|
||||
@@ -367,9 +367,9 @@ decomposePath(const char *path, uio_PathComp **pathComp,
|
||||
uio_PathComp **endResult = &result;
|
||||
uio_bool absolute = false;
|
||||
char *name;
|
||||
#ifdef WIN32
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
size_t nameLen;
|
||||
#endif
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
|
||||
if (path[0] == '\0') {
|
||||
errno = ENOENT;
|
||||
@@ -377,7 +377,7 @@ decomposePath(const char *path, uio_PathComp **pathComp,
|
||||
}
|
||||
|
||||
last = NULL;
|
||||
#ifdef WIN32
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
path += uio_getUNCServerShare(path, &name, &nameLen);
|
||||
if (name != NULL) {
|
||||
// UNC path
|
||||
@@ -386,7 +386,10 @@ decomposePath(const char *path, uio_PathComp **pathComp,
|
||||
endResult = &last->next;
|
||||
|
||||
absolute = true;
|
||||
} else if (isDriveLetter(path[0]) && path[1] == ':') {
|
||||
} else
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if (isDriveLetter(path[0]) && path[1] == ':') {
|
||||
// DOS/Windows drive letter.
|
||||
if (path[2] != '\0' && !isPathDelimiter(path[2])) {
|
||||
errno = ENOENT;
|
||||
@@ -398,7 +401,7 @@ decomposePath(const char *path, uio_PathComp **pathComp,
|
||||
endResult = &last->next;
|
||||
absolute = true;
|
||||
} else
|
||||
#endif
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
{
|
||||
if (isPathDelimiter(*path)) {
|
||||
absolute = true;
|
||||
@@ -457,17 +460,20 @@ composePath(const uio_PathComp *pathComp, uio_bool absolute,
|
||||
pathPtr = result;
|
||||
ptr = pathComp;
|
||||
if (absolute) {
|
||||
#ifdef WIN32
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
if (ptr->name[0] == '\\') {
|
||||
// UNC path
|
||||
assert(ptr->name[1] == '\\');
|
||||
// Nothing to do.
|
||||
} else if (ptr->nameLen == 2 && ptr->name[1] == ':'
|
||||
} else
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if (ptr->nameLen == 2 && ptr->name[1] == ':'
|
||||
&& isDriveLetter(ptr->name[0])) {
|
||||
// Nothing to do.
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
{
|
||||
*(pathPtr++) = '/';
|
||||
}
|
||||
|
||||
@@ -61,22 +61,22 @@ size_t uio_skipUNCServerShare(const char *inPath);
|
||||
size_t uio_getUNCServerShare(const char *inPath, char **outPath,
|
||||
size_t *outLen);
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
static inline int
|
||||
isDriveLetter(int c)
|
||||
{
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
|
||||
static inline int
|
||||
isPathDelimiter(int c)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||
return c == '/' || c == '\\';
|
||||
#else
|
||||
return c == '/';
|
||||
#endif
|
||||
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||
}
|
||||
|
||||
int decomposePath(const char *path, uio_PathComp **pathComp,
|
||||
|
||||
@@ -340,20 +340,24 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
|
||||
const char *pathUpTo;
|
||||
char *path;
|
||||
struct stat statBuf;
|
||||
#ifdef WIN32
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
char driveName[3];
|
||||
#endif
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||
if (pDirHandle->extra->extra->upDir == NULL) {
|
||||
// Top dir. Contains only drive letters and UNC \\server\share
|
||||
// parts.
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if (isDriveLetter(name[0]) && name[1] == ':' && name[2] == '\0') {
|
||||
driveName[0] = tolower(name[0]);
|
||||
driveName[1] = ':';
|
||||
driveName[2] = '\0';
|
||||
name = driveName;
|
||||
} else {
|
||||
} else
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
{
|
||||
size_t uncLen;
|
||||
|
||||
uncLen = uio_skipUNCServerShare(name);
|
||||
@@ -363,14 +367,20 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else /* !defined(HAVE_UNC_PATHS) */
|
||||
{
|
||||
// Make sure that there is an 'else' case if HAVE_DRIVE_LETTERS
|
||||
// is defined.
|
||||
}
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
|
||||
|
||||
result = uio_GPDir_getPDirEntryHandle(pDirHandle, name);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||
if (pDirHandle->extra->extra->upDir == NULL) {
|
||||
// Need to create a 'directory' for the drive letter or UNC
|
||||
// "\\server\share" part.
|
||||
@@ -383,7 +393,7 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
|
||||
return (uio_PDirEntryHandle *) uio_PDirHandle_new(
|
||||
pDirHandle->pRoot, gPDir);
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
|
||||
|
||||
pathUpTo = stdio_getPath(pDirHandle->extra);
|
||||
if (pathUpTo == NULL) {
|
||||
@@ -434,12 +444,12 @@ stdio_mount(uio_Handle *handle, int flags) {
|
||||
assert (handle == NULL);
|
||||
extra = stdio_GPDirData_new(
|
||||
uio_strdup("") /* name */,
|
||||
#ifdef WIN32
|
||||
// In MS Windows, full paths start with a drive letter.
|
||||
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||
// Full paths start with a drive letter or \\server\share
|
||||
uio_strdup("") /* cached path */,
|
||||
#else
|
||||
uio_strdup("/") /* cached path */,
|
||||
#endif
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
NULL /* parent dir */);
|
||||
|
||||
result = uio_GPRoot_makePRoot(
|
||||
@@ -711,15 +721,15 @@ stdio_getPath(uio_GPDir *gPDir) {
|
||||
size_t upPathLen, nameLen;
|
||||
|
||||
if (gPDir->extra->upDir == NULL) {
|
||||
#ifdef WIN32
|
||||
// Drive letter still needs to follow.
|
||||
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||
// Drive letter or UNC \\server\share still needs to follow.
|
||||
gPDir->extra->cachedPath = uio_malloc(1);
|
||||
gPDir->extra->cachedPath[0] = '\0';
|
||||
#else
|
||||
gPDir->extra->cachedPath = uio_malloc(2);
|
||||
gPDir->extra->cachedPath[0] = '/';
|
||||
gPDir->extra->cachedPath[1] = '\0';
|
||||
#endif
|
||||
#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
|
||||
return gPDir->extra->cachedPath;
|
||||
}
|
||||
|
||||
@@ -729,21 +739,22 @@ stdio_getPath(uio_GPDir *gPDir) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||
if (upPath[0] == '\0') {
|
||||
// The up dir is the root dir. Directly below the root dir are
|
||||
// only dirs for drive letters. No '/' needs to be attached.
|
||||
// only dirs for drive letters and UNC \\share\server parts.
|
||||
// No '/' needs to be attached.
|
||||
gPDir->extra->cachedPath = uio_strdup(gPDir->extra->name);
|
||||
return gPDir->extra->cachedPath;
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
|
||||
upPathLen = strlen(upPath);
|
||||
#ifndef WIN32
|
||||
#if !defined(HAVE_DRIVE_LETTERS) && !defined(HAVE_UNC_PATHS)
|
||||
if (upPath[upPathLen - 1] == '/') {
|
||||
// should only happen for "/"
|
||||
upPathLen--;
|
||||
}
|
||||
#endif
|
||||
#endif /* !defined(HAVE_DRIVE_LETTERS) && !defined(HAVE_UNC_PATHS) */
|
||||
nameLen = strlen(gPDir->extra->name);
|
||||
if (upPathLen + nameLen + 1 >= PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
|
||||
@@ -65,6 +65,23 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Variations in path handling
|
||||
#if defined(WIN32) || defined(__SYMBIAN32__)
|
||||
// HAVE_DRIVE_LETTERS is defined to signify that DOS/Windows style drive
|
||||
// letters are to be recognised on this platform.
|
||||
# define HAVE_DRIVE_LETTERS
|
||||
// BACKSLASH_IS_PATH_SEPARATOR is defined to signify that the backslash
|
||||
// character is to be recognised as a path separator on this platform.
|
||||
// This does not affect the acceptance of forward slashes as path
|
||||
// separators.
|
||||
# define BACKSLASH_IS_PATH_SEPARATOR
|
||||
#endif
|
||||
#if defined(WIN32)
|
||||
// HAVE_UNC_PATHS is defined to signify that Universal Naming Convention
|
||||
// style paths are to be recognised on this platform.
|
||||
# define HAVE_UNC_PATHS
|
||||
#endif
|
||||
|
||||
// User ids
|
||||
#ifdef WIN32
|
||||
typedef short uid_t;
|
||||
|
||||
Reference in New Issue
Block a user