32
32
(in-package "OSLIB")
33
33
(include-book "getpid")
34
(include-book "catpath")
35
(include-book "std/strings/decimal" :dir :system)
36
(include-book "std/strings/cat" :dir :system)
40
:short "Generate a suitable name for a temporary file."
42
:long "<p>Signature: @(call tempfile) → @('(mv filename/nil
48
(tempfile \"foo\") --> (\"/tmp/jared-31721-foo\" <state>)
51
<p>Note: this function is attachable. If you need to generate temporary file
52
names using some other scheme, you can define your own strategy and attach it
53
to @('tempfile-fn'); see @(see defattach).</p>
55
<p>The intent is that this function should produce a good @('filename') to use
56
for the name of a temporary file. To allow @('tempfile') implementations to
57
fail for whatever reason, @('filename') may be @('nil').</p>
62
(defmacro tempfile (basename &optional (state 'state))
63
`(tempfile-fn ,basename ,state))
66
(((tempfile-fn * state) => (mv * state)
67
:formals (basename state)
68
:guard (stringp basename)))
70
(local (defun tempfile-fn (basename state)
71
(declare (xargs :stobjs state)
75
(defthm type-of-tempfile-fn
76
;; Tempfile-fn can fail, for whatever reason, by producing NIL.
77
(or (stringp (mv-nth 0 (tempfile-fn basename state)))
78
(not (mv-nth 0 (tempfile-fn basename state))))
79
:rule-classes :type-prescription)
81
(defthm state-p1-of-tempfile-fn
82
(implies (force (state-p1 state))
83
(state-p1 (mv-nth 1 (tempfile-fn basename state)))))))
87
(define default-tempfile-aux
88
((tempdir stringp "Directory to generate the file in")
89
(basename stringp "Base name to use for the new file")
91
:returns (mv (tempfile "Somethign like @('$TEMPDIR/$USER-$PID-$BASENAME')"
92
(or (stringp tempfile)
94
:rule-classes :type-prescription)
95
(state state-p1 :hyp (force (state-p1 state))))
98
:short "Join together a temp directory, the user name, the PID, and the base
99
name to create a temporary filename."
101
(b* (((mv pid state) (getpid state))
103
(er hard? __function__ "getpid failed")
105
((mv ?err user state) (getenv$ "USER" state))
106
((unless (stringp user))
107
(er hard? __function__ "reading $USER failed")
109
(filename (str::cat user "-" (str::natstr pid) "-" basename))
110
(path (catpath tempdir filename)))
115
(define default-tempdir (state)
116
:returns (mv (tempdir "Directory to use for temporary files."
117
stringp :rule-classes :type-prescription)
118
(state state-p1 :hyp (force (state-p1 state))))
121
:short "Figure out what directory to use for temporary files."
122
:long "<p>We think it's conventional for Linux programs to look at the value
123
of the @('TMPDIR') environment variable. On Windows, apparently programs
124
should use @('TEMP'). If either of these is set, we try to respect the choice.
125
Otherwise, we just default to @('/tmp').</p>"
127
(b* (((mv ?err tempdir state) (getenv$ "TMPDIR" state))
128
((mv ?err temp state) (getenv$ "TEMP" state)))
129
(mv (or (and (stringp tempdir) tempdir)
130
(and (stringp temp) temp)
135
(define default-tempfile ((basename stringp)
137
:returns (mv (tempfile (or (stringp tempfile)
139
:rule-classes :type-prescription)
140
(state state-p1 :hyp (force (state-p1 state))))
142
:short "Default way to generate temporary file names."
143
(b* (((mv dir state) (default-tempdir state)))
144
(default-tempfile-aux dir basename state)))
147
(defattach tempfile-fn default-tempfile)
34
(include-book "tempfile-logic")