[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
announce: new program: mktemp
From: |
Jim Meyering |
Subject: |
announce: new program: mktemp |
Date: |
Sun, 07 Oct 2007 20:30:09 +0200 |
I've just pushed a new mktemp program for coreutils.
ChangeLog below.
Why reimplement mktemp:
Improved portability, robustness, and security.
Several weeks ago, I wrote most of the following to Todd Miller,
author of another mktemp tool/package. I'm including an edited
version of that message here:
Subject: adding mktemp to coreutils
Hi Todd,
Thanks for writing mktemp!
I've been frustrated that it is not more widely available, so looked
at its man page and wrote a mostly-compatible mktemp program that I am
nearly prepared to add to the GNU coreutils package.
Some of the differences:
uses an adaptation of glibc's mkstemp (I've changed it to use
coreutils' randint code, which makes it more secure, and lets
it degrade gracefully when e.g., /dev/urandom is not usable;
also, glibc's mkstemp uses a larger alphabet: 62 vs. 52, and
gives up after 62^3 stat calls rather than your 52^6, tho, imho
that latter doesn't matter). Likewise for mkdtemp.
provides long-style options, e.g., --directory (-d), --quiet, etc.
uses gnulib's infrastructure for things like error reporting,
and gettext support, like the rest of coreutils
detects write failures
currently doesn't support fewer than 3 X's in a template. But
I've already spec'd out code to allow just one or two X's, with
a heuristic to keep it reasonably safe and with a guarantee that
it will complete after no more than 62^X_COUNT stat calls.
most importantly, using the above mkstemp implementation, names are
less predictable, and are not generated in sequence upon retry:
compare yours:
$ for i in . . .; do mktemp -u _.XXXXXXX; done
_.Mt31935
_.fQ31936
_.BW31937
$ for i in . . .; do mktemp -u _.XXXXXXX; done
_.If31967
_.IJ31968
_.lb31969
with the new one:
$ for i in . . .; do ./mktemp -u _.XXXXXXX; done
_.2ojBe7Z
_.0oB0isC
_.yCyvyU8
$ for i in . . .; do ./mktemp -u _.XXXXXXX; done
_.W4GLDh7
_.IwpMW0a
_.vfNrmUz
This is to give you a heads-up, hoping that you see this as a good thing.
I preferred to rewrite this one, since it's so small. My "main" is only
about 70 lines, after all, if you don't count the ~50 of boilerplate
declarations and getopt option handling loop.
I see now (after rewriting) that you own the mktemp.org domain,
and have a dedicated bug-tracker. On the other hand, the last
release was 4 years ago.
Please take this as a compliment on the utility of your mktemp program,
and let me know what you think.
Regards,
Jim
===========================
He replied that he'd be happy to see mktemp more widely used, and
didn't care which version people use, as long as they're compatible.
Then I learned that on Gentoo, that same mktemp program is built so that
it requires a suffix of at least six X's in any template, and uses only the
last six of those. In that mode, it also uses glibc's mkstemp function,
so predictable names aren't a real problem. However, relying directly on
stock mkstemp from glibc means "mktemp t.XXXXX" fails on such a system,
since the template has only five X's.
So I've made Coreutils' mktemp work just like Todd's, even though I
dislike the way the -t option makes mktemp use $TMPDIR (if set),
even though another directory may have been specified via "-p DIR".
That means that people who want mktemp to honor their "-p DIR"
option will have to ensure that TMPDIR is unset first.
To provide similar functionality, but in a more usable manner,
I have added a new option that works like this:
--tmpdir[=DIR] interpret TEMPLATE relative to DIR. If DIR is
not specified, use $TMPDIR if set, else /tmp.
With this option, TEMPLATE must not be an absolute name.
Unlike with -t, TEMPLATE may contain slashes, but even
here, mktemp still creates only the final component.
In addition, I've listed the -p and -t options as "deprecated",
but expect to retain support for them for years.
As always, feedback is welcome.
Here's the full --help output:
(no .texi addition, yet)
-----------------------------------------------------
Usage: src/mktemp [OPTION]... [TEMPLATE]
Create a temporary file or directory, safely, and print its name.
If TEMPLATE is not specified, use tmp.XXXXXXXXXX.
-d, --directory create a directory, not a file
-q, --quiet suppress diagnostics about file/dir-creation failure
-u, --dry-run do not create anything; merely print a name (unsafe)
--tmpdir[=DIR] interpret TEMPLATE relative to DIR. If DIR is
not specified, use $TMPDIR if set, else /tmp.
With this option, TEMPLATE must not be an absolute name.
Unlike with -t, TEMPLATE may contain slashes, but even
here, mktemp still creates only the final component.
-p DIR use DIR as a prefix; implies -t [deprecated]
-t interpret TEMPLATE as a single file name component,
relative to a directory: $TMPDIR, if set; else the
directory specified via -p; else /tmp [deprecated]
--help display this help and exit
--version output version information and exit
Report bugs to <address@hidden>.
-----------------------------------------------------
2007-10-07 Jim Meyering <address@hidden>
http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=99b039fead8d72
New program: mktemp.
* NEWS: Mention this.
* README: Add mktemp to the list.
* AUTHORS: Add this: mktemp: Jim Meyering
* src/mktemp.c: New file.
* src/Makefile.am (bin_PROGRAMS): Add mktemp.
(mktemp_LDADD): Add $(LIB_GETHRXTIME).
* man/mktemp.x: New file.
* man/Makefile.am (dist_man_MANS): Add mktemp.1.
(mktemp.1): New dependency.
* man/.cvsignore: Add mktemp.1.
* man/.gitignore: New file.
* src/.cvsignore, src/.gitignore: Add mktemp.
* tests/misc/mktemp: New file.
* tests/misc/Makefile.am (TESTS): Add mktemp.
* tests/Coreutils.pm (run_tests): Give the POST-test function
access to stdout and stderr contents, so it can verify that
the named-on-stdout file/dir does indeed exist and has proper
permissions, etc.
[po/ChangeLog]
* POTFILES.in: Add src/mktemp.c.
http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=7eab7d027e624
Make tempname more random, via the randint module.
* gl/modules/tempname (Depends-on): Add randint and stdbool.
* gl/lib/tempname.c: Include randint.h and stdbool.h.
(uint64_t): Remove definition. Not needed.
[_LIBC] (RANDOM_BITS): Remove this block, now that we have proper
random bits.
(check_x_suffix): New function.
(gen_tempname_len): Rename from __gen_tempname.
Add a parameter, x_suffix_len, telling how many X's there must be at
the end of the template.
Use pseudo-random numbers all the way, rather than adding 7777
from one iteration to the next.
(__gen_tempname): New function, to call gen_tempname_len, requiring a
suffix length of 6.
* gl/lib/tempname.h: Add prototype for gen_tempname_len.
http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=58a7ead41d056
Convert coreutils' rand*.{c,h,m4} into modules.
First step: move these files to gl/lib:
* lib/rand-isaac.c, lib/rand-isaac.h
* lib/randint.c, lib/randint.h
* lib/randperm.c, lib/randperm.h
* lib/randread.c, lib/randread.h
Step 2: add modules/rand* and remove now-unneeded .m4 files.
* gl/modules/randint: New file.
* gl/modules/randperm: New file.
* gl/modules/randread: New file.
* m4/randint.m4: Remove file.
* m4/randperm.m4: Remove file.
* m4/randread.m4: Remove file.
Step 3: use the new modules
* bootstrap.conf (gnulib_modules): Add randint and randperm.
* m4/prereq.m4 (gl_RANDINT, gl_RANDREAD, gl_RANDPERM): Don't require;
These have been removed.
(gl_ROOT_DEV_INO): Don't require; already handled via bootstrap.conf.
http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commit;h=696f4a8042e11f6ca
Copy from gnulib the parts of tempname that we'll modify.
* gl/lib/tempname.c: Copy from gnulib.
* gl/lib/tempname.h: Likewise.
* gl/modules/tempname: Likewise.
Allow GPLv2 on temporarily(?)-imported file from gnulib/libc.
* .x-sc_GPL_version: New file.
* Makefile.am (EXTRA_DIST): Add .x-sc_GPL_version
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- announce: new program: mktemp,
Jim Meyering <=