Artifact [35eb0371da]
Not logged in

Artifact 35eb0371daa892cdcdcf5f42a6000a6ebeefd8c9:

Wiki page [ZIP virtual file system] by chw 2018-07-09 08:32:33.
D 2018-07-09T08:32:33.819
L ZIP\svirtual\sfile\ssystem
P 5fff22863b4cec9a30e13325556cb69061a1c936
U chw
W 7161
[AndroWish] comes with a special <a href="http://en.wikipedia.org/wiki/Zip_%28file_format%29">ZIP</a> virtual file system which uses mmap(2) to read-only map a ZIP file (in this case AndroWish's APK, i.e. its own installation package) into the process address space to speed up startup time and subsequent read accesses. While this file system was designed primarily for AndroWish it can be used on other platforms, too. Namely, [undroidwish] uses it on Windows and Linux to mount an archive of Tcl and native extensions which is appended to the executable portion of its binary. It is implemented in the files <tt><a href="/index.html/artifact/5e8fa959751efdbec16c5e86d396ed9da18e4946">zipfs.c</a></tt> and <tt><a href="/index.html/artifact/041e4f55b75f0a2e26198f8eaad188c0ae005759">zipfs.h</a></tt> in AndroWish's <tt>.../jni/tcl/generic</tt> folder and enabled in the Tcl core by the presence of the C preprocessor macro <tt>ZIPFS_IN_TCL</tt>.

<h3>Low-level C interface</h3>

<tt>Zipfs_Init(Tcl_Interp *interp)</tt>

    Performs one-time initialization of the file system and registers it process wide. Additionally, a package named <i>zipfs</i> is provided and supplemental Tcl commands are created in the given interpreter.

<tt>Zipfs_Mount(Tcl_Interp *<i>interp</i>, const char *<i>zipname</i>, const char *<i>mntpt</i>, const char *<i>passwd</i>)</tt>

    Mounts the ZIP archive file <tt><i>zipname</i></tt> on the mount point <tt><i>mntpt</i></tt> using the optional ZIP password <tt><i>passwd</i></tt>. Errors are reported in the interpreter <tt><i>interp</i></tt>. If <tt><i>zipname</i></tt> is NULL information on all currently mounted ZIP file systems is written into <tt><i>interp</i></tt> as a sequence of mount points and ZIP file names.

<tt>Zipfs_Unmount(Tcl_Interp *<i>interp</i>, const char *<i>zipname</i>)</tt>

    Undoes the effect of <tt>Zipfs_Mount()</tt>, i.e. unmounts the mounted ZIP archive file <tt><i>zipname</i></tt>. Errors are reported in the interpreter <tt><i>interp</i></tt>.

<h3>Tcl commands</h3>

<tt>zipfs::mount ?<i>zipfile</i> ?<i>mountpoint password</i>?</tt>

    Mounts the ZIP archive file <tt><i>zipfile</i></tt> on mount point <tt><i>mountpoint</i></tt> using the optional ZIP password <tt><i>password</i></tt>. If invoked without or with a single argument information as described above in <tt>Zipfs_Mount()</tt> is returned.

<tt>zipfs::unmount <i>zipfile<i></tt>

    Unmounts the mounted ZIP archive file <tt><i>zipfile</i></tt>.

<tt>zipfs::mkzip <i>outfile indir</i> ?<i>strip password</i>?</tt>

    Creates a ZIP archive file named <tt><i>outfile</i></tt> from the contents of the input directory <tt><i>indir</i></tt> (contained regular files only) with optional ZIP password <tt><i>password</i></tt>. While processing the files below <tt><i>indir</i></tt> the optional prefix given in <tt><i>strip</i></tt> is stripped off the beginning of the respective file name. Caution: the choice of the <tt><i>indir</i></tt> parameter (less the optional <tt><i>strip</i></tt> prefix) determines the later root name of the archive's content.

<tt>zipfs::mkimg <i>outfile indir</i> ?<i>strip password infile</i>?</tt>

    Caution: highly experimental, not usable on Android, only partially tested on Linux and Windows. Create an image (potentially a new executable file) similar to <tt>zipfs::mkzip</tt>. If the <tt><i>infile</i></tt> parameter is specified, this file is prepended in front of the ZIP archive, otherwise the file returned by <tt>Tcl_NameOfExecutable(3)</tt> (i.e. the executable file of the running process) is used. If the <tt><i>password</i></tt> parameter is not empty, an obfuscated version of that password is placed between the image and ZIP chunks of the output file and the contents of the ZIP chunk are protected with that password.

<tt>zipfs::exists <i>pathname</i></tt>

    Tests if <tt><i>pathname</i></tt> exists in any of the currently mounted ZIP archives.

<tt>zipfs::info <i>pathname</i></tt>

    Returns information on <tt><i>pathname</i></tt> as a list made up of the name of its enclosing and mounted ZIP archive file, file size uncompressed, file size compressed, and byte offset of the file from start of its enclosing ZIP archive file.

<tt>zipfs::list ?<i>-glob</i>|<i>-regexp</i>? ?<i>pattern</i>?</tt>

    Lists files of any or all of the mounted ZIP archives. If <tt><i>pattern</i></tt> is omitted all files are listed. Otherwise <tt><i>pattern</i></tt> is interpreted as a glob or regexp pattern and used to list only files matching this pattern.

<tt>zipfs::find <i>dir</i></tt>

    Recursively lists files including and below the directory <tt><i>dir</i></tt>. The result list consists of relative path names starting from the given directory. This command is also used by the <tt>zipfs::mkzip</tt> and <tt>zipfs::mkimg</tt> commands.

<h3>zipfs as Tcl (and Tk) bootstrap file system</h3>

On the Android platform zipfs is used to boot Tcl/Tk from the APK by early mounting the APK file on the file system root. Since nearly all relevant files within the APK are below the <tt>assets</tt> folder, this lets Tcl see the directory <tt>/assets</tt> with its library directories, e.g. the <tt>/assets/tcl8.6</tt> directory with Tcl's library modules, encoding tables etc. That relationship to <tt>/assets/tcl8.6</tt> is hard coded into the Tcl shared library and based on it all other packaged library directories can be found during Tcl initialization.

For standalone apps a similar approach is chosen by hard coding the file <tt>/assets/app/main.tcl</tt> as the file to be sourced (if present) right after Tcl's initialization. This allows for packaging Tcl based apps as an APK, see the description in [AndroWish SDK] for instructions.

On other platforms (currently tested Linux and Windows) the initial mount of an embedded ZIP file system is done on the executable itself, e.g. if <tt>/home/john/awish</tt> is the Tcl/Tk binary with an included ZIP file system, the Tcl library directory of the file system when mounted becomes <tt>/home/john/awish/tcl8.6</tt>. Similarly, built in application code will be started from the file <tt>/home/john/awish/app/main.tcl</tt> if present. Additionally, the contents of the optional file <tt>/home/john/awish/app/cmdline</tt> are appended to the command line before Tk is initialized and control is transferred to the <tt>main.tcl</tt> script. This is useful to setup certain aspects of SDL, e.g. to start in full screen mode with or without changed display resolution (see description of SDL startup options in [Beyond AndroWish]). Another hook is <tt>/home/john/awish/app/icon.bmp</tt> which (if present) should be a Windows BMP 24 bit RGB bitmap file used as the icon for the SDL root window.

On Windows platforms the drive letter of the base executable is prepended to the respective path names. For the example above this means: <tt>C:\home\john\awish.exe</tt> is the binary, <tt>C:/home/john/awish.exe/tcl8.6</tt> becomes the Tcl library directory, <tt>C:/home/john/awish.exe/app/main.tcl</tt> is the optional application script, and so on.





Z e368b4c56dfb585880528eef8dda079b