700 lines
38 KiB
HTML
700 lines
38 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<html>
|
|
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<title>CL-FAD - A portable pathname library for Common Lisp</title>
|
|
<style type="text/css">
|
|
pre { padding:5px; background-color:#e0e0e0 }
|
|
h3, h4, h5 { text-decoration: underline; }
|
|
a { text-decoration: none; padding: 1px 2px 1px 2px; }
|
|
a:visited { text-decoration: none; padding: 1px 2px 1px 2px; }
|
|
a:hover { text-decoration: none; padding: 1px 1px 1px 1px; border: 1px solid #000000; }
|
|
a:focus { text-decoration: none; padding: 1px 2px 1px 2px; border: none; }
|
|
a.none { text-decoration: none; padding: 0; }
|
|
a.none:visited { text-decoration: none; padding: 0; }
|
|
a.none:hover { text-decoration: none; border: none; padding: 0; }
|
|
a.none:focus { text-decoration: none; border: none; padding: 0; }
|
|
a.noborder { text-decoration: none; padding: 0; }
|
|
a.noborder:visited { text-decoration: none; padding: 0; }
|
|
a.noborder:hover { text-decoration: none; border: none; padding: 0; }
|
|
a.noborder:focus { text-decoration: none; border: none; padding: 0; }
|
|
pre.none { padding:5px; background-color:#ffffff }
|
|
</style>
|
|
</head>
|
|
|
|
<body bgcolor=white>
|
|
|
|
<h2>CL-FAD - A portable pathname library for Common Lisp</h2>
|
|
|
|
<blockquote>
|
|
<br> <br><h3><a name=abstract class=none>Abstract</a></h3>
|
|
|
|
CL-FAD (for "<font color=red>F</font>iles <font color=red>a</font>nd
|
|
<font color=red>D</font>irectories") is a thin layer atop Common
|
|
Lisp's standard pathname functions. It is intended to provide some
|
|
unification between current CL implementations on Windows, OS X,
|
|
Linux, and Unix. Most of the code was written by Peter Seibel for his book <a href="http://www.gigamonkeys.com/book/"><em>Practical Common Lisp</em></a>.
|
|
|
|
<p>
|
|
|
|
CL-FAD comes with a <a
|
|
href="http://www.opensource.org/licenses/bsd-license.php">BSD-style
|
|
license</a> so you can basically do with it whatever you want.
|
|
|
|
<p>
|
|
<font color=red>Download shortcut:</font> <a href="http://weitz.de/files/cl-fad.tar.gz">http://weitz.de/files/cl-fad.tar.gz</a>.
|
|
</blockquote>
|
|
|
|
<br> <br><h3><a class=none name="contents">Contents</a></h3>
|
|
<ol>
|
|
<li><a href="#download">Download and installation</a>
|
|
<li><a href="#implementations">Supported Lisp implementations</a>
|
|
<li><a href="#dictionary">The CL-FAD dictionary</a>
|
|
<ol>
|
|
<li><a href="#querying">Querying files, directories and pathnames</a>
|
|
<ol>
|
|
<li><a href="#directory-exists-p"><code>directory-exists-p</code> [function]</a>
|
|
<li><a href="#directory-pathname-p"><code>directory-pathname-p</code> [function]</a>
|
|
<li><a href="#file-exists-p"><code>file-exists-p</code> [function]</a>
|
|
<li><a href="#pathname-absolute-p"><code>pathname-absolute-p</code> [function]</a>
|
|
<li><a href="#pathname-equal"><code>pathname-equal</code> [function]</a>
|
|
<li><a href="#pathname-relative-p"><code>pathname-relative-p</code> [function]</a>
|
|
<li><a href="#pathname-root-p"><code>pathname-root-p</code> [function]</a>
|
|
</ol> </li>
|
|
<li><a href="#manipulating">Manipulating pathnames</a>
|
|
<ol>
|
|
<li><a href="#canonical-pathname"><code>canonical-pathname</code> [function]</a>
|
|
<li><a href="#merge-pathnames-as-directory"><code>merge-pathnames-as-directory</code> [function]</a>
|
|
<li><a href="#merge-pathnames-as-file"><code>merge-pathnames-as-file</code> [function]</a>
|
|
<li><a href="#pathname-as-directory"><code>pathname-as-directory</code> [function]</a>
|
|
<li><a href="#pathname-as-file"><code>pathname-as-file</code> [function]</a>
|
|
<li><a href="#pathname-directory-pathname"><code>pathname-directory-pathname</code> [function]</a>
|
|
<li><a href="#pathname-parent-directory"><code>pathname-parent-directory</code> [function]</a>
|
|
</ol> </li>
|
|
<li><a href="#traversing">Traversing directories</a>
|
|
<ol>
|
|
<li><a href="#list-directory"><code>list-directory</code> [function]</a>
|
|
<li><a href="#walk-directory"><code>walk-directory</code> [function]</a>
|
|
</ol> </li>
|
|
<li><a href="#temporary-files">Temporary Files</a>
|
|
<ol>
|
|
<li><a href="#open-temporary"><code>open-temporary</code> [function]</a>
|
|
<li><a href="#with-output-to-temporary-file"><code>with-output-to-temporary-file</code> [macro]</a>
|
|
<li><a href="#with-open-temporary-file"><code>with-open-temporary-file</code> [macro]</a>
|
|
<li><a href="#star-default-template-star"><code>*default-template*</code> [variable]</a>
|
|
<li><a href="#cannot-create-temporary-file"><code>cannot-create-temporary-file</code> [condition]</a>
|
|
<li><a href="#invalid-temporary-pathname-template"><code>invalid-temporary-pathname-template</code> [condition]</a>
|
|
<li><a href="#missing-temp-environment-variable"><code>missing-temp-environment-variable</code> [condition]</a>
|
|
<li><a href="#lp-host-temporary-files"><code>temporary-files</code> [logical pathname host]</a>
|
|
</ol>
|
|
</li>
|
|
<li><a href="#modifying">Modifying the file system</a>
|
|
<ol>
|
|
<li><a href="#copy-file"><code>copy-file</code> [function]</a>
|
|
<li><a href="#copy-stream"><code>copy-stream</code> [function]</a>
|
|
<li><a href="#delete-directory-and-files"><code>delete-directory-and-files</code> [function]</a>
|
|
</ol> </li>
|
|
<li><a href="#package-path"><code>path</code> [package]</a>
|
|
</ol>
|
|
<li><a href="#ack">Acknowledgements</a>
|
|
</ol>
|
|
|
|
|
|
|
|
<br> <br><h3><a class=none name="download">Download and installation</a></h3>
|
|
|
|
CL-FAD together with this documentation can be downloaded from <a
|
|
href="https://github.com/edicl/cl-fad/releases/latest">https://github.com/edicl/cl-fad/releases/latest</a>. The
|
|
current version is 0.7.6.
|
|
<p>
|
|
CL-FAD comes with simple system definitions for <a
|
|
href="http://www.cliki.net/mk-defsystem">MK:DEFSYSTEM</a> and <a
|
|
href="http://www.cliki.net/asdf">asdf</a> so you can either adapt it
|
|
to your needs or just unpack the archive and from within the CL-FAD
|
|
directory start your Lisp image and evaluate the form
|
|
<code>(mk:compile-system "cl-fad")</code> - or <code>(asdf:oos 'asdf:load-op :cl-fad)</code> for asdf - which should compile and load the whole
|
|
system.
|
|
Installation via <a
|
|
href="http://www.cliki.net/asdf-install">asdf-install</a> should as well
|
|
be possible. Plus, there are ports
|
|
for <a href="http://www.gentoo.org/proj/en/common-lisp/index.xml">Gentoo Linux</a> thanks to Matthew Kennedy
|
|
and for <a href="http://packages.debian.org/cgi-bin/search_packages.pl?keywords=cl-fad&searchon=names&subword=1&version=all&release=all">Debian Linux</a> thanks to René van Bevern.
|
|
<p>
|
|
If for some reason you can't or don't want to use MK:DEFSYSTEM or asdf you
|
|
can just <code>LOAD</code> the file <code>load.lisp</code>.
|
|
<p>
|
|
The latest version of the source code lives in the github repository <a href="https://github.com/edicl/cl-fad">edicl/cl-fad</a>.
|
|
|
|
If you want to send patches,
|
|
please <a href="http://weitz.de/patches.html">read this first</a>.
|
|
Please submit your changes
|
|
as <a href="https://github.com/edicl/cl-fad/pulls">GitHub pull
|
|
request"</a>.
|
|
|
|
<br> <br><h3><a class=none name="implementations">Supported Lisp implementations</a></h3>
|
|
|
|
<p>
|
|
The following Common Lisp implementations are currently supported:
|
|
<ul>
|
|
<li><a href="http://armedbear.org/abcl.html">Armed Bear Common Lisp</a>
|
|
<li><a href="http://www.cons.org/cmucl/">CMUCL</a>
|
|
<li><a href="http://www.cormanlisp.com/">Corman Common Lisp</a>
|
|
<li><a href="http://ecls.sf.net/">ECL</a>
|
|
<li><a href="http://www.franz.com/products/allegrocl/">Franz AllegroCL</a>
|
|
<li><a href="http://clisp.cons.org/">GNU CLISP</a>
|
|
<li><a href="http://www.lispworks.com/">LispWorks</a>
|
|
<li><a href="http://www.digitool.com/">Macintosh Common Lisp</a>
|
|
<li><a href="http://openmcl.clozure.com/">OpenMCL</a>
|
|
<li><a href="http://www.scieneer.com/scl/">Scieneer Common Lisp</a>
|
|
<li><a href="http://sbcl.sourceforge.net/">Steel Bank Common Lisp</a>
|
|
</ul>
|
|
|
|
I'll gladly accepts patches to make CL-FAD work on other platforms.
|
|
|
|
|
|
<br> <br><h3><a class=none name="dictionary">The CL-FAD dictionary</a></h3>
|
|
|
|
<h4><a class=none name="querying">Querying files, directories and pathnames</a></h4>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="directory-exists-p"><b>directory-exists-p</b> <i> pathspec </i> => <i> generalized-boolean</i></a>
|
|
|
|
<blockquote><br>
|
|
Checks whether the file named by the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a> <code><i>pathspec</i></code>
|
|
exists and if it is a directory. Returns its <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_t.htm#truename">truename</a> if this is the
|
|
case, <code>NIL</code> otherwise. The truename is returned in <em>directory form</em> as if
|
|
by <a href="#pathname-as-directory"><code>PATHNAME-AS-DIRECTORY</code></a>.
|
|
</blockquote>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="directory-pathname-p"><b>directory-pathname-p</b> <i> pathspec </i> => <i> generalized-boolean</i></a>
|
|
|
|
<blockquote><br>
|
|
Returns <code>NIL</code> if <code><i>pathspec</i></code> (a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a>) does not designate
|
|
a directory, <code><i>pathspec</i></code> otherwise. It is irrelevant whether the file or
|
|
directory designated by <code><i>pathspec</i></code> does actually exist.
|
|
</blockquote>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="file-exists-p"><b>file-exists-p</b> <i> pathspec </i> => <i> generalized-boolean</i></a>
|
|
|
|
<blockquote><br>
|
|
Checks whether the file named by the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a> <code><i>pathspec</i></code>
|
|
exists and returns its <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_t.htm#truename">truename</a> if this is the case, <code>NIL</code> otherwise.
|
|
The truename is returned in "canonical" form, i.e. the truename of a
|
|
directory is returned in <em>directory form</em> as if by <a href="#pathname-as-directory"><code>PATHNAME-AS-DIRECTORY</code></a>.
|
|
</blockquote>
|
|
|
|
<p><br>[Function]<br><a class=none name='pathname-absolute-p'><b>pathname-absolute-p</b> <i>a</i> => <i>result</i></a>
|
|
<blockquote>
|
|
<p>Returns true if <code><i>a</i></code> is an absolute pathname. This simply
|
|
tests if <code><i>a</i></code>'s directory list starts with <code>:ABSOLUTE</code></p>
|
|
</blockquote>
|
|
|
|
<p><br>[Function]<br><a class=none name='pathname-equal'><b>pathname-equal</b> <i>a b</i> => <i>result</i></a>
|
|
<blockquote>
|
|
|
|
<p>Returns <em>true</em> if <code><i>a</i></code> and <code><i>b</i></code>
|
|
represent the same pathname. This function does not access the
|
|
filesystem, it only looks at the components of the two pathnames to
|
|
test if they are the same (though by passing both <code><i>a</i></code>
|
|
and <code><i>b</i></code> to probe-file one can make this function test for
|
|
file 'sameness'.</p>
|
|
|
|
<p>Equality is defined as:</p>
|
|
|
|
<ul>
|
|
<li>strings that are <code>string=</code>
|
|
<li>symbols (including <code>nil</code> and keywords) which are <code>eql</code>
|
|
<li>lists of the same length with equal (as per these rules) elements.
|
|
</ul>
|
|
|
|
<p>If any of these tree conditions is false for any of the components in
|
|
<code><i>a</i></code> and <code><i>b</i></code> then <code><i>a</i></code>
|
|
and <code><i>b</i></code> are different, otherwise they are the same.</p>
|
|
|
|
<p><em>NB:</em> This function does not convert name strings to pathnames. So
|
|
"foo.txt" and #P"foo.txt" are different pathnames.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p><br>[Function]<br><a class=none name='pathname-relative-p'><b>pathname-relative-p</b> <i>a</i> => <i>result</i></a>
|
|
<blockquote>
|
|
<p>Returns true if <code><i>a</i></code> is a relative pathname. This simply
|
|
tests if <code><i>a</i></code>'s directory starts
|
|
with <code>:RELATIVE</code>.</p>
|
|
</blockquote>
|
|
|
|
<p><br>[Function]<br><a class=none name='pathname-root-p'><b>pathname-root-p</b> <i>a</i> => <i>result</i></a>
|
|
<blockquote>
|
|
<p>Returns <em>true</em> if <code><i>pathname</i></code> is the root
|
|
directory (in other words, a directory which is its own parent).</p>
|
|
</blockquote>
|
|
|
|
<h4><a class=none name="manipulating">Manipulating pathnames</a></h4>
|
|
|
|
<p><br>[Function]<br><a class=none name='canonical-pathname'><b>canonical-pathname</b> <i>pathname</i> => <i>result</i></a>
|
|
<blockquote>
|
|
<p>Remove redundant information from PATHNAME.</p>
|
|
|
|
<p>This simply walks down <code>PATHNAME</code>'s
|
|
pathname-directory and drops "." directories, removes :back
|
|
and its preceding element.</p>
|
|
|
|
<p>NB: This function does not access the filesystem, it only looks at the
|
|
values in the pathname and works on their known (or assumed)
|
|
meanings.</p>
|
|
|
|
<p>NB: Since this function does not access the filesystem it will only
|
|
remove <code>:BACK</code> elements from the path (not <code>:UP</code>
|
|
elements). Since some lisps, ccl/sbcl/clisp convert ".." in
|
|
pathnames to <code>:UP</code>, and not <code>:BACK</code>, the actual
|
|
utility of the function is limited.</p>
|
|
</blockquote>
|
|
|
|
<p><br>[Function]<br><a class=none name='merge-pathnames-as-directory'><b>merge-pathnames-as-directory</b> <i><tt>&rest</tt> pathnames</i> => <i>result</i></a>
|
|
<blockquote>
|
|
<p>Given a list of (probably relative) pathnames, this returns a single
|
|
directory pathname containing the logical concatenation of them all.</p>
|
|
|
|
<p>The returned value is the current directory if one were to cd into
|
|
each of <code><i>pathnames</i></code> in order. For this reason an
|
|
absolute pathname will, effectively, cancel the affect of any previous
|
|
relative pathnames.</p>
|
|
|
|
<p>The returned value's defaults are taken from the first element of
|
|
<code><i>pathnames</i></code> (host, version and device).</p>
|
|
|
|
<p><em>NB:</em> Since this function only looks at directory names the name and
|
|
type of the elements of <code><i>pathnames</i></code> are ignored. Make sure to properly
|
|
use either trailing #\/s, or <a href="#pathname-as-directory">pathname-as-directory</a>, to get the
|
|
expected results.</p>
|
|
|
|
<p>Examples:</p>
|
|
|
|
<pre>
|
|
(merge-pathnames-as-directory #P"foo/" #P"bar/") == #P"foo/bar/"
|
|
|
|
(merge-pathnames-as-directory #P"foo/" #P"./bar/") == #P"foo/./bar/"
|
|
|
|
(merge-pathnames-as-directory #P"foo/" #P"/bar/") == #P"/bar/"
|
|
|
|
(merge-pathnames-as-directory #P"foo/" #P"/bar/" #P'quux/file.txt) == #P"/bar/quux/"
|
|
</pre>
|
|
|
|
</blockquote>
|
|
|
|
<p><br>[Function]<br><a class=none name='merge-pathnames-as-file'><b>merge-pathnames-as-file</b> <i><tt>&rest</tt> pathnames</i> => <i>result</i></a>
|
|
<blockquote>
|
|
<p>Given a list of, probably relative, pathnames returns a single
|
|
filename pathname containing the logical concatenation of them all.</p>
|
|
|
|
<p>The returned value's defaults are taken from the first element of
|
|
<code><i>pathnames</i></code> (host, version and device). The returned
|
|
values's name, type and version are taken from the last element
|
|
of <code><i>pathnames</i></code>. The intervening elements are used only for
|
|
their pathname-directory values.</p>
|
|
|
|
Examples:
|
|
|
|
<pre>
|
|
(merge-pathnames-as-file #P"foo/" #P"bar.txt") == #P"foo/bar.txt"
|
|
|
|
(merge-pathnames-as-file #P"foo/" #P"./bar.txt") == #P"foo/./bar.txt"
|
|
|
|
(merge-pathnames-as-file #P"foo/" #P"/bar/README") == #P"/bar/README"
|
|
|
|
(merge-pathnames-as-file #P"/foo/" #P"/bar/" #P'quux/file.txt) == #P"/bar/quux/file.txt"
|
|
</pre>
|
|
|
|
</blockquote>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="pathname-as-directory"><b>pathname-as-directory</b> <i> pathspec </i> => <i> pathname</i></a>
|
|
<blockquote><br>
|
|
Converts the <em>non-wild</em> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a> <code><i>pathspec</i></code> to <em>directory form</em>, i.e. it returns a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname">pathname</a> which would return a <em>true</em> value if fed to <a href="#directory-pathname-p"><code>DIRECTORY-PATHNAME-P</code></a>.
|
|
</blockquote>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="pathname-as-file"><b>pathname-as-file</b> <i> pathspec </i> => <i> pathname</i></a>
|
|
|
|
<blockquote><br>
|
|
Converts the <em>non-wild</em> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a> <code><i>pathspec</i></code> to <em>file form</em>, i.e. it returns a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname">pathname</a> which would return a <code>NIL</code> value if fed to <a href="#directory-pathname-p"><code>DIRECTORY-PATHNAME-P</code></a>.
|
|
</blockquote>
|
|
|
|
<p><br>[Function]<br><a class=none name='pathname-directory-pathname'><b>pathname-directory-pathname</b> <i>pathname</i> => <i>result</i></a>
|
|
<blockquote>
|
|
<p>Returns a complete pathname representing the directory of
|
|
<code><i>pathname</i></code>. If <code><i>pathname</i></code> is
|
|
already a directory pathname
|
|
(<code>name</code> <code>nil</code>, <code>type</code>
|
|
<code>nil</code>) returns a pathname equal (as
|
|
per <a href="#pathname-equal">pathname-equal</a>) to it.</p>
|
|
</blockquote>
|
|
|
|
<p><br>[Function]<br><a class=none name='pathname-parent-directory'><b>pathname-parent-directory</b> <i>pathname</i> => <i>result</i></a>
|
|
<blockquote>
|
|
|
|
<p>Returns a pathname which would, by name at least,
|
|
contain <code><i>pathname</i></code> as one of its direct
|
|
children. Symlinks can make the parent/child relationship a like
|
|
opaque, but generally speaking the value returned by this function is
|
|
a directory name which contains <code><i>pathname</i></code>.</p>
|
|
|
|
<p>The root directory, #P"/", is its own parent. The parent
|
|
directory of a filename is the parent of the filename's
|
|
dirname.</p>
|
|
|
|
</blockquote>
|
|
|
|
<h4><a class=none name="traversing">Traversing directories</a></h4>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="list-directory"><b>list-directory</b> <i> dirname <tt>&key</tt> follow-symlinks</i> => <i> list</i></a>
|
|
|
|
<blockquote><br>
|
|
<p>
|
|
Returns a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#fresh">fresh</a> list of pathnames corresponding to
|
|
all files within the directory named by the non-wild <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a> <code><i>dirname</i></code>. The pathnames of sub-directories are returned in
|
|
<em>directory form</em> - see <a href="#pathname-as-directory"><code>PATHNAME-AS-DIRECTORY</code></a>.
|
|
</p>
|
|
<p>
|
|
If <code><i>follow-symlinks</i></code> is true (which is the
|
|
default), then the returned list contains truenames (symlinks will
|
|
be resolved) which essentially means that it might also return files
|
|
from <b>outside</b> the directory. This works on all platforms.
|
|
</p>
|
|
<p>
|
|
When <code><i>follow-symlinks</i></code> is <code>NIL</code>, it should return the actual directory
|
|
contents, which might include symlinks. (This is currently implemented only on SBCL and CCL.)
|
|
</p>
|
|
</blockquote>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="walk-directory"><b>walk-directory</b> <i> dirname fn <tt>&key</tt> directories if-does-not-exist test follow-symlinks</i> => |</a>
|
|
|
|
<blockquote><br>
|
|
<p>
|
|
Recursively applies the function designated by the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_designator">function
|
|
designator</a> <code><i>fn</i></code> to all files within the directory named
|
|
by the non-wild <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname
|
|
designator</a> <code><i>dirname</i></code> and all of its sub-directories. <code><i>fn</i></code>
|
|
will only be applied to files for which the function <code><i>test</i></code>
|
|
returns a <em>true</em> value. (The default value for <code><i>test</i></code>
|
|
always returns <em>true</em>.) If <code><i>directories</i></code> is not <code>NIL</code>,
|
|
<code><i>fn</i></code> and <code><i>test</i></code> are applied to directories
|
|
as well. If <code><i>directories</i></code> is <code>:DEPTH-FIRST</code>, <code><i>fn</i></code>
|
|
will be applied to the directory's contents first. If <code><i>directories</i></code>
|
|
is <code>:BREADTH-FIRST</code> and <code><i>test</i></code> returns <code>NIL</code>, the
|
|
directory's content will be skipped. <code><i>if-does-not-exist</i></code> must
|
|
be one of <code>:ERROR</code> or <code>:IGNORE</code> where <code>:ERROR</code>
|
|
(the default) means that an error will be signaled if the directory <code><i>dirname</i></code>
|
|
does not exist.
|
|
</p>
|
|
<p>
|
|
If <code><i>follow-symlinks</i></code> is true (which is
|
|
the default), then your callback will receive truenames. Otherwise
|
|
you should get the actual directory contents, which might include
|
|
symlinks. This might not be supported on all platforms. See
|
|
<a href="#list-directory"><code>LIST-DIRECTORY</code></a>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<h4><a class=none name="temporary-files">Temporary Files</a></h4>
|
|
|
|
<h5>Synopsis</h5>
|
|
|
|
<p>
|
|
Create a temporary file and return its name:
|
|
<pre>CL-USER> (temporary-file:<code xmlns=""><a href="#with-output-to-temporary-file">with-output-to-temporary-file</a></code> (foo)
|
|
(print "hello" foo))
|
|
#P"/var/folders/Yu/YuNMNBNPGoqs9G-1Wmj1dk+++TI/-Tmp-/temp-yjck024x"</pre>
|
|
</p>
|
|
<p>
|
|
Create a temporary file, read and write it, have it be deleted
|
|
automatically:
|
|
<pre>CL-USER> (temporary-file:<code xmlns=""><a href="#with-open-temporary-file">with-open-temporary-file</a></code> (foo :direction :io)
|
|
(print "hello" foo)
|
|
(file-position foo 0)
|
|
(read foo))
|
|
"hello"</pre>
|
|
</p>
|
|
|
|
<h5><a class="none" name="default-temporary-directory">Default temporary file directory</a></h5>
|
|
By default, temporary files are created in a system specific
|
|
directory that defaults based on operating system conventions. On
|
|
Unix and Unix-like systems, the directory <tt>/tmp/</tt> is used
|
|
by default. It can be overridden by setting the <tt>TMPDIR</tt>
|
|
environment variable. On Windows, the value of the environment
|
|
variable <tt>TEMP</tt> is used. If it is not set, temporary file
|
|
creation will fail.
|
|
|
|
<h5><a class="none" name="defining-temporary-directory">Defining the temporary file directory</a></h5>
|
|
<p>
|
|
The Lisp application can set the default directory in which
|
|
temporary files are created by the way of the
|
|
<code xmlns=""><a href="#temporary-files">temporary-files</a></code> logical pathname host:
|
|
|
|
<pre>(setf (<a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_logica.htm">logical-pathname-translations</a> "<code xmlns=""><a href="#temporary-files">temporary-files</a></code>") '(("*.*.*" "/var/tmp/")))</pre>
|
|
|
|
This would set the directory for temporary files to
|
|
<tt>/var/tmp/</tt>. For more information about logical
|
|
pathnames, please refer to <a href="http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/html/cltl/clm/node208.html#SECTION002715000000000000000">Common
|
|
Lisp the Language, 2nd Edition</a> and the <a href="http://clhs.lisp.se/Body/19_.htm">Common Lisp
|
|
HyperSpec</a>.
|
|
</p>
|
|
<p>
|
|
Physical path names have restrictions regarding the permitted
|
|
character in file names. If these restrictions conflict with
|
|
your desired naming scheme, you can pass a physical pathname as
|
|
TEMPLATE parameter to the temporary file generation function.
|
|
</p>
|
|
<p>
|
|
Here are a few examples:
|
|
<pre>CL-USER> (<a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_logica.htm">logical-pathname-translations</a> "temporary-files")
|
|
(("*.*.*" #P"/var/folders/Yu/YuNMNBNPGoqs9G-1Wmj1dk+++TI/-Tmp-/"))
|
|
CL-USER> (temporary-file:<code xmlns=""><a href="#with-open-temporary-file">with-open-temporary-file</a></code> (foo)
|
|
(<a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_pn.htm">pathname</a> foo))
|
|
#P"/var/folders/Yu/YuNMNBNPGoqs9G-1Wmj1dk+++TI/-Tmp-/temp-6rdqdkd1"</pre>
|
|
|
|
This used the temporary directory established in the TMPDIR
|
|
environment variable, by the way of the definition of the
|
|
temporary-files logical host definition.
|
|
|
|
<pre>CL-USER> (temporary-file:<code xmlns=""><a href="#with-open-temporary-file">with-open-temporary-file</a></code> (foo :template "/tmp/file.with.dots.in.name.%.txt")
|
|
(<a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_pn.htm">pathname</a> foo))
|
|
#P"/tmp/file.with.dots.in.name.2EF04KUJ.txt"</pre>
|
|
|
|
Here, a physical pathname was used for the
|
|
<code xmlns=""><i>:template</i></code> keyword argument so that a
|
|
filename containing multiple dots could be generated.
|
|
|
|
<pre>CL-USER> (temporary-file:<code xmlns=""><a href="#with-open-temporary-file">with-open-temporary-file</a></code> (foo :template "temporary-files:blah-%.txt")
|
|
(<a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_pn.htm">pathname</a> foo))
|
|
#P"/var/folders/Yu/YuNMNBNPGoqs9G-1Wmj1dk+++TI/-Tmp-/blah-72mj450d.txt"</pre>
|
|
|
|
This used the temporary-files logical pathname host, but changed
|
|
the filename slightly.
|
|
|
|
<pre>CL-USER> *default-pathname-defaults*
|
|
#P"/Users/hans/"
|
|
CL-USER> (temporary-file:<code xmlns=""><a href="#with-open-temporary-file">with-open-temporary-file</a></code> (foo :template "blah-%.txt")
|
|
(<a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_pn.htm">pathname</a> foo))
|
|
#P"/Users/hans/blah-5OEJELG2.txt"</pre>
|
|
|
|
Here, a relative pathname was used in the template, which
|
|
caused the file to be generated in the directory established
|
|
by <a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/v_defaul.htm">*default-pathname-defaults*</a>.
|
|
</p>
|
|
<p>
|
|
Alternatively, the <code xmlns=""><a href="#*default-template*">*default-template*</a></code>
|
|
special variable can be set to define a custom default template
|
|
for generating names.
|
|
</p>
|
|
|
|
<h5 xmlns=""><a class="none" name="security">Security</a></h5>
|
|
The TEMPORARY-FILE library does not directly address security
|
|
issues. The application that uses it needs to take additional
|
|
measures if it is important that files created by one process
|
|
cannot be accessed by other, unrelated processes. This can be
|
|
done by using the system dependent security mechanisms like
|
|
default file permissions or access control lists.
|
|
|
|
<h5>Dictionary</h5>
|
|
|
|
|
|
<p xmlns="">[Function]<br><a class="none" name="open-temporary"><b>open-temporary</b> <i><clix:lambda-list xmlns:clix="http://bknr.net/clixdoc"><tt>&rest</tt> open-arguments <tt>&key</tt> template generate-random-string max-tries <tt>&allow-other-keys</tt></clix:lambda-list></i>
|
|
=>
|
|
<i>stream</i></a><blockquote><clix:description xmlns:clix="http://bknr.net/clixdoc">
|
|
<p xmlns="http://www.w3.org/1999/xhtml">
|
|
Create a file with a randomly generated name and return the
|
|
opened stream. The resulting pathname is generated from
|
|
<code xmlns=""><i>template</i></code>, which is a string
|
|
representing a pathname template. A percent sign (%) in
|
|
that string is replaced by a randomly generated string to
|
|
make the filename unique. The default for
|
|
<code xmlns=""><i>template</i></code> places temporary files in the
|
|
<code xmlns=""><a href="#temporary-files">temporary-files</a></code> logical pathname host,
|
|
which is automatically set up in a system specific manner.
|
|
The file name generated from <code xmlns=""><i>template</i></code>
|
|
is merged with <a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/v_defaul.htm">*default-pathname-defaults*</a>,
|
|
so random pathnames relative to that directory can be
|
|
generated by not specifying a directory in
|
|
<code xmlns=""><i>template</i></code>.
|
|
</p>
|
|
<p xmlns="http://www.w3.org/1999/xhtml">
|
|
<code xmlns=""><i>generate-random-string</i></code> can be passed to
|
|
override the default function that generates the random name
|
|
component. It should return a random string consisting of
|
|
characters that are permitted in a pathname (logical or
|
|
physical, depending on <code xmlns=""><i>template</i></code>).
|
|
</p>
|
|
<p xmlns="http://www.w3.org/1999/xhtml">
|
|
The name of the temporary file can be accessed calling the
|
|
<a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_pn.htm">pathname</a>
|
|
function on <code xmlns=""><i>stream</i></code>. For convenience,
|
|
the temporary file is opened on the physical pathname,
|
|
i.e. if the <code xmlns=""><i>template</i></code> designate a
|
|
logical pathname the translation to a physical pathname is
|
|
performed before opening the stream.
|
|
</p>
|
|
<p xmlns="http://www.w3.org/1999/xhtml">
|
|
In order to create a unique file name,
|
|
<code xmlns=""><a href="#open-temporary">open-temporary</a></code> may loop internally up
|
|
to <code xmlns=""><i>max-tries</i></code> times before giving up and
|
|
signalling a
|
|
<code xmlns=""><a href="#cannot-create-temporary-file">cannot-create-temporary-file</a></code> condition.
|
|
</p>
|
|
<p xmlns="http://www.w3.org/1999/xhtml">
|
|
Any unrecognized keyword arguments are passed to the call to
|
|
<a xmlns="" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_open.htm">open</a>.
|
|
</p>
|
|
</clix:description></blockquote></p>
|
|
<p xmlns="">[Macro]<br><a class="none" name="with-output-to-temporary-file"><b>with-output-to-temporary-file</b> <i><clix:lambda-list xmlns:clix="http://bknr.net/clixdoc">(stream <tt>&rest</tt> args) <tt>&body</tt> body</clix:lambda-list></i>
|
|
=>
|
|
<i>pathname</i></a><blockquote><clix:description xmlns:clix="http://bknr.net/clixdoc">
|
|
Create a temporary file using
|
|
<code xmlns=""><a href="#open-temporary">open-temporary</a></code> with
|
|
<code xmlns=""><i>args</i></code> and run <code xmlns=""><i>body</i></code>
|
|
with <code xmlns=""><i>stream</i></code> bound to the temporary file
|
|
stream. Returns the pathname of the file that has been
|
|
created. See <code xmlns=""><a href="#open-temporary">open-temporary</a></code> for
|
|
permitted options.
|
|
</clix:description></blockquote></p>
|
|
<p xmlns="">[Macro]<br><a class="none" name="with-open-temporary-file"><b>with-open-temporary-file</b> <i><clix:lambda-list xmlns:clix="http://bknr.net/clixdoc">(stream <tt>&rest</tt> args <tt>&key</tt> keep <tt>&allow-other-keys</tt>) <tt>&body</tt> body</clix:lambda-list></i>
|
|
=>
|
|
<i>values</i></a><blockquote><clix:description xmlns:clix="http://bknr.net/clixdoc">
|
|
Create a temporary file using
|
|
<code xmlns=""><a href="#open-temporary">open-temporary</a></code> with
|
|
<code xmlns=""><i>args</i></code> and run <code xmlns=""><i>body</i></code>
|
|
with <code xmlns=""><i>stream</i></code> bound to the temporary file
|
|
stream. Returns the values returned by
|
|
<code xmlns=""><i>body</i></code>. By default, the file is deleted
|
|
when <code xmlns=""><i>body</i></code> is exited. If a true value is
|
|
passed in <code xmlns=""><i>keep</i></code>, the file is not deleted
|
|
when the body is exited. See
|
|
<code xmlns=""><a href="#open-temporary">open-temporary</a></code> for more permitted
|
|
options.
|
|
</clix:description></blockquote></p>
|
|
<p xmlns="">
|
|
[Special variable]<br><a class="none" name="*default-template*"><b>*default-template*</b></a><blockquote><clix:description xmlns:clix="http://bknr.net/clixdoc">
|
|
This variable can be set to a string representing the desired
|
|
default template for temporary file name generation. See
|
|
<code xmlns=""><a href="#open-temporary">open-temporary</a></code> for a description of the
|
|
template string format.
|
|
</clix:description></blockquote></p>
|
|
<p xmlns="">
|
|
[Condition type]<br><a class="none" name="cannot-create-temporary-file"><b>cannot-create-temporary-file</b></a><blockquote><clix:description xmlns:clix="http://bknr.net/clixdoc">
|
|
Signalled when an attempt to create unique temporary file name
|
|
failed after the established number of retries.
|
|
</clix:description></blockquote></p>
|
|
<p xmlns="">
|
|
[Condition type]<br><a class="none" name="invalid-temporary-pathname-template"><b>invalid-temporary-pathname-template</b></a><blockquote><clix:description xmlns:clix="http://bknr.net/clixdoc">
|
|
Signalled when the <code xmlns=""><i>template</i></code> argument to
|
|
<code xmlns=""><a href="#open-temporary">open-temporary</a></code> does not contain a valid
|
|
template string. The template string must contain a percent
|
|
sign, which is replaced by the generated random string to
|
|
yield the filename.
|
|
</clix:description></blockquote></p>
|
|
<p xmlns="">
|
|
[Condition type]<br><a class="none" name="missing-temp-environment-variable"><b>missing-temp-environment-variable</b></a><blockquote><clix:description xmlns:clix="http://bknr.net/clixdoc">
|
|
(Windows only) Signalled when the TEMP environment variable is
|
|
not set.
|
|
</clix:description></blockquote></p>
|
|
<p xmlns="">
|
|
[Logical Pathname Host]<br><a class="none" name="lp-host-temporary-files"><b>temporary-files</b></a><blockquote><clix:description xmlns:clix="http://bknr.net/clixdoc">
|
|
This logical pathname host defines where temporary files are
|
|
stored by default. It is initialized in a suitable system
|
|
specific fashion: On Unix and Unix-like systems, the directory
|
|
specified in the TMPDIR environment variable is used. If that
|
|
variable is not set, /tmp is used as the default. On Windows,
|
|
the directory specified in the TEMP environment variable is
|
|
used. If it is not set, a
|
|
<code xmlns=""><a href="#missing-temp-environment-variable">missing-temp-environment-variable</a></code> error
|
|
is signalled.
|
|
</clix:description></blockquote></p>
|
|
|
|
|
|
<h4><a class=none name="modifying">Modifying the file system</a></h4>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="copy-file"><b>copy-file</b> <i> from to <tt>&key</tt> overwrite</i> => |</a>
|
|
|
|
<blockquote><br>
|
|
Copies the file designated by the non-wild <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a> <code><i>from</i></code> to the
|
|
file designated by the non-wild <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a> <code><i>to</i></code>. If <code><i>overwrite</i></code> is <em>true</em> (the default is <code>NIL</code>)
|
|
overwrites the file designated by <code><i>to</i></code> if it exists.
|
|
</blockquote>
|
|
|
|
<p><br>[Function]
|
|
<br><a class=none name="copy-stream"><b>copy-stream</b> <i> from to <tt>&optional</tt> checkp</i> => |</a>
|
|
|
|
<blockquote><br> Copies into <code><i>to</i></code> (a stream)
|
|
from <code><i>from</i></code> (also a stream) until the end
|
|
of <code><i>from</i></code> is reached. The streams should have the
|
|
same <a
|
|
href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stm_el.htm">element
|
|
type</a> unless they are bivalent. If <code><i>checkp</i></code> is
|
|
true (which is the default), the function will signal an error if the
|
|
element types aren't the same.
|
|
</blockquote>
|
|
<p><br>[Function]
|
|
<br><a class=none name="delete-directory-and-files"><b>delete-directory-and-files</b> <i> dirname <tt>&key</tt> if-does-not-exist</i> => |</a>
|
|
|
|
<blockquote><br>
|
|
<p>
|
|
Recursively deletes all files and directories within the directory
|
|
designated by the non-wild <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator">pathname designator</a> <code><i>dirname</i></code> including
|
|
<code><i>dirname</i></code> itself. <code><i>if-does-not-exist</i></code> must be one of <code>:ERROR</code> or <code>:IGNORE</code>
|
|
where <code>:ERROR</code> (the default) means that an error will be signaled if the directory
|
|
<code><i>dirname</i></code> does not exist.
|
|
</p>
|
|
<p>
|
|
<b>Warning:</b> this function <em>might</em> remove files from outside the
|
|
directory, if the directory that you are deleting contains links to
|
|
external files. This is currently fixed for SBCL and CCL.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<h4>The <code>PATH</code> package</h4>
|
|
|
|
<p><br>[Package]
|
|
<br><a class=none name="package-path">(defpackage <b>path</b>)</a>
|
|
|
|
<blockquote>
|
|
Provides a set of short names for commonly used pathname manipulation
|
|
functions (these are all functions from the <code>cl-fad</code>
|
|
package which are being exported under different names):
|
|
<dl>
|
|
<dt><code>dirname</code></dt> <dd><a href="#pathname-as-directory">pathname-as-directory</a></dd>
|
|
<dt><code>basename</code></dt> <dd><code>cl:file-namestring</code></dd>
|
|
<dt><code>-e</code></dt> <dd><a href="#file-exists-p">file-exists-p</a></dd>
|
|
<dt><code>-d</code></dt> <dd><a href="#directory-exists-p">directory-exists-p</a></dd>
|
|
<dt><code>catfile</code></dt> <dd><a href="#merge-pathnames-as-file">merge-pathnames-as-file</a></dd>
|
|
<dt><code>catdir</code></dt> <dd><a href="#merge-pathnames-as-directory">merge-pathnames-as-directory</a></dd>
|
|
<dt><code>rm-r</code></dt> <dd><a href="#delete-directory-and-files">delete-directory-and-files</a></dd>
|
|
<dt><code>=</code></dt> <dd><a href="#pathname-equal">pathname-equal</a></dd>
|
|
<dt><code>absolute-p</code></dt> <dd><a href="#pathname-absolute-p">pathname-absolute-p</a></dd>
|
|
<dt><code>relative-p</code></dt> <dd><a href="#pathname-relative-p">pathname-relative-p</a></dd>
|
|
<dt><code>root-p</code></dt> <dd><a href="#pathname-root-p">pathname-root-p</a></dd>
|
|
</dl>
|
|
</blockquote>
|
|
|
|
|
|
<br> <br><h3><a class=none name="ack">Acknowledgements</a></h3>
|
|
|
|
The original code for this library was written by Peter Seibel for his
|
|
book <a href="http://www.gigamonkeys.com/book/"><em>Practical Common
|
|
Lisp</em></a>. I added some stuff and made sure it worked properly on
|
|
Windows, specifically with CCL. Thanks to James Bielman, Maciek
|
|
Pasternacki, Jack D. Unrue, Gary King, and Douglas Crosher who sent
|
|
patches for OpenMCL, ECL, ABCL, MCL, and Scieneer CL.
|
|
|
|
<p>
|
|
$Header: /usr/local/cvsrep/cl-fad/doc/index.html,v 1.33 2009/09/30 14:23:12 edi Exp $
|
|
<p><a href="http://weitz.de/index.html">BACK TO MY HOMEPAGE</a>
|
|
|
|
</body>
|
|
</html>
|
|
|