summaryrefslogtreecommitdiffstats
path: root/generic/tclZipfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclZipfs.c')
-rw-r--r--generic/tclZipfs.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index e7c1f90..ca15b38 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -381,6 +381,7 @@ static int ZipFSFileAttrsSetProc(Tcl_Interp *interp, int index,
static int ZipFSLoadFile(Tcl_Interp *interp, Tcl_Obj *path,
Tcl_LoadHandle *loadHandle,
Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
+static void ZipfsExitHandler(ClientData clientData);
static void ZipfsSetup(void);
static int ZipChannelClose(void *instanceData,
Tcl_Interp *interp);
@@ -1280,6 +1281,7 @@ ZipFSCatalogFilesystem(
*zf = *zf0;
zf->mountPoint = Tcl_GetHashKey(&ZipFS.zipHash, hPtr);
+ Tcl_CreateExitHandler(ZipfsExitHandler, (ClientData)zf);
zf->mountPointLen = strlen(zf->mountPoint);
zf->nameLength = strlen(zipname);
zf->name = Tcl_Alloc(zf->nameLength + 1);
@@ -1673,9 +1675,16 @@ TclZipfs_Mount(
return TCL_ERROR;
}
if (ZipFSOpenArchive(interp, zipname, 1, zf) != TCL_OK) {
+ Tcl_Free(zf);
return TCL_ERROR;
}
- return ZipFSCatalogFilesystem(interp, zf, mountPoint, passwd, zipname);
+ if (ZipFSCatalogFilesystem(interp, zf, mountPoint, passwd, zipname)
+ != TCL_OK) {
+ Tcl_Free(zf);
+ return TCL_ERROR;
+ }
+ Tcl_Free(zf);
+ return TCL_OK;
}
/*
@@ -1705,6 +1714,7 @@ TclZipfs_MountBuffer(
int copy)
{
ZipFile *zf;
+ int result;
ReadLock();
if (!ZipFS.initialized) {
@@ -1762,11 +1772,14 @@ TclZipfs_MountBuffer(
zf->data = data;
zf->ptrToFree = NULL;
}
+ zf->passBuf[0] = 0; /* stop valgrind cries */
if (ZipFSFindTOC(interp, 0, zf) != TCL_OK) {
return TCL_ERROR;
}
- return ZipFSCatalogFilesystem(interp, zf, mountPoint, NULL,
+ result = ZipFSCatalogFilesystem(interp, zf, mountPoint, NULL,
"Memory Buffer");
+ Tcl_Free(zf);
+ return result;
}
/*
@@ -1834,6 +1847,7 @@ TclZipfs_Unmount(
Tcl_Free(z);
}
ZipFSCloseArchive(interp, zf);
+ Tcl_DeleteExitHandler(ZipfsExitHandler, (ClientData)zf);
Tcl_Free(zf);
unmounted = 1;
done:
@@ -1905,7 +1919,7 @@ ZipFSMountBufferObjCmd(
unsigned char *data;
size_t length = 0;
- if (objc > 4) {
+ if (objc > 3) {
Tcl_WrongNumArgs(interp, 1, objv, "?mountpoint? ?data?");
return TCL_ERROR;
}
@@ -4819,6 +4833,17 @@ ZipfsAppHookFindTclInit(
return TCL_ERROR;
}
+static void
+ZipfsExitHandler(
+ ClientData clientData)
+{
+ ZipFile *zf = (ZipFile *)clientData;
+
+ if (TCL_OK != TclZipfs_Unmount(NULL, zf->mountPoint)) {
+ Tcl_Panic("tried to unmount busy filesystem");
+ }
+}
+
/*
*-------------------------------------------------------------------------
*