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:
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -268,6 +268,11 @@ copyError(int error,
|
|||||||
* 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.
|
||||||
@@ -277,9 +282,16 @@ copyError(int error,
|
|||||||
* 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,12 +441,19 @@ 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.
|
||||||
|
if (writePRootPathPtr != NULL)
|
||||||
|
*writePRootPathPtr = joinPathsAbsolute(
|
||||||
|
writeItem->mountInfo->dirName, writePRootPath);
|
||||||
|
if (restPtr != NULL)
|
||||||
*restPtr = uio_strdup(readRest);
|
*restPtr = uio_strdup(readRest);
|
||||||
uio_free(fullPath);
|
uio_free(fullPath);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -490,8 +519,15 @@ 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;
|
||||||
|
if (writePRootPathPtr != NULL)
|
||||||
|
*writePRootPathPtr = joinPathsAbsolute(
|
||||||
|
writeItem->mountInfo->dirName, writePRootPath);
|
||||||
|
if (restPtr != NULL)
|
||||||
*restPtr = uio_strdup(rest);
|
*restPtr = uio_strdup(rest);
|
||||||
uio_free(fullPath);
|
uio_free(fullPath);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -142,11 +142,18 @@ 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] == '/')
|
||||||
firstLen--;
|
firstLen--;
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user