-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lack of cross-platform function to create temporary directory #189
Comments
Below is an initial sketch. # https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2w
(defn windows-temp-root
[]
(os/getenv "TMP"
(os/getenv "TEMP"
(os/getenv "USERPROFILE"
# XXX
(os/getenv "WINDIR")))))
# https://en.cppreference.com/w/cpp/filesystem/temp_directory_path
(defn posix-temp-root
[]
(os/getenv "TMPDIR"
(os/getenv "TMP"
(os/getenv "TEMP"
(os/getenv "TEMPDIR" "/tmp")))))
(defn temp-root
[]
(case (os/which)
# see comment above function definition
:windows (windows-temp-root)
# XXX: unsure
:mingw "/tmp"
# XXX: unsure, but https://cygwin.com/cygwin-ug-net/setup-env.html
:cygwin "/tmp"
# https://ss64.com/mac/syntax-env_vars.html
:macos (os/getenv "TMPDIR")
# https://emscripten.org/docs/api_reference/Filesystem-API.html
:web "/tmp"
# https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard
:linux "/tmp"
# https://www.freebsd.org/cgi/man.cgi?query=hier&sektion=7
:freebsd "/tmp"
# https://man.openbsd.org/hier.7
:openbsd "/tmp"
# https://man.netbsd.org/hier.7
:netbsd "/tmp"
# https://leaf.dragonflybsd.org/cgi/web-man?command=hier§ion=7
:dragonfly "/tmp"
# based on the *bsd info above, following seems reasonable
:bsd "/tmp"
# see comment above function definition
:posix (posix-temp-root)
(errorf "unrecognized os: %n" (os/which))))
(defn mk-temp-dir
``
Tries to create a new subdirectory of a system-specific temporary
directory. Optional argument `template` is used to specify a
template for the new subdirectory's name. Each forward slash (`/`)
in the template is replaced with some hex value (0-9, a-f) to result
in a candidate name. The default value of `template` is `//////`.
Optional argument `tries` is the maximum number of subdirectory
creation attempts. The default value of `tries` is 5. Upon
success, returns the full path of the newly created subdirectory.
``
[&opt template tries]
(default template "//////")
(default tries 5)
(def fs-sep (if (= :windows (os/which)) `\` "/"))
(assert (not (empty? template))
"template should be a non-empty string")
(assert (and (nat? tries) (pos? tries))
(string/format "tries should be a positive integer, not: %d"
tries))
(def tmp-root (temp-root))
(assert (= :directory (os/stat tmp-root :mode))
(string/format "failed to find temp root `%s` for os `%s"
tmp-root (os/which)))
(def rng (math/rng (os/cryptorand 8)))
(defn rand-hex [_] (string/format "%x" (math/rng-int rng 16)))
(var result nil)
(for i 0 tries
(def cand-path
(string tmp-root fs-sep (string/replace-all "/" rand-hex template)))
(when (os/mkdir cand-path)
(set result cand-path)
(break result)))
(when (not result)
(errorf "failed to create new temp directory after %d tries" tries))
result)
(comment
(peg/match ~(repeat 6 :h)
(reverse (mk-temp-dir)))
# =>
@[]
(peg/match ~(sequence (thru "hello-")
(repeat 3 :h))
(mk-temp-dir "hello-///"))
# =>
@[]
(do
(def [success? _] (protect (mk-temp-dir "")))
(not success?))
# =>
true
) |
Perhaps it could be useful to honor certain environment variables if users would prefer use of non-system locations. The current sketch does something like this for some cases but not all. Candidate env vars for this purpose include:
May be better to avoid this kind of complication initially (^^; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
On more than one occasion, I've wanted to create a (previously non-existent) temporary directory to dump some files in. I'm guessing others have too (^^;
By "cross-platform", I'm mostly meaning various BSDs, Linux, macos, and recent Windows.
Did a bit of searching and have come up with the following links:
/tmp
and/var/tmp
$TMPDIR
$TMP
,$TEMP
,$USERPROFILE
,GetTempPath2
Following is a sketch of a possible flow:
The focus here is not on hiding things away (like is done in parts of Python's tempfile library), but just to have some place that won't accidentally get used.
Does this sound like:
The text was updated successfully, but these errors were encountered: