Support for stdio file access through temporary files.
Added relevant functions:
uio_StdioAccessHandle *uio_getStdioAccess(uio_DirHandle *dir,
const char *path, int flags, uio_DirHandle *tempDir);
const char *uio_StdioAccessHandle_getPath(uio_StdioAccessHandle *handle);
void uio_releaseStdioAccess(uio_StdioAccessHandle *handle);
These are made available by including "uioutils.h" in addition to "uio.h".
An other function that's available through uioutils is
int uio_copyFile(uio_DirHandle *srcDir, const char *srcName,
uio_DirHandle *dstDir, const char *newName);
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1288 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
uqm_SUBDIRS="stdio"
|
||||
uqm_CFILES="charhashtable.c defaultfs.c fileblock.c fstypes.c
|
||||
gphys.c hashtable.c io.c ioaux.c match.c mount.c
|
||||
mounttree.c paths.c physical.c uiostream.c uioutils.c"
|
||||
mounttree.c paths.c physical.c uiostream.c uioutils.c
|
||||
utils.c"
|
||||
|
||||
if [ -n "$uqm_USE_ZIP_IO" ]; then
|
||||
uqm_SUBDIRS="$uqm_SUBDIRS zip"
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "debug.h"
|
||||
#include "uioport.h"
|
||||
#include "io.h"
|
||||
#include "utils.h"
|
||||
#include "types.h"
|
||||
#include "mem.h"
|
||||
#include "uioutils.h"
|
||||
@@ -134,11 +135,11 @@ debugMountOne(uio_Repository *destRep, const char *mountPoint,
|
||||
mountHandle = uio_mountDir(destRep, mountPoint, fsType, sourceDir,
|
||||
sourcePath, inPath, autoMount, flags, relative);
|
||||
if (mountHandle == NULL) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
fprintf(stderr, "Could not mount '%s' and graft '%s' from that "
|
||||
"into the repository at '%s': %s\n",
|
||||
sourcePath, inPath, mountPoint, strerror(errno));
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
}
|
||||
return mountHandle;
|
||||
}
|
||||
@@ -213,9 +214,15 @@ initRepository(void) {
|
||||
uio_closeDir(rootDir);
|
||||
}
|
||||
}
|
||||
mountHandles[8] = debugMountOne(repository, "/tmp/",
|
||||
uio_FSTYPE_STDIO, NULL, NULL, "/tmp/", autoMount,
|
||||
uio_MOUNT_TOP, NULL);
|
||||
|
||||
#if 1
|
||||
mountHandles[8] = debugMountOne(repository, "/root/root/",
|
||||
uio_FSTYPE_STDIO, NULL, NULL, "/", autoMount,
|
||||
uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -432,40 +439,55 @@ debugCmdCd(DebugContext *debugContext, int argc, char *argv[]) {
|
||||
static int
|
||||
debugCmdExec(DebugContext *debugContext, int argc, char *argv[]) {
|
||||
int i;
|
||||
char **newArgs;
|
||||
const char **newArgs;
|
||||
int errCode = 0;
|
||||
uio_StdioAccessHandle **handles;
|
||||
uio_DirHandle *tempDir;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(debugContext->err, "Invalid number of arguments.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempDir = uio_openDirRelative(debugContext->cwd, "/tmp", 0);
|
||||
if (tempDir == 0) {
|
||||
fprintf(debugContext->err, "Could not open temp dir: %s.\n",
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
newArgs = uio_malloc(argc * sizeof (char *));
|
||||
newArgs[0] = argv[1];
|
||||
handles = uio_malloc(argc * sizeof (uio_StdioAccessHandle *));
|
||||
handles[0] = NULL;
|
||||
|
||||
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.
|
||||
#if 0
|
||||
if (argv[i][0] == '-') {
|
||||
// Don't try to parse arguments that start with '-'.
|
||||
// They are probably option flags.
|
||||
newArgs[i - 1] = argv[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
fsID = uio_getMountFileSystemType(mountHandle);
|
||||
if (fsID != uio_FSTYPE_STDIO) {
|
||||
// Wrong file system type.
|
||||
#endif
|
||||
handles[i - 1] = uio_getStdioAccess(debugContext->cwd, argv[i],
|
||||
O_RDONLY, tempDir);
|
||||
if (handles[i - 1] == NULL) {
|
||||
if (errno == ENOENT) {
|
||||
// No match; we keep what's typed litterally.
|
||||
newArgs[i - 1] = argv[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
// error
|
||||
fprintf(debugContext->err,
|
||||
"Cannot execute: %s is not in a stdio filesystem.\n",
|
||||
argv[i]);
|
||||
errCode = 0;
|
||||
"Cannot execute: Cannot get stdio access to %s: %s.\n",
|
||||
argv[i], strerror(errno));
|
||||
errCode = 1;
|
||||
argc = i + 1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
newArgs[i - 1] = uio_StdioAccessHandle_getPath(handles[i - 1]);
|
||||
}
|
||||
newArgs[argc - 1] = NULL;
|
||||
|
||||
@@ -486,7 +508,7 @@ debugCmdExec(DebugContext *debugContext, int argc, char *argv[]) {
|
||||
break;
|
||||
case 0:
|
||||
// child
|
||||
execvp(newArgs[0], newArgs);
|
||||
execvp(newArgs[0], (char * const *) newArgs);
|
||||
fprintf(debugContext->err, "Error: execvp() failed: %s.\n",
|
||||
strerror(errno));
|
||||
_exit(EXIT_FAILURE);
|
||||
@@ -528,11 +550,13 @@ debugCmdExec(DebugContext *debugContext, int argc, char *argv[]) {
|
||||
#endif
|
||||
|
||||
err:
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i] != newArgs[i - 1])
|
||||
uio_free(newArgs[i - 1]);
|
||||
for (i = 1; i < argc - 1; i++) {
|
||||
if (handles[i] != NULL)
|
||||
uio_releaseStdioAccess(handles[i]);
|
||||
}
|
||||
uio_free(handles);
|
||||
uio_free(newArgs);
|
||||
uio_closeDir(tempDir);
|
||||
|
||||
return errCode;
|
||||
}
|
||||
@@ -822,11 +846,11 @@ debugCmdStat(DebugContext *debugContext, int argc, char *argv[]) {
|
||||
|
||||
if (uio_stat(debugContext->cwd, argv[1], &statBuf) == -1) {
|
||||
// errno is set
|
||||
int saveErrno;
|
||||
saveErrno = errno;
|
||||
int savedErrno;
|
||||
savedErrno = errno;
|
||||
fprintf(debugContext->err, "Could not stat file: %s\n",
|
||||
strerror(errno));
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Needed before use in UQM:
|
||||
- documentation
|
||||
- configuring for HAVE_REGEX and GLOB
|
||||
- when doing uio_getStdioPhysical(), if write access is required, but
|
||||
not available on the original location, also copy the file to the
|
||||
temporary dir.
|
||||
|
||||
Documentation:
|
||||
- use doxygen
|
||||
@@ -35,6 +38,7 @@ Bugs:
|
||||
- uio_Stream file might get unaligned (not sure).
|
||||
- 'openDir(repository, "dir/")' will have the trailing '/'
|
||||
in the dirHandle, which will cause problems.
|
||||
- 'openDirRelative(repository, "/")' causes segfaults lateron
|
||||
- uio_rename() doesn't work on directories
|
||||
uio_getPhysicalAccess() needs to be changed so that it works the same on
|
||||
dirs as on files. stat() can be cleaned up too then.
|
||||
|
||||
@@ -51,9 +51,9 @@ static inline void uio_PDirHandle_free(uio_PDirHandle *pDirHandle);
|
||||
static inline uio_PFileHandle *uio_PFileHandle_alloc(void);
|
||||
static inline void uio_PFileHandle_free(uio_PFileHandle *pFileHandle);
|
||||
|
||||
static uio_DirHandle *uio_newDirHandle(uio_Repository *repository, char *path,
|
||||
static uio_DirHandle *uio_DirHandle_new(uio_Repository *repository, char *path,
|
||||
char *rootEnd);
|
||||
static inline uio_DirHandle *uio_allocDirHandle(void);
|
||||
static inline uio_DirHandle *uio_DirHandle_alloc(void);
|
||||
static inline void uio_DirHandle_free(uio_DirHandle *dirHandle);
|
||||
|
||||
static inline uio_Handle *uio_Handle_alloc(void);
|
||||
@@ -354,10 +354,10 @@ uio_rename(uio_DirHandle *oldDir, const char *oldPath,
|
||||
if (uio_getPhysicalAccess(newDir, newPath, O_WRONLY | O_CREAT | O_EXCL,
|
||||
uio_GPA_NOWRITE, &newReadMountInfo, &newPReadDir, NULL,
|
||||
&newWriteMountInfo, &newPWriteDir, NULL, &newName) == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_PDirHandle_unref(oldPReadDir);
|
||||
uio_free(oldName);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -393,13 +393,13 @@ uio_rename(uio_DirHandle *oldDir, const char *oldPath,
|
||||
retVal = oldReadMountInfo->pDirHandle->pRoot->handler->rename(
|
||||
oldPReadDir, oldName, newPReadDir, newName);
|
||||
if (retVal == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_PDirHandle_unref(oldPReadDir);
|
||||
uio_PDirHandle_unref(newPReadDir);
|
||||
uio_PDirHandle_unref(newPWriteDir);
|
||||
uio_free(oldName);
|
||||
uio_free(newName);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -469,9 +469,9 @@ uio_statDir(uio_DirHandle *dirHandle, const char *path,
|
||||
}
|
||||
|
||||
if (uio_statOneDir(pDirHandles[0], statBuf) == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
// TODO: atm, fstat'ing a dir will show the info for the topmost
|
||||
@@ -484,9 +484,9 @@ uio_statDir(uio_DirHandle *dirHandle, const char *path,
|
||||
|
||||
if (statOneDir(pDirHandles[i], &statOne) == -1) {
|
||||
// errno is set
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -536,10 +536,10 @@ uio_mkdir(uio_DirHandle *dir, const char *path, mode_t mode) {
|
||||
|
||||
newDirHandle = pWriteDir->pRoot->handler->mkdir(pWriteDir, name, mode);
|
||||
if (newDirHandle == NULL) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(name);
|
||||
uio_PDirHandle_unref(pWriteDir);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -597,11 +597,11 @@ uio_open(uio_DirHandle *dir, const char *path, int flags, mode_t mode) {
|
||||
// file needs to be copied
|
||||
if (uio_copyFilePhysical(readPDirHandle, name, writePDirHandle,
|
||||
name) == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(name);
|
||||
uio_PDirHandle_unref(readPDirHandle);
|
||||
uio_PDirHandle_unref(writePDirHandle);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -623,10 +623,10 @@ uio_open(uio_DirHandle *dir, const char *path, int flags, mode_t mode) {
|
||||
handle = pDirHandle->pRoot->handler->open(pDirHandle, name, flags, mode);
|
||||
// Also adds a new entry to the physical dir if appropriate.
|
||||
if (handle == NULL) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(name);
|
||||
uio_PDirHandle_unref(pDirHandle);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -640,14 +640,17 @@ uio_openDir(uio_Repository *repository, const char *path, int flags) {
|
||||
uio_DirHandle *dirHandle;
|
||||
const char * const rootStr = "/";
|
||||
|
||||
dirHandle = uio_newDirHandle(repository,
|
||||
dirHandle = uio_DirHandle_new(repository,
|
||||
unconst(rootStr), unconst(rootStr));
|
||||
// dirHandle->path will be replaced before uio_openDir()
|
||||
// exits()
|
||||
if (uio_verifyPath(dirHandle, path, &dirHandle->path) == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_DirHandle_free(dirHandle);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
// dirHandle->path is no longer equal to 'path' at this point.
|
||||
// TODO: increase ref in repository?
|
||||
dirHandle->rootEnd = dirHandle->path;
|
||||
if (flags & uio_OD_ROOT)
|
||||
@@ -665,12 +668,12 @@ uio_openDirRelative(uio_DirHandle *base, const char *path, int flags) {
|
||||
return NULL;
|
||||
}
|
||||
if (flags & uio_OD_ROOT) {
|
||||
dirHandle = uio_newDirHandle(base->repository,
|
||||
dirHandle = uio_DirHandle_new(base->repository,
|
||||
newPath, newPath + strlen(newPath));
|
||||
// TODO: increase ref in base->repository?
|
||||
} else {
|
||||
// use the root of the base dir
|
||||
dirHandle = uio_newDirHandle(base->repository,
|
||||
dirHandle = uio_DirHandle_new(base->repository,
|
||||
newPath, newPath + (base->rootEnd - base->path));
|
||||
}
|
||||
return dirHandle;
|
||||
@@ -678,8 +681,7 @@ uio_openDirRelative(uio_DirHandle *base, const char *path, int flags) {
|
||||
|
||||
int
|
||||
uio_closeDir(uio_DirHandle *dirHandle) {
|
||||
uio_free(dirHandle->path);
|
||||
uio_DirHandle_free(dirHandle);
|
||||
uio_DirHandle_unref(dirHandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -765,12 +767,12 @@ uio_rmdir(uio_DirHandle *dirHandle, const char *path) {
|
||||
|
||||
err:
|
||||
{
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
|
||||
uio_free(items);
|
||||
if (entry != NULL)
|
||||
uio_PDirEntryHandle_unref(entry);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -875,12 +877,12 @@ uio_unlink(uio_DirHandle *dirHandle, const char *path) {
|
||||
|
||||
err:
|
||||
{
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
|
||||
uio_free(items);
|
||||
if (entry != NULL)
|
||||
uio_PDirEntryHandle_unref(entry);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -945,13 +947,13 @@ uio_getFileLocation(uio_DirHandle *dir, const char *inPath,
|
||||
// file needs to be copied
|
||||
if (uio_copyFilePhysical(readPDirHandle, name, writePDirHandle,
|
||||
name) == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(name);
|
||||
uio_PDirHandle_unref(readPDirHandle);
|
||||
uio_free(readPRootPath);
|
||||
uio_PDirHandle_unref(writePDirHandle);
|
||||
uio_free(writePRootPath);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1054,16 +1056,16 @@ uio_getDirList(uio_DirHandle *dirHandle, const char *path, const char *pattern,
|
||||
matchType);
|
||||
|
||||
{
|
||||
int saveErrno;
|
||||
saveErrno = errno;
|
||||
int savedErrno;
|
||||
savedErrno = errno;
|
||||
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Names and newNames may point to the same location.
|
||||
// &numNames and numNewNames may point to the same location.
|
||||
// numNewNames may point to &numNames.
|
||||
static void
|
||||
uio_filterDoubleNames(const char * const *names, int numNames,
|
||||
const char **newNames, int *numNewNames) {
|
||||
@@ -1538,19 +1540,27 @@ uio_Handle_free(uio_Handle *handle) {
|
||||
uio_free(handle);
|
||||
}
|
||||
|
||||
// ref count set to 1
|
||||
static uio_DirHandle *
|
||||
uio_newDirHandle(uio_Repository *repository, char *path, char *rootEnd) {
|
||||
uio_DirHandle_new(uio_Repository *repository, char *path, char *rootEnd) {
|
||||
uio_DirHandle *result;
|
||||
|
||||
result = uio_allocDirHandle();
|
||||
result = uio_DirHandle_alloc();
|
||||
result->ref = 1;
|
||||
result->repository = repository;
|
||||
result->path = path;
|
||||
result->rootEnd = rootEnd;
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
uio_DirHandle_delete(uio_DirHandle *dirHandle) {
|
||||
uio_free(dirHandle->path);
|
||||
uio_DirHandle_free(dirHandle);
|
||||
}
|
||||
|
||||
static inline uio_DirHandle *
|
||||
uio_allocDirHandle(void) {
|
||||
uio_DirHandle_alloc(void) {
|
||||
uio_DirHandle *result = uio_malloc(sizeof (uio_DirHandle));
|
||||
#ifdef uio_MEM_DEBUG
|
||||
uio_MemDebug_debugAlloc(uio_DirHandle, (void *) result);
|
||||
|
||||
@@ -124,9 +124,9 @@ uio_makePath(uio_PDirHandle *pDirHandle, const char *path, size_t pathLen,
|
||||
|
||||
newPDirHandle = mkdirFun(pDirHandle, buf, mode);
|
||||
if (newPDirHandle == NULL) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_PDirHandle_unref(pDirHandle);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
uio_PDirHandle_unref(pDirHandle);
|
||||
@@ -366,8 +366,8 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
|
||||
// component is present in this dir.
|
||||
entry = uio_getPDirEntryHandle(pDirHandle, rest);
|
||||
if (entry != NULL) {
|
||||
// Entry is not a dir, as otherwise uio_getPDirEntryHandle
|
||||
// wouldn't have stopped where it did.
|
||||
// 'rest' exists, and it is not a dir, as otherwise
|
||||
// uio_getPDirEntryHandle wouldn't have stopped where it did.
|
||||
uio_PDirEntryHandle_unref(entry);
|
||||
readItem = item;
|
||||
if (readPDirHandle != NULL)
|
||||
@@ -378,7 +378,9 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
|
||||
entryExists = true;
|
||||
break;
|
||||
} else {
|
||||
if (readItem == NULL) {
|
||||
// 'rest' doesn't exist
|
||||
// We're only interested in this dir if we want to write too.
|
||||
if (((flags & O_ACCMODE) != O_RDONLY) && readItem == NULL) {
|
||||
// Keep the first one.
|
||||
readItem = item;
|
||||
assert(readPDirHandle == NULL);
|
||||
@@ -490,17 +492,17 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
|
||||
writePDirHandle = uio_makePath(writeItem->mountInfo->pDirHandle,
|
||||
pRootPath, rest - pRootPath, 0777);
|
||||
if (writePDirHandle == NULL) {
|
||||
int saveErrno;
|
||||
int savedErrno;
|
||||
if (errno == ENOSYS) {
|
||||
// mkdir not supported. We want to report that we failed
|
||||
// because of an error in the underlying layer.
|
||||
// EIO sounds like the best choice.
|
||||
errno = EIO;
|
||||
}
|
||||
saveErrno = errno;
|
||||
savedErrno = errno;
|
||||
uio_PDirHandle_unref(readPDirHandle);
|
||||
uio_free(fullPath);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
rest++; // skip the '/'
|
||||
|
||||
@@ -50,6 +50,7 @@ struct uio_Handle {
|
||||
};
|
||||
|
||||
struct uio_DirHandle {
|
||||
int ref;
|
||||
struct uio_Repository *repository;
|
||||
char *path;
|
||||
// does not contain any '.' or '..'
|
||||
@@ -102,6 +103,7 @@ struct uio_EntriesContext {
|
||||
uio_Handle *uio_Handle_new(uio_PRoot *root, uio_NativeHandle native,
|
||||
int openFlags);
|
||||
void uio_Handle_delete(uio_Handle *handle);
|
||||
void uio_DirHandle_delete(uio_DirHandle *dirHandle);
|
||||
|
||||
uio_PDirEntryHandle *uio_getPDirEntryHandle(
|
||||
const uio_PDirHandle *dirHandle, const char *name);
|
||||
@@ -130,6 +132,19 @@ uio_Handle_unref(uio_Handle *handle) {
|
||||
uio_Handle_delete(handle);
|
||||
}
|
||||
|
||||
static inline void
|
||||
uio_DirHandle_ref(uio_DirHandle *dirHandle) {
|
||||
dirHandle->ref++;
|
||||
}
|
||||
|
||||
static inline void
|
||||
uio_DirHandle_unref(uio_DirHandle *dirHandle) {
|
||||
assert(dirHandle->ref > 0);
|
||||
dirHandle->ref--;
|
||||
if (dirHandle->ref == 0)
|
||||
uio_DirHandle_delete(dirHandle);
|
||||
}
|
||||
|
||||
static inline uio_bool
|
||||
uio_PDirEntryHandle_isDir(const uio_PDirEntryHandle *handle) {
|
||||
return (handle->flags & uio_PDirEntryHandle_TYPEMASK) ==
|
||||
|
||||
@@ -188,6 +188,7 @@ joinPathsAbsolute(const char *first, const char *second) {
|
||||
result = uio_malloc(secondLen + 2);
|
||||
result[0] = '/';
|
||||
memcpy(&result[1], second, secondLen);
|
||||
result[secondLen + 1] = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,12 +63,57 @@ uio_PRoot_new(uio_PDirHandle *topDirHandle,
|
||||
pRoot->handle = handle;
|
||||
pRoot->extra = extra;
|
||||
pRoot->flags = flags;
|
||||
#ifdef uio_PROOT_HAVE_CLOSE_HANDLERS
|
||||
pRoot->numCloseHandlers = 0;
|
||||
pRoot->closeHandlers = NULL;
|
||||
#endif
|
||||
|
||||
return pRoot;
|
||||
}
|
||||
|
||||
#ifdef uio_PROOT_HAVE_CLOSE_HANDLERS
|
||||
// Closehandlers code disabled.
|
||||
// It was only meant for internal use, but I don't need it any more.
|
||||
// Keeping it around for a while until I'm confident I won't need it in the
|
||||
// future.
|
||||
|
||||
void
|
||||
uio_PRoot_addCloseHandler(uio_PRoot *pRoot, void (*fun)(void *), void *arg) {
|
||||
pRoot->numCloseHandlers++;
|
||||
pRoot->closeHandlers = uio_realloc(pRoot->closeHandlers,
|
||||
pRoot->numCloseHandlers * sizeof (uio_PRoot_CloseHandler));
|
||||
pRoot->closeHandlers[pRoot->numCloseHandlers - 1].fun = fun;
|
||||
pRoot->closeHandlers[pRoot->numCloseHandlers - 1].arg = arg;
|
||||
}
|
||||
|
||||
void
|
||||
uio_PRoot_callCloseHandlers(uio_PRoot *pRoot) {
|
||||
int i;
|
||||
|
||||
i = pRoot->numCloseHandlers;
|
||||
while (i--) {
|
||||
uio_PRoot_CloseHandler *closeHandler;
|
||||
|
||||
closeHandler = &pRoot->closeHandlers[i];
|
||||
(closeHandler->fun)(closeHandler->arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
uio_PRoot_removeCloseHandlers(uio_PRoot *pRoot) {
|
||||
pRoot->numCloseHandlers = 0;
|
||||
if (pRoot->closeHandlers != NULL)
|
||||
uio_free(pRoot->closeHandlers);
|
||||
pRoot->closeHandlers = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
uio_PRoot_delete(uio_PRoot *pRoot) {
|
||||
#ifdef uio_PROOT_HAVE_CLOSE_HANDLERS
|
||||
uio_PRoot_callCloseHandlers(pRoot);
|
||||
uio_PRoot_removeCloseHandlers(pRoot);
|
||||
#endif
|
||||
assert(pRoot->handler->umount != NULL);
|
||||
pRoot->handler->umount(pRoot);
|
||||
if (pRoot->handle)
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef void *uio_NativeEntriesContext;
|
||||
|
||||
// 'forward' declarations
|
||||
typedef struct uio_PRoot uio_PRoot;
|
||||
typedef struct uio_PRoot_CloseHandler uio_PRoot_CloseHandler;
|
||||
|
||||
|
||||
#include "iointrn.h"
|
||||
@@ -55,14 +56,31 @@ struct uio_PRoot {
|
||||
/* The handle through which this PRoot is opened,
|
||||
* this is NULL for the top PRoot */
|
||||
// TODO: move this to extra?
|
||||
#ifdef uio_PROOT_HAVE_CLOSE_HANDLERS
|
||||
int numCloseHandlers;
|
||||
uio_PRoot_CloseHandler *closeHandlers;
|
||||
#endif
|
||||
uio_PRootExtra extra;
|
||||
/* extra internal data for some filesystem types */
|
||||
};
|
||||
|
||||
#ifdef uio_PROOT_HAVE_CLOSE_HANDLERS
|
||||
struct uio_PRoot_CloseHandler {
|
||||
void (*fun)(void *);
|
||||
void *arg;
|
||||
};
|
||||
#endif
|
||||
|
||||
void uio_PRoot_deletePRootExtra(uio_PRoot *pRoot);
|
||||
uio_PRoot *uio_PRoot_new(uio_PDirHandle *topDirHandle,
|
||||
uio_FileSystemHandler *handler, uio_Handle *handle,
|
||||
uio_PRootExtra extra, int flags);
|
||||
#ifdef uio_PROOT_HAVE_CLOSE_HANDLERS
|
||||
void uio_PRoot_addCloseHandler(uio_PRoot *pRoot, void (*fun)(void *),
|
||||
void *arg);
|
||||
void uio_PRoot_callCloseHandlers(uio_PRoot *pRoot);
|
||||
void uio_PRoot_removeCloseHandlers(uio_PRoot *pRoot);
|
||||
#endif
|
||||
uio_PDirHandle *uio_PRoot_getRootDirHandle(uio_PRoot *pRoot);
|
||||
void uio_PRoot_refHandle(uio_PRoot *pRoot);
|
||||
void uio_PRoot_unrefHandle(uio_PRoot *pRoot);
|
||||
|
||||
@@ -137,9 +137,9 @@ stdio_stat(uio_PDirHandle *pDirHandle, const char *name,
|
||||
|
||||
result = stat(path, statBuf);
|
||||
if (result == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(path);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -159,9 +159,9 @@ stdio_mkdir(uio_PDirHandle *pDirHandle, const char *name, mode_t mode) {
|
||||
}
|
||||
|
||||
if (MKDIR(path, mode) == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(path);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
uio_free(path);
|
||||
@@ -244,10 +244,10 @@ stdio_rename(uio_PDirHandle *oldPDirHandle, const char *oldName,
|
||||
|
||||
result = rename(oldPath, newPath);
|
||||
if (result == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(oldPath);
|
||||
uio_free(newPath);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -283,9 +283,9 @@ stdio_rmdir(uio_PDirHandle *pDirHandle, const char *name) {
|
||||
|
||||
result = rmdir(path);
|
||||
if (result == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(path);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -319,9 +319,9 @@ stdio_unlink(uio_PDirHandle *pDirHandle, const char *name) {
|
||||
|
||||
result = unlink(path);
|
||||
if (result == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_free(path);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_H
|
||||
#define _UTILS_H
|
||||
#ifndef _UIOUTILS_H
|
||||
#define _UIOUTILS_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@@ -88,5 +88,5 @@ minu(unsigned int i1, unsigned int i2) {
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* _UIOUTILS_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (C) 2003 Serge van den Boom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
* Nota bene: later versions of the GNU General Public License do not apply
|
||||
* to this program.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "iointrn.h"
|
||||
#include "ioaux.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int uio_copyError(uio_Handle *srcHandle, uio_Handle *dstHandle,
|
||||
uio_DirHandle *unlinkHandle, const char *unlinkPath, uio_uint8 *buf);
|
||||
|
||||
struct uio_StdioAccessHandle {
|
||||
uio_DirHandle *tempRoot;
|
||||
char *tempDirName;
|
||||
uio_DirHandle *tempDir;
|
||||
char *fileName;
|
||||
char *stdioPath;
|
||||
};
|
||||
|
||||
static inline uio_StdioAccessHandle *uio_StdioAccessHandle_new(
|
||||
uio_DirHandle *tempRoot, char *tempDirName,
|
||||
uio_DirHandle *tempDir, char *fileName,
|
||||
char *stdioPath);
|
||||
static inline void uio_StdioAccessHandle_delete(
|
||||
uio_StdioAccessHandle *handle);
|
||||
static inline uio_StdioAccessHandle *uio_StdioAccessHandle_alloc(void);
|
||||
static inline void uio_StdioAccessHandle_free(uio_StdioAccessHandle *handle);
|
||||
|
||||
/*
|
||||
* Copy a file with path srcName to a file with name newName.
|
||||
* If the destination already exists, the operation fails.
|
||||
* Links are followed.
|
||||
* Special files (fifos, char devices, block devices, etc) will be
|
||||
* read as long as there is data available and the destination will be
|
||||
* a regular file with that data.
|
||||
* The new file will have the same permissions as the old.
|
||||
* If an error occurs during copying, an attempt will be made to
|
||||
* remove the copy.
|
||||
*/
|
||||
int
|
||||
uio_copyFile(uio_DirHandle *srcDir, const char *srcName,
|
||||
uio_DirHandle *dstDir, const char *newName) {
|
||||
uio_Handle *src, *dst;
|
||||
struct stat sb;
|
||||
#define BUFSIZE 65536
|
||||
uio_uint8 *buf, *bufPtr;
|
||||
ssize_t numInBuf, numWritten;
|
||||
|
||||
src = uio_open(srcDir, srcName, O_RDONLY
|
||||
#ifdef WIN32
|
||||
| O_BINARY
|
||||
#endif
|
||||
, 0);
|
||||
if (src == NULL)
|
||||
return -1;
|
||||
|
||||
if (uio_fstat(src, &sb) == -1)
|
||||
return uio_copyError(src, NULL, NULL, NULL, NULL);
|
||||
|
||||
dst = uio_open(dstDir, newName, O_WRONLY | O_CREAT | O_EXCL
|
||||
#ifdef WIN32
|
||||
| O_BINARY
|
||||
#endif
|
||||
, sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
||||
if (dst == NULL)
|
||||
return uio_copyError(src, NULL, NULL, NULL, NULL);
|
||||
|
||||
buf = uio_malloc(BUFSIZE);
|
||||
// This was originally a statically allocated buffer,
|
||||
// but as this function might be run from a thread with
|
||||
// a small Stack, this is better.
|
||||
while (1) {
|
||||
numInBuf = uio_read(src, buf, BUFSIZE);
|
||||
if (numInBuf == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return uio_copyError(src, dst, dstDir, newName, buf);
|
||||
}
|
||||
if (numInBuf == 0)
|
||||
break;
|
||||
|
||||
bufPtr = buf;
|
||||
do
|
||||
{
|
||||
numWritten = uio_write(dst, bufPtr, numInBuf);
|
||||
if (numWritten == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return uio_copyError(src, dst, dstDir, newName, buf);
|
||||
}
|
||||
numInBuf -= numWritten;
|
||||
bufPtr += numWritten;
|
||||
} while (numInBuf > 0);
|
||||
}
|
||||
|
||||
uio_free(buf);
|
||||
uio_close(src);
|
||||
uio_close(dst);
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes srcHandle if it's not -1.
|
||||
* Closes dstHandle if it's not -1.
|
||||
* Removes unlinkpath from the unlinkHandle dir if it's not NULL.
|
||||
* Frees 'buf' if not NULL.
|
||||
* Always returns -1.
|
||||
* errno is what was before the call.
|
||||
*/
|
||||
static int
|
||||
uio_copyError(uio_Handle *srcHandle, uio_Handle *dstHandle,
|
||||
uio_DirHandle *unlinkHandle, const char *unlinkPath, uio_uint8 *buf) {
|
||||
int savedErrno;
|
||||
|
||||
savedErrno = errno;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Error while copying: %s\n", strerror(errno));
|
||||
#endif
|
||||
|
||||
if (srcHandle != NULL)
|
||||
uio_close(srcHandle);
|
||||
|
||||
if (dstHandle != NULL)
|
||||
uio_close(dstHandle);
|
||||
|
||||
if (unlinkPath != NULL)
|
||||
uio_unlink(unlinkHandle, unlinkPath);
|
||||
|
||||
if (buf != NULL)
|
||||
uio_free(buf);
|
||||
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define NUM_TEMP_RETRIES 16
|
||||
// Retry this many times to create a temporary dir, before giving
|
||||
// up. If undefined, keep trying indefinately.
|
||||
|
||||
uio_StdioAccessHandle *
|
||||
uio_getStdioAccess(uio_DirHandle *dir, const char *path, int flags,
|
||||
uio_DirHandle *tempDir) {
|
||||
int res;
|
||||
uio_MountHandle *mountHandle;
|
||||
const char *name;
|
||||
char *newPath;
|
||||
char *tempDirName;
|
||||
uio_DirHandle *newDir;
|
||||
uio_FileSystemID fsID;
|
||||
|
||||
res = uio_getFileLocation(dir, path, flags, &mountHandle, &newPath);
|
||||
if (res == -1) {
|
||||
// errno is set
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fsID = uio_getMountFileSystemType(mountHandle);
|
||||
if (fsID == uio_FSTYPE_STDIO) {
|
||||
// Current location is usable.
|
||||
return uio_StdioAccessHandle_new(NULL, NULL, NULL, NULL, newPath);
|
||||
}
|
||||
uio_free(newPath);
|
||||
|
||||
{
|
||||
uio_uint32 dirNum;
|
||||
int i;
|
||||
|
||||
// Current location is not usable. Create a directory with a
|
||||
// generated name, as a temporary location to store a copy of
|
||||
// the file.
|
||||
dirNum = (uio_uint32) time(NULL);
|
||||
tempDirName = uio_malloc(sizeof "01234567");
|
||||
for (i = 0; ; i++) {
|
||||
#ifdef NUM_TEMP_RETRIES
|
||||
if (i >= NUM_TEMP_RETRIES) {
|
||||
// Using ENOSPC to report that we couldn't create a
|
||||
// temporary dir, getting EEXIST.
|
||||
uio_free(tempDirName);
|
||||
errno = ENOSPC;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
sprintf(tempDirName, "%08lx", (unsigned long) dirNum + i);
|
||||
|
||||
res = uio_mkdir(tempDir, tempDirName, 0700);
|
||||
if (res == -1) {
|
||||
int savedErrno;
|
||||
if (errno == EEXIST)
|
||||
continue;
|
||||
savedErrno = errno;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Error: Could not create temporary dir: %s\n",
|
||||
strerror(errno));
|
||||
#endif
|
||||
uio_free(tempDirName);
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
newDir = uio_openDirRelative(tempDir, tempDirName, 0);
|
||||
if (newDir == NULL) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Error: Could not open temporary dir: %s\n",
|
||||
strerror(errno));
|
||||
#endif
|
||||
res = uio_rmdir(tempDir, tempDirName);
|
||||
#ifdef DEBUG
|
||||
if (res == -1)
|
||||
fprintf(stderr, "Warning: Could not remove temporary dir: "
|
||||
"%s.\n", strerror(errno));
|
||||
#endif
|
||||
uio_free(tempDirName);
|
||||
errno = EIO;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the last component of path. This should be the file to
|
||||
// access.
|
||||
name = strrchr(path, '/');
|
||||
if (name == NULL)
|
||||
name = path;
|
||||
|
||||
// Copy the file
|
||||
res = uio_copyFile(dir, path, newDir, name);
|
||||
if (res == -1) {
|
||||
int savedErrno = errno;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Error: Could not copy file to temporary dir: "
|
||||
"%s\n", strerror(errno));
|
||||
#endif
|
||||
uio_closeDir(newDir);
|
||||
uio_free(tempDirName);
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
res = uio_getFileLocation(newDir, name, flags, &mountHandle, &newPath);
|
||||
if (res == -1) {
|
||||
int savedErrno = errno;
|
||||
fprintf(stderr, "Error: %s: Could not get location of temporary "
|
||||
"dir: %s.\n", __FUNCTION__, strerror(errno));
|
||||
uio_closeDir(newDir);
|
||||
uio_free(tempDirName);
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fsID = uio_getMountFileSystemType(mountHandle);
|
||||
if (fsID != uio_FSTYPE_STDIO) {
|
||||
// Temp dir isn't on a stdio fs either.
|
||||
fprintf(stderr, "Error: %s: Temporary file location isn't on a "
|
||||
"stdio filesystem.\n", __FUNCTION__);
|
||||
uio_closeDir(newDir);
|
||||
uio_free(tempDirName);
|
||||
uio_free(newPath);
|
||||
// errno = EXDEV;
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uio_DirHandle_ref(tempDir);
|
||||
return uio_StdioAccessHandle_new(tempDir, tempDirName, newDir,
|
||||
uio_strdup(name), newPath);
|
||||
}
|
||||
|
||||
void
|
||||
uio_releaseStdioAccess(uio_StdioAccessHandle *handle) {
|
||||
if (handle->tempDir != NULL) {
|
||||
if (uio_unlink(handle->tempDir, handle->fileName) == -1) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Error: Could not remove temporary file: "
|
||||
"%s\n", strerror(errno));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Need to free this handle in advance. There should be no handles
|
||||
// to a dir left when removing it.
|
||||
uio_DirHandle_unref(handle->tempDir);
|
||||
handle->tempDir = NULL;
|
||||
|
||||
if (uio_rmdir(handle->tempRoot, handle->tempDirName) == -1) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Error: Could not remove temporary directory: "
|
||||
"%s\n", strerror(errno));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
uio_StdioAccessHandle_delete(handle);
|
||||
}
|
||||
|
||||
const char *
|
||||
uio_StdioAccessHandle_getPath(uio_StdioAccessHandle *handle) {
|
||||
return (const char *) handle->stdioPath;
|
||||
}
|
||||
|
||||
// references to tempRoot and tempDir are not increased.
|
||||
// no copies of arguments are made.
|
||||
// By calling this function control of the values is transfered to
|
||||
// the handle.
|
||||
static inline uio_StdioAccessHandle *
|
||||
uio_StdioAccessHandle_new(
|
||||
uio_DirHandle *tempRoot, char *tempDirName,
|
||||
uio_DirHandle *tempDir, char *fileName, char *stdioPath) {
|
||||
uio_StdioAccessHandle *result;
|
||||
|
||||
result = uio_StdioAccessHandle_alloc();
|
||||
result->tempRoot = tempRoot;
|
||||
result->tempDirName = tempDirName;
|
||||
result->tempDir = tempDir;
|
||||
result->fileName = fileName;
|
||||
result->stdioPath = stdioPath;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void
|
||||
uio_StdioAccessHandle_delete(uio_StdioAccessHandle *handle) {
|
||||
if (handle->tempDir != NULL)
|
||||
uio_DirHandle_unref(handle->tempDir);
|
||||
if (handle->fileName != NULL)
|
||||
uio_free(handle->fileName);
|
||||
if (handle->tempRoot != NULL)
|
||||
uio_DirHandle_unref(handle->tempRoot);
|
||||
if (handle->tempDirName != NULL)
|
||||
uio_free(handle->tempDirName);
|
||||
uio_free(handle->stdioPath);
|
||||
uio_StdioAccessHandle_free(handle);
|
||||
}
|
||||
|
||||
static inline uio_StdioAccessHandle *
|
||||
uio_StdioAccessHandle_alloc(void) {
|
||||
return uio_malloc(sizeof (uio_StdioAccessHandle));
|
||||
}
|
||||
|
||||
static inline void
|
||||
uio_StdioAccessHandle_free(uio_StdioAccessHandle *handle) {
|
||||
uio_free(handle);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2003 Serge van den Boom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
* Nota bene: later versions of the GNU General Public License do not apply
|
||||
* to this program.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_H
|
||||
#define _UTILS_H
|
||||
|
||||
#ifdef uio_INTERNAL
|
||||
typedef struct uio_StdioAccessHandle uio_StdioAccessHandle;
|
||||
#else
|
||||
typedef void uio_StdioAccessHandle;
|
||||
#endif
|
||||
|
||||
int uio_copyFile(uio_DirHandle *srcDir, const char *srcName,
|
||||
uio_DirHandle *dstDir, const char *newName);
|
||||
uio_StdioAccessHandle *uio_getStdioAccess(uio_DirHandle *dir,
|
||||
const char *path, int flags, uio_DirHandle *tempDir);
|
||||
const char *uio_StdioAccessHandle_getPath(uio_StdioAccessHandle *handle);
|
||||
void uio_releaseStdioAccess(uio_StdioAccessHandle *handle);
|
||||
|
||||
|
||||
#endif /* _UTILS_H */
|
||||
|
||||
@@ -580,13 +580,13 @@ zip_mount(uio_Handle *handle, int flags) {
|
||||
|
||||
rootDirHandle = uio_PRoot_getRootDirHandle(result);
|
||||
if (zip_fillDirStructure(rootDirHandle->extra, handle) == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Error: failed to read the zip directory "
|
||||
"structure - %d.\n", errno);
|
||||
#endif
|
||||
uio_GPRoot_umount(result);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -662,11 +662,11 @@ zip_fillDirStructureCentral(uio_GPDir *top, uio_Handle *handle) {
|
||||
|
||||
err:
|
||||
{
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
|
||||
if (fileBlock != NULL)
|
||||
uio_closeFileBlock(fileBlock);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -845,10 +845,10 @@ zip_findEndOfCentralDirectoryRecord(uio_Handle *handle,
|
||||
bufLen = uio_accessFileBlock(fileBlock, startPos, endPos - startPos + 4,
|
||||
&buf);
|
||||
if (bufLen == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
fprintf(stderr, "Error: Read error while searching for "
|
||||
"'end-of-central-directory record'.\n");
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
if (bufLen != endPos - startPos + 4) {
|
||||
@@ -973,8 +973,8 @@ zip_fillDirStructureLocal(uio_GPDir *top, uio_Handle *handle) {
|
||||
|
||||
pos = uio_lseek(handle, 0, SEEK_SET);
|
||||
if (pos == -1) {
|
||||
int saveErrno = errno;
|
||||
errno = saveErrno;
|
||||
int savedErrno = errno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
if (pos != 0) {
|
||||
@@ -1015,10 +1015,10 @@ zip_fillDirStructureLocal(uio_GPDir *top, uio_Handle *handle) {
|
||||
|
||||
err:
|
||||
{
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
|
||||
uio_closeFileBlock(fileBlock);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1209,9 +1209,9 @@ zip_updateFileDataFromLocalHeader(uio_Handle *handle,
|
||||
}
|
||||
if (zip_updatePFileDataFromLocalFileHeader(gPFileData,
|
||||
fileBlock, gPFileData->headerOffset) == -1) {
|
||||
int saveErrno = errno;
|
||||
int savedErrno = errno;
|
||||
uio_closeFileBlock(fileBlock);
|
||||
errno = saveErrno;
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
if (gPFileData->ctime == (time_t) 0)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2003 Serge van den Boom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
* Nota bene: later versions of the GNU General Public License do not apply
|
||||
* to this program.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _UIOUTILS_H
|
||||
#define _UIOUTILS_H
|
||||
|
||||
#include "uio/utils.h"
|
||||
|
||||
#endif /* _UIOUTILS_H */
|
||||
|
||||
Reference in New Issue
Block a user