From b45a4e4ffdbdbf64adc71d4d79d5da4b43ac4809 Mon Sep 17 00:00:00 2001 From: meep-eep Date: Fri, 24 Oct 2003 02:36:27 +0000 Subject: [PATCH] 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 --- sc2/src/sc2code/libs/uio/debug.c | 121 +++++++++++++++++++++++++++- sc2/src/sc2code/libs/uio/doc/todo | 6 +- sc2/src/sc2code/libs/uio/io.c | 123 ++++++++++++++++++++++++++--- sc2/src/sc2code/libs/uio/io.h | 6 ++ sc2/src/sc2code/libs/uio/ioaux.c | 56 ++++++++++--- sc2/src/sc2code/libs/uio/ioaux.h | 9 ++- sc2/src/sc2code/libs/uio/paths.c | 47 +++++++++++ sc2/src/sc2code/libs/uio/paths.h | 1 + sc2/src/sc2code/libs/uio/zip/zip.c | 11 ++- 9 files changed, 351 insertions(+), 29 deletions(-) diff --git a/sc2/src/sc2code/libs/uio/debug.c b/sc2/src/sc2code/libs/uio/debug.c index 6b1d170ae..e4aa69929 100644 --- a/sc2/src/sc2code/libs/uio/debug.c +++ b/sc2/src/sc2code/libs/uio/debug.c @@ -25,6 +25,9 @@ #include #include #include +#ifdef __unix__ +# include +#endif #include "debug.h" #include "uioport.h" @@ -58,6 +61,7 @@ void unInitRepository(void); static int debugCmdCat(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 debugCmdLs(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[] = { { "cat", debugCmdCat }, { "cd", debugCmdCd }, + { "exec", debugCmdExec }, { "exit", debugCmdExit }, { "fwritetest", debugCmdFwriteTest }, { "ls", debugCmdLs }, @@ -294,12 +299,12 @@ makeArgs(char *lineBuf, int *argc, char ***argv) { numArg = 0; ptr = lineBuf; while(1) { - while (isspace(*ptr)) + while (isspace((int) *ptr)) ptr++; if (*ptr == '\0') break; numArg++; - while (!isspace(*ptr)) + while (!isspace((int) *ptr)) ptr++; } @@ -307,13 +312,13 @@ makeArgs(char *lineBuf, int *argc, char ***argv) { numArg = 0; ptr = lineBuf; while(1) { - while (isspace(*ptr)) + while (isspace((int) *ptr)) ptr++; if (*ptr == '\0') break; args[numArg] = ptr; numArg++; - while (!isspace(*ptr)) + while (!isspace((int) *ptr)) ptr++; if (*ptr == '\0') break; @@ -424,6 +429,114 @@ debugCmdCd(DebugContext *debugContext, int argc, char *argv[]) { 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 debugCmdExit(DebugContext *debugContext, int argc, char *argv[]) { debugContext->exit = true; diff --git a/sc2/src/sc2code/libs/uio/doc/todo b/sc2/src/sc2code/libs/uio/doc/todo index dae859a1c..1e3ffcb2c 100644 --- a/sc2/src/sc2code/libs/uio/doc/todo +++ b/sc2/src/sc2code/libs/uio/doc/todo @@ -36,8 +36,12 @@ Bugs: - 'openDir(repository, "dir/")' will have the trailing '/' in the dirHandle, which will cause problems. - 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. +- 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): - Make functions to use for uio_malloc, uio_free and uio_realloc diff --git a/sc2/src/sc2code/libs/uio/io.c b/sc2/src/sc2code/libs/uio/io.c index b693382a6..a4b7478e8 100644 --- a/sc2/src/sc2code/libs/uio/io.c +++ b/sc2/src/sc2code/libs/uio/io.c @@ -325,6 +325,11 @@ uio_unmountAllDirs(uio_Repository *repository) { return 0; } +uio_FileSystemID +uio_getMountFileSystemType(uio_MountHandle *mountHandle) { + return mountHandle->mountInfo->fsID; +} + int uio_close(uio_Handle *handle) { uio_Handle_unref(handle); @@ -340,15 +345,15 @@ uio_rename(uio_DirHandle *oldDir, const char *oldPath, int retVal; if (uio_getPhysicalAccess(oldDir, oldPath, O_RDONLY, 0, - &oldReadMountInfo, &oldPReadDir, - NULL, NULL, &oldName) == -1) { + &oldReadMountInfo, &oldPReadDir, NULL, + NULL, NULL, NULL, &oldName) == -1) { // errno is set return -1; } if (uio_getPhysicalAccess(newDir, newPath, O_WRONLY | O_CREAT | O_EXCL, - uio_GPA_NOWRITE, &newReadMountInfo, &newPReadDir, - &newWriteMountInfo, &newPWriteDir, &newName) == -1) { + uio_GPA_NOWRITE, &newReadMountInfo, &newPReadDir, NULL, + &newWriteMountInfo, &newPWriteDir, NULL, &newName) == -1) { int saveErrno = errno; uio_PDirHandle_unref(oldPReadDir); uio_free(oldName); @@ -423,8 +428,8 @@ uio_stat(uio_DirHandle *dir, const char *path, struct stat *statBuf) { int result; if (uio_getPhysicalAccess(dir, path, O_RDONLY, 0, - &readMountInfo, &pReadDir, - NULL, NULL, &name) == -1) { + &readMountInfo, &pReadDir, NULL, + NULL, NULL, NULL, &name) == -1) { if (uio_statDir(dir, path, statBuf) == -1) { // errno is set return -1; @@ -513,8 +518,8 @@ uio_mkdir(uio_DirHandle *dir, const char *path, mode_t mode) { uio_PDirHandle *newDirHandle; if (uio_getPhysicalAccess(dir, path, O_WRONLY | O_CREAT | O_EXCL, 0, - &readMountInfo, &pReadDir, - &writeMountInfo, &pWriteDir, &name) == -1) { + &readMountInfo, &pReadDir, NULL, + &writeMountInfo, &pWriteDir, NULL, &name) == -1) { // errno is set if (errno == EISDIR) errno = EEXIST; @@ -552,8 +557,8 @@ uio_open(uio_DirHandle *dir, const char *path, int flags, mode_t mode) { uio_Handle *handle; if (uio_getPhysicalAccess(dir, path, flags, 0, - &readMountInfo, &readPDirHandle, - &writeMountInfo, &writePDirHandle, &name) == -1) { + &readMountInfo, &readPDirHandle, NULL, + &writeMountInfo, &writePDirHandle, NULL, &name) == -1) { // errno is set 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 *** // #define uio_DIR_BUFFER_SIZE 2048 diff --git a/sc2/src/sc2code/libs/uio/io.h b/sc2/src/sc2code/libs/uio/io.h index 6ab56dafe..db66796d1 100644 --- a/sc2/src/sc2code/libs/uio/io.h +++ b/sc2/src/sc2code/libs/uio/io.h @@ -87,6 +87,9 @@ int uio_unmountDir(uio_MountHandle *mountHandle); // Unmount all previously mounted dirs. int uio_unmountAllDirs(uio_Repository *repository); +// Get the filesystem identifier for a mounted directory. +uio_FileSystemID uio_getMountFileSystemType(uio_MountHandle *mountHandle); + // Open a file uio_Handle *uio_open(uio_DirHandle *dir, const char *file, int flags, 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_getFileLocation(uio_DirHandle *dir, const char *inPath, + int flags, uio_MountHandle **mountHandle, char **outPath); + // Get a directory handle. uio_DirHandle *uio_openDir(uio_Repository *repository, const char *path, int flags); diff --git a/sc2/src/sc2code/libs/uio/ioaux.c b/sc2/src/sc2code/libs/uio/ioaux.c index 40c11f310..82586bfca 100644 --- a/sc2/src/sc2code/libs/uio/ioaux.c +++ b/sc2/src/sc2code/libs/uio/ioaux.c @@ -260,26 +260,38 @@ copyError(int error, * extraFlags - either 0 or uio_GPA_NOWRITE * When 0, the path will be created if it doesn't * exist in the writing location, but does exist - * in the reading location. With uio_GPA_NOWRITE, it - * won't be created, and -1 will be returned and errno - * will be set to ENOENT. + * in the reading location. With uio_GPA_NOWRITE, it + * won't be created, and -1 will be returned and errno + * will be set to ENOENT. * mountInfoReadPtr - pointer to location where the pointer * to the MountInfo structure for the reading location * should be stored. * readPDirHandlePtr - pointer to the location where the pointer * 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 * to the MountInfo structure for the writing location * should be stored. * writePDirHandlePtr - pointer to the location where the pointer * to the PDirHandle used for writing should be stored. * NULL if O_RDONLY was specified. - * If this is the same dir as the one refered - * to by readPDirHandlePtr, the handles will be the - * same too. - * restPtr - pointer to a newly created string with as contents - * the last component of 'path'. + * If this is the same dir as the one refered + * to by readPDirHandlePtr, the handles will be the + * same too. + * writePRootPath - pointer to the location where the pointer + * to the physical path to the writing location + * is to be stored. * 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 * -1 - failure (errno set) * NB: This is the function that would most benefit from @@ -291,10 +303,13 @@ int uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, int flags, int extraFlags, uio_MountInfo **mountInfoReadPtr, uio_PDirHandle **readPDirHandlePtr, + char **readPRootPathPtr, uio_MountInfo **mountInfoWritePtr, uio_PDirHandle **writePDirHandlePtr, + char **writePRootPathPtr, char **restPtr) { char *fullPath; // path from dirHandle with 'path' added const char *pRootPath; // path from the pRoot of a physical tree + const char *readPRootPath, *writePRootPath; const char *rest, *readRest; uio_MountTree *tree; uio_MountTreeItem *item; @@ -317,8 +332,10 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, readItem = NULL; readPDirHandle = NULL; + readPRootPath = NULL; writeItem = NULL; writePDirHandle = NULL; + writePRootPath = NULL; readRest = NULL; // Satisfy compiler. entryExists = false; @@ -356,6 +373,7 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, if (readPDirHandle != NULL) uio_PDirHandle_unref(readPDirHandle); readPDirHandle = pDirHandle; + readPRootPath = pRootPath; readRest = rest; entryExists = true; break; @@ -365,6 +383,7 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, readItem = item; assert(readPDirHandle == NULL); readPDirHandle = pDirHandle; + readPRootPath = pRootPath; readRest = rest; continue; } @@ -399,6 +418,9 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, // write access is not needed *mountInfoReadPtr = readItem->mountInfo; *readPDirHandlePtr = readPDirHandle; + if (readPRootPathPtr != NULL) + *readPRootPathPtr = joinPathsAbsolute( + readItem->mountInfo->dirName, readPRootPath); // Don't touch mountInfoWritePtr and writePDirHandlePtr. // they'd be NULL. *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. *mountInfoReadPtr = readItem->mountInfo; *readPDirHandlePtr = readPDirHandle; + if (readPRootPathPtr != NULL) + *readPRootPathPtr = joinPathsAbsolute( + readItem->mountInfo->dirName, readPRootPath); *mountInfoWritePtr = writeItem->mountInfo; // writeItem == readItem uio_PDirHandle_ref(readPDirHandle); *writePDirHandlePtr = readPDirHandle; // No copy&paste error, the read PDirHandle is the write // 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); return 0; } @@ -490,9 +519,16 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, *mountInfoReadPtr = readItem->mountInfo; *readPDirHandlePtr = readPDirHandle; + if (readPRootPathPtr != NULL) + *readPRootPathPtr = joinPathsAbsolute( + readItem->mountInfo->dirName, readPRootPath); *mountInfoReadPtr = writeItem->mountInfo; *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); return 0; } diff --git a/sc2/src/sc2code/libs/uio/ioaux.h b/sc2/src/sc2code/libs/uio/ioaux.h index 5a2e7e3a1..c4dab8b5f 100644 --- a/sc2/src/sc2code/libs/uio/ioaux.h +++ b/sc2/src/sc2code/libs/uio/ioaux.h @@ -33,9 +33,12 @@ uio_PDirHandle *uio_makePath(uio_PDirHandle *pDirHandle, const char *path, int uio_copyFilePhysical(uio_PDirHandle *fromDir, const char *fromName, uio_PDirHandle *toDir, const char *toName); int uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, - int flags, int extraFlags, uio_MountInfo **mountInfoReadPtr, - uio_PDirHandle **readPDirHandlePtr, uio_MountInfo **mountInfoWritePtr, - uio_PDirHandle **writePDirHandlePtr, char **restPtr); + int flags, int extraFlags, + uio_MountInfo **mountInfoReadPtr, uio_PDirHandle **readPDirHandlePtr, + char **readPRootPathPtr, + uio_MountInfo **mountInfoWritePtr, uio_PDirHandle **writePDirHandlePtr, + char **writePRootPathPtr, + char **restPtr); #define uio_GPA_NOWRITE 1 int uio_getPathPhysicalDirs(uio_DirHandle *dirHandle, const char *path, size_t pathLen, uio_PDirHandle ***resPDirHandles, diff --git a/sc2/src/sc2code/libs/uio/paths.c b/sc2/src/sc2code/libs/uio/paths.c index 0b4dd9521..8b83aff5f 100644 --- a/sc2/src/sc2code/libs/uio/paths.c +++ b/sc2/src/sc2code/libs/uio/paths.c @@ -142,10 +142,17 @@ getPreviousPathComponent(const char *dir, (*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 * joinPaths(const char *first, const char *second) { char *result, *resPtr; size_t firstLen, secondLen; + + if (first[0] == '\0') + return uio_strdup(second); firstLen = strlen(first); if (first[firstLen - 1] == '/') @@ -167,6 +174,46 @@ joinPaths(const char *first, const char *second) { 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 validPathName(const char *path, size_t len) { const char *pathEnd; diff --git a/sc2/src/sc2code/libs/uio/paths.h b/sc2/src/sc2code/libs/uio/paths.h index aa65dec08..87fefd7e6 100644 --- a/sc2/src/sc2code/libs/uio/paths.h +++ b/sc2/src/sc2code/libs/uio/paths.h @@ -39,6 +39,7 @@ void getPreviousPathComponent(const char *dir, const char **startComp, const char **endComp); #define getPreviousPath0Component getPreviousPathComponent 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); diff --git a/sc2/src/sc2code/libs/uio/zip/zip.c b/sc2/src/sc2code/libs/uio/zip/zip.c index 69c93dde3..e09ff0abd 100644 --- a/sc2/src/sc2code/libs/uio/zip/zip.c +++ b/sc2/src/sc2code/libs/uio/zip/zip.c @@ -579,7 +579,16 @@ zip_mount(uio_Handle *handle, int flags) { handle, NULL, uio_GPDir_COMPLETE); 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; }