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 in the directory. "/a/../b" will always be functionally equivalent to
"/b", even when "/a" is a symlink. "/b", even when "/a" is a symlink.
Testing:
- Test mounting an UNC directory
Bugs: Bugs:
- 'openDir(repository, "dir/")' will have the trailing '/' - 'openDir(repository, "dir/")' will have the trailing '/'
in the dirHandle, which will cause problems. 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_MountInfo *mountInfo;
uio_MountTree *mountTree; uio_MountTree *mountTree;
uio_PDirHandle *pRootHandle; uio_PDirHandle *pRootHandle;
#ifdef WIN32 #ifdef BACKSLASH_IS_PATH_SEPARATOR
char *unixPath; char *unixPath;
unixPath = dosToUnixPath(inPath); unixPath = dosToUnixPath(inPath);
inPath = unixPath; inPath = unixPath;
#endif #endif /* BACKSLASH_IS_PATH_SEPARATOR */
if (inPath[0] == '/') if (inPath[0] == '/')
inPath++; inPath++;
@@ -252,9 +252,9 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint,
&endDirHandle, &endInPath); &endDirHandle, &endInPath);
if (*endInPath != '\0') { if (*endInPath != '\0') {
// Path inside the filesystem to mount does not exist. // Path inside the filesystem to mount does not exist.
#ifdef WIN32 #ifdef BACKSLASH_IS_PATH_SEPARATOR
uio_free(unixPath); uio_free(unixPath);
#endif #endif /* BACKSLASH_IS_PATH_SEPARATOR */
uio_PDirHandle_unref(endDirHandle); uio_PDirHandle_unref(endDirHandle);
uio_PRoot_unrefMount(pRoot); uio_PRoot_unrefMount(pRoot);
if (handle) if (handle)
@@ -266,10 +266,10 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint,
dirName = uio_malloc(endInPath - inPath + 1); dirName = uio_malloc(endInPath - inPath + 1);
memcpy(dirName, inPath, endInPath - inPath); memcpy(dirName, inPath, endInPath - inPath);
dirName[endInPath - inPath] = '\0'; dirName[endInPath - inPath] = '\0';
#ifdef WIN32 #ifdef BACKSLASH_IS_PATH_SEPARATOR
// InPath is a copy with the paths fixed. // InPath is a copy with the paths fixed.
uio_free(unixPath); uio_free(unixPath);
#endif #endif /* BACKSLASH_IS_PATH_SEPARATOR */
mountInfo = uio_MountInfo_new(fsType, NULL, endDirHandle, dirName, mountInfo = uio_MountInfo_new(fsType, NULL, endDirHandle, dirName,
autoMount, NULL, flags); autoMount, NULL, flags);
uio_repositoryAddMount(destRep, mountInfo, uio_repositoryAddMount(destRep, mountInfo,
+14 -8
View File
@@ -367,9 +367,9 @@ decomposePath(const char *path, uio_PathComp **pathComp,
uio_PathComp **endResult = &result; uio_PathComp **endResult = &result;
uio_bool absolute = false; uio_bool absolute = false;
char *name; char *name;
#ifdef WIN32 #ifdef HAVE_UNC_PATHS
size_t nameLen; size_t nameLen;
#endif #endif /* HAVE_UNC_PATHS */
if (path[0] == '\0') { if (path[0] == '\0') {
errno = ENOENT; errno = ENOENT;
@@ -377,7 +377,7 @@ decomposePath(const char *path, uio_PathComp **pathComp,
} }
last = NULL; last = NULL;
#ifdef WIN32 #ifdef HAVE_UNC_PATHS
path += uio_getUNCServerShare(path, &name, &nameLen); path += uio_getUNCServerShare(path, &name, &nameLen);
if (name != NULL) { if (name != NULL) {
// UNC path // UNC path
@@ -386,7 +386,10 @@ decomposePath(const char *path, uio_PathComp **pathComp,
endResult = &last->next; endResult = &last->next;
absolute = true; 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. // DOS/Windows drive letter.
if (path[2] != '\0' && !isPathDelimiter(path[2])) { if (path[2] != '\0' && !isPathDelimiter(path[2])) {
errno = ENOENT; errno = ENOENT;
@@ -398,7 +401,7 @@ decomposePath(const char *path, uio_PathComp **pathComp,
endResult = &last->next; endResult = &last->next;
absolute = true; absolute = true;
} else } else
#endif #endif /* HAVE_DRIVE_LETTERS */
{ {
if (isPathDelimiter(*path)) { if (isPathDelimiter(*path)) {
absolute = true; absolute = true;
@@ -457,17 +460,20 @@ composePath(const uio_PathComp *pathComp, uio_bool absolute,
pathPtr = result; pathPtr = result;
ptr = pathComp; ptr = pathComp;
if (absolute) { if (absolute) {
#ifdef WIN32 #ifdef HAVE_UNC_PATHS
if (ptr->name[0] == '\\') { if (ptr->name[0] == '\\') {
// UNC path // UNC path
assert(ptr->name[1] == '\\'); assert(ptr->name[1] == '\\');
// Nothing to do. // 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])) { && isDriveLetter(ptr->name[0])) {
// Nothing to do. // Nothing to do.
} }
else else
#endif #endif /* HAVE_DRIVE_LETTERS */
{ {
*(pathPtr++) = '/'; *(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 uio_getUNCServerShare(const char *inPath, char **outPath,
size_t *outLen); size_t *outLen);
#ifdef WIN32 #ifdef HAVE_DRIVE_LETTERS
static inline int static inline int
isDriveLetter(int c) isDriveLetter(int c)
{ {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
} }
#endif #endif /* HAVE_DRIVE_LETTERS */
static inline int static inline int
isPathDelimiter(int c) isPathDelimiter(int c)
{ {
#ifdef WIN32 #ifdef BACKSLASH_IS_PATH_SEPARATOR
return c == '/' || c == '\\'; return c == '/' || c == '\\';
#else #else
return c == '/'; return c == '/';
#endif #endif /* BACKSLASH_IS_PATH_SEPARATOR */
} }
int decomposePath(const char *path, uio_PathComp **pathComp, 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; const char *pathUpTo;
char *path; char *path;
struct stat statBuf; struct stat statBuf;
#ifdef WIN32 #ifdef HAVE_DRIVE_LETTERS
char driveName[3]; 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) { if (pDirHandle->extra->extra->upDir == NULL) {
// Top dir. Contains only drive letters and UNC \\server\share // Top dir. Contains only drive letters and UNC \\server\share
// parts. // parts.
#ifdef HAVE_DRIVE_LETTERS
if (isDriveLetter(name[0]) && name[1] == ':' && name[2] == '\0') { if (isDriveLetter(name[0]) && name[1] == ':' && name[2] == '\0') {
driveName[0] = tolower(name[0]); driveName[0] = tolower(name[0]);
driveName[1] = ':'; driveName[1] = ':';
driveName[2] = '\0'; driveName[2] = '\0';
name = driveName; name = driveName;
} else { } else
#endif /* HAVE_DRIVE_LETTERS */
#ifdef HAVE_UNC_PATHS
{
size_t uncLen; size_t uncLen;
uncLen = uio_skipUNCServerShare(name); uncLen = uio_skipUNCServerShare(name);
@@ -363,14 +367,20 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
return NULL; 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); result = uio_GPDir_getPDirEntryHandle(pDirHandle, name);
if (result != NULL) if (result != NULL)
return result; return result;
#ifdef WIN32 #if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
if (pDirHandle->extra->extra->upDir == NULL) { if (pDirHandle->extra->extra->upDir == NULL) {
// Need to create a 'directory' for the drive letter or UNC // Need to create a 'directory' for the drive letter or UNC
// "\\server\share" part. // "\\server\share" part.
@@ -383,7 +393,7 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
return (uio_PDirEntryHandle *) uio_PDirHandle_new( return (uio_PDirEntryHandle *) uio_PDirHandle_new(
pDirHandle->pRoot, gPDir); pDirHandle->pRoot, gPDir);
} }
#endif #endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
pathUpTo = stdio_getPath(pDirHandle->extra); pathUpTo = stdio_getPath(pDirHandle->extra);
if (pathUpTo == NULL) { if (pathUpTo == NULL) {
@@ -434,12 +444,12 @@ stdio_mount(uio_Handle *handle, int flags) {
assert (handle == NULL); assert (handle == NULL);
extra = stdio_GPDirData_new( extra = stdio_GPDirData_new(
uio_strdup("") /* name */, uio_strdup("") /* name */,
#ifdef WIN32 #if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
// In MS Windows, full paths start with a drive letter. // Full paths start with a drive letter or \\server\share
uio_strdup("") /* cached path */, uio_strdup("") /* cached path */,
#else #else
uio_strdup("/") /* cached path */, uio_strdup("/") /* cached path */,
#endif #endif /* HAVE_DRIVE_LETTERS */
NULL /* parent dir */); NULL /* parent dir */);
result = uio_GPRoot_makePRoot( result = uio_GPRoot_makePRoot(
@@ -711,15 +721,15 @@ stdio_getPath(uio_GPDir *gPDir) {
size_t upPathLen, nameLen; size_t upPathLen, nameLen;
if (gPDir->extra->upDir == NULL) { if (gPDir->extra->upDir == NULL) {
#ifdef WIN32 #if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
// Drive letter still needs to follow. // Drive letter or UNC \\server\share still needs to follow.
gPDir->extra->cachedPath = uio_malloc(1); gPDir->extra->cachedPath = uio_malloc(1);
gPDir->extra->cachedPath[0] = '\0'; gPDir->extra->cachedPath[0] = '\0';
#else #else
gPDir->extra->cachedPath = uio_malloc(2); gPDir->extra->cachedPath = uio_malloc(2);
gPDir->extra->cachedPath[0] = '/'; gPDir->extra->cachedPath[0] = '/';
gPDir->extra->cachedPath[1] = '\0'; gPDir->extra->cachedPath[1] = '\0';
#endif #endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
return gPDir->extra->cachedPath; return gPDir->extra->cachedPath;
} }
@@ -729,21 +739,22 @@ stdio_getPath(uio_GPDir *gPDir) {
return NULL; return NULL;
} }
#ifdef WIN32 #if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
if (upPath[0] == '\0') { if (upPath[0] == '\0') {
// The up dir is the root dir. Directly below the root dir are // 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); gPDir->extra->cachedPath = uio_strdup(gPDir->extra->name);
return gPDir->extra->cachedPath; return gPDir->extra->cachedPath;
} }
#endif #endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
upPathLen = strlen(upPath); upPathLen = strlen(upPath);
#ifndef WIN32 #if !defined(HAVE_DRIVE_LETTERS) && !defined(HAVE_UNC_PATHS)
if (upPath[upPathLen - 1] == '/') { if (upPath[upPathLen - 1] == '/') {
// should only happen for "/" // should only happen for "/"
upPathLen--; upPathLen--;
} }
#endif #endif /* !defined(HAVE_DRIVE_LETTERS) && !defined(HAVE_UNC_PATHS) */
nameLen = strlen(gPDir->extra->name); nameLen = strlen(gPDir->extra->name);
if (upPathLen + nameLen + 1 >= PATH_MAX) { if (upPathLen + nameLen + 1 >= PATH_MAX) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
+17
View File
@@ -65,6 +65,23 @@
# endif # endif
#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 // User ids
#ifdef WIN32 #ifdef WIN32
typedef short uid_t; typedef short uid_t;