Added uio_getPhysicalAccess(), uio_getMountFileSystemType() and

some small improvements.


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1283 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
meep-eep
2003-10-24 02:36:27 +00:00
parent c8ba5aed50
commit b45a4e4ffd
9 changed files with 351 additions and 29 deletions
+117 -4
View File
@@ -25,6 +25,9 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
#ifdef __unix__
# include <sys/wait.h>
#endif
#include "debug.h" #include "debug.h"
#include "uioport.h" #include "uioport.h"
@@ -58,6 +61,7 @@ void unInitRepository(void);
static int debugCmdCat(DebugContext *debugContext, int argc, char *argv[]); static int debugCmdCat(DebugContext *debugContext, int argc, char *argv[]);
static int debugCmdCd(DebugContext *debugContext, int argc, char *argv[]); static int debugCmdCd(DebugContext *debugContext, int argc, char *argv[]);
static int debugCmdExec(DebugContext *debugContext, int argc, char *argv[]);
static int debugCmdExit(DebugContext *debugContext, int argc, char *argv[]); static int debugCmdExit(DebugContext *debugContext, int argc, char *argv[]);
static int debugCmdLs(DebugContext *debugContext, int argc, char *argv[]); static int debugCmdLs(DebugContext *debugContext, int argc, char *argv[]);
static int debugCmdMem(DebugContext *debugContext, int argc, char *argv[]); static int debugCmdMem(DebugContext *debugContext, int argc, char *argv[]);
@@ -87,6 +91,7 @@ debugMountOne(uio_Repository *destRep, const char *mountPoint,
DebugCommand debugCommands[] = { DebugCommand debugCommands[] = {
{ "cat", debugCmdCat }, { "cat", debugCmdCat },
{ "cd", debugCmdCd }, { "cd", debugCmdCd },
{ "exec", debugCmdExec },
{ "exit", debugCmdExit }, { "exit", debugCmdExit },
{ "fwritetest", debugCmdFwriteTest }, { "fwritetest", debugCmdFwriteTest },
{ "ls", debugCmdLs }, { "ls", debugCmdLs },
@@ -294,12 +299,12 @@ makeArgs(char *lineBuf, int *argc, char ***argv) {
numArg = 0; numArg = 0;
ptr = lineBuf; ptr = lineBuf;
while(1) { while(1) {
while (isspace(*ptr)) while (isspace((int) *ptr))
ptr++; ptr++;
if (*ptr == '\0') if (*ptr == '\0')
break; break;
numArg++; numArg++;
while (!isspace(*ptr)) while (!isspace((int) *ptr))
ptr++; ptr++;
} }
@@ -307,13 +312,13 @@ makeArgs(char *lineBuf, int *argc, char ***argv) {
numArg = 0; numArg = 0;
ptr = lineBuf; ptr = lineBuf;
while(1) { while(1) {
while (isspace(*ptr)) while (isspace((int) *ptr))
ptr++; ptr++;
if (*ptr == '\0') if (*ptr == '\0')
break; break;
args[numArg] = ptr; args[numArg] = ptr;
numArg++; numArg++;
while (!isspace(*ptr)) while (!isspace((int) *ptr))
ptr++; ptr++;
if (*ptr == '\0') if (*ptr == '\0')
break; break;
@@ -424,6 +429,114 @@ debugCmdCd(DebugContext *debugContext, int argc, char *argv[]) {
return 0; return 0;
} }
static int
debugCmdExec(DebugContext *debugContext, int argc, char *argv[]) {
int i;
char **newArgs;
int errCode = 0;
if (argc < 2) {
fprintf(debugContext->err, "Invalid number of arguments.\n");
return 1;
}
newArgs = uio_malloc(argc * sizeof (char *));
newArgs[0] = argv[1];
for (i = 2; i < argc; i++) {
int retVal;
uio_FileSystemID fsID;
uio_MountHandle *mountHandle;
retVal = uio_getFileLocation(debugContext->cwd, argv[i], O_RDONLY,
&mountHandle, &newArgs[i - 1]);
if (retVal == -1) {
// No match; we keep what's typed litterally.
newArgs[i - 1] = argv[i];
continue;
}
fsID = uio_getMountFileSystemType(mountHandle);
if (fsID != uio_FSTYPE_STDIO) {
// Wrong file system type.
fprintf(debugContext->err,
"Cannot execute: %s is not in a stdio filesystem.\n",
argv[i]);
errCode = 0;
argc = i + 1;
goto err;
}
}
newArgs[argc - 1] = NULL;
fprintf(debugContext->err, "Executing: %s", newArgs[0]);
for (i = 1; i < argc - 1; i++)
fprintf(debugContext->err, " %s", newArgs[i]);
fprintf(debugContext->err, "\n");
#ifdef __unix__
{
pid_t pid;
pid = fork();
switch (pid) {
case -1:
fprintf(debugContext->err, "Error: fork() failed: %s.\n",
strerror(errno));
break;
case 0:
// child
execvp(newArgs[0], newArgs);
fprintf(debugContext->err, "Error: execvp() failed: %s.\n",
strerror(errno));
_exit(EXIT_FAILURE);
break;
default: {
// parent
int status;
pid_t retVal;
while (1) {
retVal = waitpid(pid, &status, 0);
if (retVal != -1)
break;
if (errno != EINTR) {
fprintf(debugContext->err, "Error: waitpid() "
"failed: %s\n", strerror(errno));
break;
}
}
if (retVal == -1)
break;
if (WIFEXITED(status)) {
fprintf(debugContext->err, "Exit status: %d\n",
WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
fprintf(debugContext->err, "Terminated on signal %d.\n",
WTERMSIG(status));
} else {
fprintf(debugContext->err, "Error: weird exit status.\n");
}
break;
}
}
}
#else
fprintf(debugContext->err, "Cannot execute: not supported on this "
"platform.\n");
#endif
err:
for (i = 1; i < argc; i++) {
if (argv[i] != newArgs[i - 1])
uio_free(newArgs[i - 1]);
}
uio_free(newArgs);
return errCode;
}
static int static int
debugCmdExit(DebugContext *debugContext, int argc, char *argv[]) { debugCmdExit(DebugContext *debugContext, int argc, char *argv[]) {
debugContext->exit = true; debugContext->exit = true;
+5 -1
View File
@@ -36,8 +36,12 @@ 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.
- uio_rename() doesn't work on directories - uio_rename() doesn't work on directories
uio_GetPhysicalAccess() needs to be changed so that it works the same on uio_getPhysicalAccess() needs to be changed so that it works the same on
dirs as on files. stat() can be cleaned up too then. dirs as on files. stat() can be cleaned up too then.
- uio_getPhysicalAccess() will not return ENOENT when (only) the last
component does not exist, even when O_RDONLY is used.
For O_RDRW, O_CREAT should probably be checked too (function description
needs to be updated too then).
Extra features (not necessary for UQM): Extra features (not necessary for UQM):
- Make functions to use for uio_malloc, uio_free and uio_realloc - Make functions to use for uio_malloc, uio_free and uio_realloc
+113 -10
View File
@@ -325,6 +325,11 @@ uio_unmountAllDirs(uio_Repository *repository) {
return 0; return 0;
} }
uio_FileSystemID
uio_getMountFileSystemType(uio_MountHandle *mountHandle) {
return mountHandle->mountInfo->fsID;
}
int int
uio_close(uio_Handle *handle) { uio_close(uio_Handle *handle) {
uio_Handle_unref(handle); uio_Handle_unref(handle);
@@ -340,15 +345,15 @@ uio_rename(uio_DirHandle *oldDir, const char *oldPath,
int retVal; int retVal;
if (uio_getPhysicalAccess(oldDir, oldPath, O_RDONLY, 0, if (uio_getPhysicalAccess(oldDir, oldPath, O_RDONLY, 0,
&oldReadMountInfo, &oldPReadDir, &oldReadMountInfo, &oldPReadDir, NULL,
NULL, NULL, &oldName) == -1) { NULL, NULL, NULL, &oldName) == -1) {
// errno is set // errno is set
return -1; return -1;
} }
if (uio_getPhysicalAccess(newDir, newPath, O_WRONLY | O_CREAT | O_EXCL, if (uio_getPhysicalAccess(newDir, newPath, O_WRONLY | O_CREAT | O_EXCL,
uio_GPA_NOWRITE, &newReadMountInfo, &newPReadDir, uio_GPA_NOWRITE, &newReadMountInfo, &newPReadDir, NULL,
&newWriteMountInfo, &newPWriteDir, &newName) == -1) { &newWriteMountInfo, &newPWriteDir, NULL, &newName) == -1) {
int saveErrno = errno; int saveErrno = errno;
uio_PDirHandle_unref(oldPReadDir); uio_PDirHandle_unref(oldPReadDir);
uio_free(oldName); uio_free(oldName);
@@ -423,8 +428,8 @@ uio_stat(uio_DirHandle *dir, const char *path, struct stat *statBuf) {
int result; int result;
if (uio_getPhysicalAccess(dir, path, O_RDONLY, 0, if (uio_getPhysicalAccess(dir, path, O_RDONLY, 0,
&readMountInfo, &pReadDir, &readMountInfo, &pReadDir, NULL,
NULL, NULL, &name) == -1) { NULL, NULL, NULL, &name) == -1) {
if (uio_statDir(dir, path, statBuf) == -1) { if (uio_statDir(dir, path, statBuf) == -1) {
// errno is set // errno is set
return -1; return -1;
@@ -513,8 +518,8 @@ uio_mkdir(uio_DirHandle *dir, const char *path, mode_t mode) {
uio_PDirHandle *newDirHandle; uio_PDirHandle *newDirHandle;
if (uio_getPhysicalAccess(dir, path, O_WRONLY | O_CREAT | O_EXCL, 0, if (uio_getPhysicalAccess(dir, path, O_WRONLY | O_CREAT | O_EXCL, 0,
&readMountInfo, &pReadDir, &readMountInfo, &pReadDir, NULL,
&writeMountInfo, &pWriteDir, &name) == -1) { &writeMountInfo, &pWriteDir, NULL, &name) == -1) {
// errno is set // errno is set
if (errno == EISDIR) if (errno == EISDIR)
errno = EEXIST; errno = EEXIST;
@@ -552,8 +557,8 @@ uio_open(uio_DirHandle *dir, const char *path, int flags, mode_t mode) {
uio_Handle *handle; uio_Handle *handle;
if (uio_getPhysicalAccess(dir, path, flags, 0, if (uio_getPhysicalAccess(dir, path, flags, 0,
&readMountInfo, &readPDirHandle, &readMountInfo, &readPDirHandle, NULL,
&writeMountInfo, &writePDirHandle, &name) == -1) { &writeMountInfo, &writePDirHandle, NULL, &name) == -1) {
// errno is set // errno is set
return NULL; return NULL;
} }
@@ -880,6 +885,104 @@ err:
} }
} }
// inPath and *outPath may point to the same location
int
uio_getFileLocation(uio_DirHandle *dir, const char *inPath,
int flags, uio_MountHandle **mountHandle, char **outPath) {
uio_PDirHandle *readPDirHandle, *writePDirHandle;
uio_MountInfo *readMountInfo, *writeMountInfo, *mountInfo;
char *name;
char *readPRootPath, *writePRootPath, *pRootPath;
if (uio_getPhysicalAccess(dir, inPath, flags, 0,
&readMountInfo, &readPDirHandle, &readPRootPath,
&writeMountInfo, &writePDirHandle, &writePRootPath,
&name) == -1) {
// errno is set
return -1;
}
// TODO: This code is partly the same as the code in uio_open().
// probably some code could be put in a seperate function.
if ((flags & O_ACCMODE) == O_RDONLY) {
// WritePDirHandle is not filled in.
uio_PDirHandle_unref(readPDirHandle);
pRootPath = readPRootPath;
mountInfo = readMountInfo;
} else if (readPDirHandle == writePDirHandle) {
// In general, the dirs can be the same even when the handles are
// not the same. But here it works, because uio_getPhysicalAccess
// guarantees it.
uio_PDirHandle_unref(readPDirHandle);
uio_PDirHandle_unref(writePDirHandle);
pRootPath = readPRootPath;
mountInfo = readMountInfo;
uio_free(writePRootPath);
} else {
// need to write
uio_PDirEntryHandle *entry;
entry = uio_getPDirEntryHandle(readPDirHandle, name);
if (entry != NULL) {
// file already exists
uio_PDirEntryHandle_unref(entry);
if ((flags & O_CREAT) == O_CREAT &&
(flags & O_EXCL) == O_EXCL) {
uio_free(name);
uio_PDirHandle_unref(readPDirHandle);
uio_free(readPRootPath);
uio_PDirHandle_unref(writePDirHandle);
uio_free(writePRootPath);
errno = EEXIST;
return -1;
}
if ((flags & O_TRUNC) == O_TRUNC) {
// No use copying the file to the writable dir.
// As it doesn't exists there, O_TRUNC needs to be turned off
// though.
flags &= ~O_TRUNC;
} else {
// file needs to be copied
if (uio_copyFilePhysical(readPDirHandle, name, writePDirHandle,
name) == -1) {
int saveErrno = errno;
uio_free(name);
uio_PDirHandle_unref(readPDirHandle);
uio_free(readPRootPath);
uio_PDirHandle_unref(writePDirHandle);
uio_free(writePRootPath);
errno = saveErrno;
return -1;
}
}
} else {
// file does not exist
if (((flags & O_ACCMODE) == O_RDONLY) ||
(flags & O_CREAT) != O_CREAT) {
uio_free(name);
uio_PDirHandle_unref(readPDirHandle);
uio_free(readPRootPath);
uio_PDirHandle_unref(writePDirHandle);
uio_free(writePRootPath);
errno = ENOENT;
return -1;
}
}
uio_PDirHandle_unref(readPDirHandle);
uio_PDirHandle_unref(writePDirHandle);
pRootPath = writePRootPath;
mountInfo = writeMountInfo;
uio_free(readPRootPath);
}
uio_free(name);
*mountHandle = mountInfo->mountHandle;
*outPath = pRootPath;
return 0;
}
// *** begin dirList stuff *** // // *** begin dirList stuff *** //
#define uio_DIR_BUFFER_SIZE 2048 #define uio_DIR_BUFFER_SIZE 2048
+6
View File
@@ -87,6 +87,9 @@ int uio_unmountDir(uio_MountHandle *mountHandle);
// Unmount all previously mounted dirs. // Unmount all previously mounted dirs.
int uio_unmountAllDirs(uio_Repository *repository); int uio_unmountAllDirs(uio_Repository *repository);
// Get the filesystem identifier for a mounted directory.
uio_FileSystemID uio_getMountFileSystemType(uio_MountHandle *mountHandle);
// Open a file // Open a file
uio_Handle *uio_open(uio_DirHandle *dir, const char *file, int flags, uio_Handle *uio_open(uio_DirHandle *dir, const char *file, int flags,
mode_t mode); mode_t mode);
@@ -115,6 +118,9 @@ ssize_t uio_write(uio_Handle *handle, const void *buf, size_t count);
int uio_unlink(uio_DirHandle *dirHandle, const char *path); int uio_unlink(uio_DirHandle *dirHandle, const char *path);
int uio_getFileLocation(uio_DirHandle *dir, const char *inPath,
int flags, uio_MountHandle **mountHandle, char **outPath);
// Get a directory handle. // Get a directory handle.
uio_DirHandle *uio_openDir(uio_Repository *repository, const char *path, uio_DirHandle *uio_openDir(uio_Repository *repository, const char *path,
int flags); int flags);
+46 -10
View File
@@ -260,26 +260,38 @@ copyError(int error,
* extraFlags - either 0 or uio_GPA_NOWRITE * extraFlags - either 0 or uio_GPA_NOWRITE
* When 0, the path will be created if it doesn't * When 0, the path will be created if it doesn't
* exist in the writing location, but does exist * exist in the writing location, but does exist
* in the reading location. With uio_GPA_NOWRITE, it * in the reading location. With uio_GPA_NOWRITE, it
* won't be created, and -1 will be returned and errno * won't be created, and -1 will be returned and errno
* will be set to ENOENT. * will be set to ENOENT.
* mountInfoReadPtr - pointer to location where the pointer * mountInfoReadPtr - pointer to location where the pointer
* to the MountInfo structure for the reading location * to the MountInfo structure for the reading location
* should be stored. * should be stored.
* readPDirHandlePtr - pointer to the location where the pointer * readPDirHandlePtr - pointer to the location where the pointer
* to the PDirHandle used for reading should be stored. * to the PDirHandle used for reading should be stored.
* readPRootPath - pointer to the location where the pointer
* to the physical path to the reading location
* is to be stored.
* The caller is responsible for freeing this.
* Ignored if NULL.
* mountInfoWritePtr - pointer to location where the pointer * mountInfoWritePtr - pointer to location where the pointer
* to the MountInfo structure for the writing location * to the MountInfo structure for the writing location
* should be stored. * should be stored.
* writePDirHandlePtr - pointer to the location where the pointer * writePDirHandlePtr - pointer to the location where the pointer
* to the PDirHandle used for writing should be stored. * to the PDirHandle used for writing should be stored.
* NULL if O_RDONLY was specified. * NULL if O_RDONLY was specified.
* If this is the same dir as the one refered * If this is the same dir as the one refered
* to by readPDirHandlePtr, the handles will be the * to by readPDirHandlePtr, the handles will be the
* same too. * same too.
* restPtr - pointer to a newly created string with as contents * writePRootPath - pointer to the location where the pointer
* the last component of 'path'. * to the physical path to the writing location
* is to be stored.
* The caller is responsible for freeing this. * The caller is responsible for freeing this.
* Ignored if NULL.
* restPtr - pointer to the location where a newly created
* string with as contents the last component of 'path'
* is to be stored.
* The caller is responsible for freeing this.
* Ignored if NULL.
* Returns: 0 - success * Returns: 0 - success
* -1 - failure (errno set) * -1 - failure (errno set)
* NB: This is the function that would most benefit from * NB: This is the function that would most benefit from
@@ -291,10 +303,13 @@ int
uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
int flags, int extraFlags, int flags, int extraFlags,
uio_MountInfo **mountInfoReadPtr, uio_PDirHandle **readPDirHandlePtr, uio_MountInfo **mountInfoReadPtr, uio_PDirHandle **readPDirHandlePtr,
char **readPRootPathPtr,
uio_MountInfo **mountInfoWritePtr, uio_PDirHandle **writePDirHandlePtr, uio_MountInfo **mountInfoWritePtr, uio_PDirHandle **writePDirHandlePtr,
char **writePRootPathPtr,
char **restPtr) { char **restPtr) {
char *fullPath; // path from dirHandle with 'path' added char *fullPath; // path from dirHandle with 'path' added
const char *pRootPath; // path from the pRoot of a physical tree const char *pRootPath; // path from the pRoot of a physical tree
const char *readPRootPath, *writePRootPath;
const char *rest, *readRest; const char *rest, *readRest;
uio_MountTree *tree; uio_MountTree *tree;
uio_MountTreeItem *item; uio_MountTreeItem *item;
@@ -317,8 +332,10 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
readItem = NULL; readItem = NULL;
readPDirHandle = NULL; readPDirHandle = NULL;
readPRootPath = NULL;
writeItem = NULL; writeItem = NULL;
writePDirHandle = NULL; writePDirHandle = NULL;
writePRootPath = NULL;
readRest = NULL; readRest = NULL;
// Satisfy compiler. // Satisfy compiler.
entryExists = false; entryExists = false;
@@ -356,6 +373,7 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
if (readPDirHandle != NULL) if (readPDirHandle != NULL)
uio_PDirHandle_unref(readPDirHandle); uio_PDirHandle_unref(readPDirHandle);
readPDirHandle = pDirHandle; readPDirHandle = pDirHandle;
readPRootPath = pRootPath;
readRest = rest; readRest = rest;
entryExists = true; entryExists = true;
break; break;
@@ -365,6 +383,7 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
readItem = item; readItem = item;
assert(readPDirHandle == NULL); assert(readPDirHandle == NULL);
readPDirHandle = pDirHandle; readPDirHandle = pDirHandle;
readPRootPath = pRootPath;
readRest = rest; readRest = rest;
continue; continue;
} }
@@ -399,6 +418,9 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
// write access is not needed // write access is not needed
*mountInfoReadPtr = readItem->mountInfo; *mountInfoReadPtr = readItem->mountInfo;
*readPDirHandlePtr = readPDirHandle; *readPDirHandlePtr = readPDirHandle;
if (readPRootPathPtr != NULL)
*readPRootPathPtr = joinPathsAbsolute(
readItem->mountInfo->dirName, readPRootPath);
// Don't touch mountInfoWritePtr and writePDirHandlePtr. // Don't touch mountInfoWritePtr and writePDirHandlePtr.
// they'd be NULL. // they'd be NULL.
*restPtr = uio_strdup(readRest); *restPtr = uio_strdup(readRest);
@@ -419,13 +441,20 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
// The read directory is usable as write directory too. // The read directory is usable as write directory too.
*mountInfoReadPtr = readItem->mountInfo; *mountInfoReadPtr = readItem->mountInfo;
*readPDirHandlePtr = readPDirHandle; *readPDirHandlePtr = readPDirHandle;
if (readPRootPathPtr != NULL)
*readPRootPathPtr = joinPathsAbsolute(
readItem->mountInfo->dirName, readPRootPath);
*mountInfoWritePtr = writeItem->mountInfo; *mountInfoWritePtr = writeItem->mountInfo;
// writeItem == readItem // writeItem == readItem
uio_PDirHandle_ref(readPDirHandle); uio_PDirHandle_ref(readPDirHandle);
*writePDirHandlePtr = readPDirHandle; *writePDirHandlePtr = readPDirHandle;
// No copy&paste error, the read PDirHandle is the write // No copy&paste error, the read PDirHandle is the write
// pDirHandle too. // pDirHandle too.
*restPtr = uio_strdup(readRest); if (writePRootPathPtr != NULL)
*writePRootPathPtr = joinPathsAbsolute(
writeItem->mountInfo->dirName, writePRootPath);
if (restPtr != NULL)
*restPtr = uio_strdup(readRest);
uio_free(fullPath); uio_free(fullPath);
return 0; return 0;
} }
@@ -490,9 +519,16 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
*mountInfoReadPtr = readItem->mountInfo; *mountInfoReadPtr = readItem->mountInfo;
*readPDirHandlePtr = readPDirHandle; *readPDirHandlePtr = readPDirHandle;
if (readPRootPathPtr != NULL)
*readPRootPathPtr = joinPathsAbsolute(
readItem->mountInfo->dirName, readPRootPath);
*mountInfoReadPtr = writeItem->mountInfo; *mountInfoReadPtr = writeItem->mountInfo;
*writePDirHandlePtr = writePDirHandle; *writePDirHandlePtr = writePDirHandle;
*restPtr = uio_strdup(rest); if (writePRootPathPtr != NULL)
*writePRootPathPtr = joinPathsAbsolute(
writeItem->mountInfo->dirName, writePRootPath);
if (restPtr != NULL)
*restPtr = uio_strdup(rest);
uio_free(fullPath); uio_free(fullPath);
return 0; return 0;
} }
+6 -3
View File
@@ -33,9 +33,12 @@ uio_PDirHandle *uio_makePath(uio_PDirHandle *pDirHandle, const char *path,
int uio_copyFilePhysical(uio_PDirHandle *fromDir, const char *fromName, int uio_copyFilePhysical(uio_PDirHandle *fromDir, const char *fromName,
uio_PDirHandle *toDir, const char *toName); uio_PDirHandle *toDir, const char *toName);
int uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, int uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
int flags, int extraFlags, uio_MountInfo **mountInfoReadPtr, int flags, int extraFlags,
uio_PDirHandle **readPDirHandlePtr, uio_MountInfo **mountInfoWritePtr, uio_MountInfo **mountInfoReadPtr, uio_PDirHandle **readPDirHandlePtr,
uio_PDirHandle **writePDirHandlePtr, char **restPtr); char **readPRootPathPtr,
uio_MountInfo **mountInfoWritePtr, uio_PDirHandle **writePDirHandlePtr,
char **writePRootPathPtr,
char **restPtr);
#define uio_GPA_NOWRITE 1 #define uio_GPA_NOWRITE 1
int uio_getPathPhysicalDirs(uio_DirHandle *dirHandle, const char *path, int uio_getPathPhysicalDirs(uio_DirHandle *dirHandle, const char *path,
size_t pathLen, uio_PDirHandle ***resPDirHandles, size_t pathLen, uio_PDirHandle ***resPDirHandles,
+47
View File
@@ -142,10 +142,17 @@ getPreviousPathComponent(const char *dir,
(*startComp)--; (*startComp)--;
} }
// Combine two parts of a paths into a new path.
// The new path starts with a '/' only when the first part does.
// The first path may (but doesn't have to) end on a '/', or may be empty.
// Pre: the second path doesn't start with a '/'
char * char *
joinPaths(const char *first, const char *second) { joinPaths(const char *first, const char *second) {
char *result, *resPtr; char *result, *resPtr;
size_t firstLen, secondLen; size_t firstLen, secondLen;
if (first[0] == '\0')
return uio_strdup(second);
firstLen = strlen(first); firstLen = strlen(first);
if (first[firstLen - 1] == '/') if (first[firstLen - 1] == '/')
@@ -167,6 +174,46 @@ joinPaths(const char *first, const char *second) {
return result; return result;
} }
// Combine two parts of a paths into a new path,
// The new path will always start with a '/'.
// The first path may (but doesn't have to) end on a '/', or may be empty.
// Pre: the second path doesn't start with a '/'
char *
joinPathsAbsolute(const char *first, const char *second) {
char *result, *resPtr;
size_t firstLen, secondLen;
if (first[0] == '\0') {
secondLen = strlen(second);
result = uio_malloc(secondLen + 2);
result[0] = '/';
memcpy(&result[1], second, secondLen);
return result;
}
firstLen = strlen(first);
if (first[firstLen - 1] == '/')
firstLen--;
secondLen = strlen(second);
result = uio_malloc(firstLen + secondLen + 3);
resPtr = result;
*resPtr = '/';
resPtr++;
memcpy(resPtr, first, firstLen);
resPtr += firstLen;
*resPtr = '/';
resPtr++;
memcpy(resPtr, second, secondLen);
resPtr += secondLen;
*resPtr = '\0';
return result;
}
uio_bool uio_bool
validPathName(const char *path, size_t len) { validPathName(const char *path, size_t len) {
const char *pathEnd; const char *pathEnd;
+1
View File
@@ -39,6 +39,7 @@ void getPreviousPathComponent(const char *dir, const char **startComp,
const char **endComp); const char **endComp);
#define getPreviousPath0Component getPreviousPathComponent #define getPreviousPath0Component getPreviousPathComponent
char *joinPaths(const char *first, const char *second); char *joinPaths(const char *first, const char *second);
char *joinPathsAbsolute(const char *first, const char *second);
uio_bool validPathName(const char *path, size_t len); uio_bool validPathName(const char *path, size_t len);
+10 -1
View File
@@ -579,7 +579,16 @@ zip_mount(uio_Handle *handle, int flags) {
handle, NULL, uio_GPDir_COMPLETE); handle, NULL, uio_GPDir_COMPLETE);
rootDirHandle = uio_PRoot_getRootDirHandle(result); rootDirHandle = uio_PRoot_getRootDirHandle(result);
zip_fillDirStructure(rootDirHandle->extra, handle); if (zip_fillDirStructure(rootDirHandle->extra, handle) == -1) {
int saveErrno = errno;
#ifdef DEBUG
fprintf(stderr, "Error: failed to read the zip directory "
"structure - %d.\n", errno);
#endif
uio_GPRoot_umount(result);
errno = saveErrno;
return NULL;
}
return result; return result;
} }