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:
Meep-Eep
2008-08-22 20:50:38 +00:00
parent ad25f17f1e
commit eea348180a
6 changed files with 73 additions and 36 deletions
+3
View File
@@ -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.
+6 -6
View File
@@ -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,
+14 -8
View File
@@ -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++) = '/';
}
+4 -4
View File
@@ -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,
+29 -18
View File
@@ -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
#endif /* HAVE_UNC_PATHS */
}
#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;
+17
View File
@@ -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;