Eric Blake <ebb9 <at> byu.net> writes: > Now that glibc 2.11 has mkostemps, and I'm working on adding that to gnulib, it > would be nice to expose the idea of an explicit suffix to temporary file > names. But rather than require the user to count how long their suffix is, I > imagine it would make more sense to give mktemp(1) some do-what-I-mean smarts.
Before I do that, how about documenting what mktemp currently does. The proposed patch documents the current behavior, although it probably needs some tweaks (and corresponding tweaks in mktemp.c) based this email. mktemp --help is not very obvious that --tmpdir is implied if no TEMPLATE is given. Right now, 'mktemp --help' claims that --tmpdir and -p are distinct, but the code says they are almost the same (they both set use_dest_dir=true and dest_dir_arg=optarg). The only difference is that --tmpdir has an optional argument, while -p has a mandatory argument, so dest_dir_arg can be NULL if you use --tmpdir but not if you use -p. By the way, the optional argument to --subdir has some interesting effects, because we are not consistent on whether we check optarg for being the empty string: mkdir --subdir="$dir" => if $dir is empty, try $TMPDIR; if that is empty, use /tmp mkdir --subdir="$dir" -t => if $TMPDIR is empty, use $dir; if that is empty, use . In other words, the only thing that I can see -t doing is whether we first check $TMPDIR or the argument to -p/--tmpdir, and restricts us from using subdirectories in the template (is this restriction really necessary)? It doesn't even print a deprecation warning or have a FIXME date with proposed removal. So, what if we just undeprecate -t (by adding a long option), and document/implement things as follows: -p DIR, --tmpdir[=DIR] interpret TEMPLATE relative to DIR. If DIR is empty or not supplied, use $TMPDIR if set, else /tmp -t, --favor-tmpdir with -p, favor $TMPDIR over the DIR argument; otherwise use $TMPDIR or /tmp instead of current directory TEMPLATE may contain slashes, but intermediate directories must exist. If -p or -t is specified, TEMPLATE must not be absolute. Also, is there a cleanup hole? For most code paths, an exit status of 1 means that the temporary file could not be created. But consider: mktemp >/dev/full This currently gives exit status 1, because the atexit() handler recognizes failure to print the file name to stdout, but leaves the temporary file around. Should we go ahead and manually flush/close stdout, rather than relying on close_stdout, so that we can then remove the just-created file if we detect write failure? That way, if we fail to inform the user what just got created, we are at least avoiding littering their file system with a random file. Fortunately, 'mktemp >&-' does not make the mistake of printing the just- created file as the contents of that file, since we close the fd returned by mkstemp before printing anything. At any rate, here's the proposed documentation patch: From: Eric Blake <e...@byu.net> Date: Tue, 3 Nov 2009 10:47:42 -0700 Subject: [PATCH] doc: document mktemp * doc/coreutils.texi (mktemp invocation): New node. --- doc/coreutils.texi | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 142 insertions(+), 2 deletions(-) diff --git a/doc/coreutils.texi b/doc/coreutils.texi index ec5bcfb..1fd1bec 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -31,7 +31,6 @@ @c FIXME: the following need documentation @c * [: (coreutils)[ invocation. File/string tests. @c * pinky: (coreutils)pinky invocation. FIXME. -...@c * mktemp: (coreutils)mktemp invocation. FIXME. @dircategory Individual utilities @direntry @@ -80,6 +79,7 @@ * mkdir: (coreutils)mkdir invocation. Create directories. * mkfifo: (coreutils)mkfifo invocation. Create FIFOs (named pipes). * mknod: (coreutils)mknod invocation. Create special files. +* mktemp: (coreutils)mktemp invocation. Create temporary files. * mv: (coreutils)mv invocation. Rename files. * nice: (coreutils)nice invocation. Modify niceness. * nl: (coreutils)nl invocation. Number lines and write files. @@ -193,7 +193,7 @@ Top * Printing text:: echo printf yes * Conditions:: false true test expr * Redirection:: tee -* File name manipulation:: dirname basename pathchk +* File name manipulation:: dirname basename pathchk mktemp * Working context:: pwd stty printenv tty * User information:: id logname whoami groups users who * System context:: date arch uname hostname hostid uptime @@ -378,6 +378,7 @@ Top * basename invocation:: Strip directory and suffix from a file name * dirname invocation:: Strip non-directory suffix from a file name * pathchk invocation:: Check file name validity and portability +* mktemp invocation:: Create temporary file or directory Working context @@ -11876,6 +11877,7 @@ File name manipulation * basename invocation:: Strip directory and suffix from a file name. * dirname invocation:: Strip non-directory suffix from a file name. * pathchk invocation:: Check file name validity and portability. +* mktemp invocation:: Create temporary file or directory. @end menu @@ -12050,6 +12052,144 @@ pathchk invocation 1 otherwise. @end display +...@node mktemp invocation +...@section @command{mktemp}: Create temporary file or directory + +...@pindex mktemp +...@cindex file names, creating temporary +...@cindex directory, creating temporary +...@cindex temporary files and directories + +...@command{mktemp} manages the creation of temporary files and +directories. Synopsis: + +...@example +mktemp [...@var{option}]@dots{} [...@var{template}] +...@end example + +Safely create a temporary file or directory based on @var{template}, +and print its name. If given, @var{template} must end in at least +three consecutive @samp{X}. If omitted, the template +...@samp{tmp.xxxxxxxxxx} is used, and option @option{--tmpdir} is +implied. + +When creating a file, the resulting file has read and write +permissions for the current user, but no permissions for the group or +others; these permissions are reduced if the current umask is more +restrictive. + +Here are some examples (although note that if you repeat them, you +will most likely get different file names): + +...@itemize @bullet + +...@item +Create a temporary file in the current directory. +...@example +$ mktemp file.XXXX +file.H47c +...@end example + +...@item +Create a secure fifo relative to the user's choice of @env{TMPDIR}, +but falling back to the current directory rather than @file{/tmp}. +Note that @command{mktemp} does not create fifos, but can create a +secure directory in which the fifo can live. Exit the shell if the +directory or fifo could not be created. +...@example +$ dir=$(mktemp -p "$...@{tmpdir:-...@}" -d dir-XXXX) || exit 1 +$ fifo=$dir/fifo +$ mkfifo "$fifo" || @{ rmdir $dir; exit 1; @} +...@end example + +...@item +Create and use a temporary file if possible, but ignore failure. The +file will reside in the directory named by @env{TMPDIR}, if specified, +or else in @file{/tmp}. +...@example +$ file=$(mktemp -q) && @{ +> # Safe to use $file only within this block +> echo ... > $file +> rm $file +> @} +...@end example + +...@item +Act as a semi-random character generator (it is not fully random, +since it is impacted by the contents of the current directory). To +avoid security holes, do not use the resulting names to create a file. +...@example +$ mktemp -u XXX +Gb9 +$ mktemp -u XXX +nzC +...@end example + +...@end itemize + + +The program accepts the following options. Also see @ref{Common options}. + +...@table @samp + +...@item -d +...@itemx --directory +...@opindex -d +...@opindex --directory +Create a directory rather than a file. The directory will have read, +write, and execute permissions for the current user, but no +permissions for the group or others; these permissions are reduced if +the current umask is more restrictive. + +...@item -q +...@itemx --quiet +...@opindex -q +...@opindex --quiet +Suppress diagnostics about failure to create a file or directory. The +exit status will still reflect whether a file was created. + +...@item -u +...@itemx --dry-run +...@opindex -u +...@opindex --dry-run +Generate a temporary name that does not name an existing file, without +changing the file system contents. Using the output of this command +to create a new file is inherently unsafe, as there is a window of +time between generating the name and using it where another process +can create an object by the same name. + +...@item -p @var{dir} +...@itemx --tempdi...@var{dir}] +...@opindex -p +...@opindex --tempdir +Treat @var{template} relative to the directory @var{dir}. If +...@var{dir} is not specified (only possible with the long option +...@option{--tempdir}) or is the empty string, use the value of +...@env{tmpdir} if available, otherwise use @samp{/tmp}. If this is +specified, @var{template} must not be absolute. However, +...@var{template} can still contain slashes, although intermediate +directories must already exist. + +...@item -t +...@opindex -t +Treat @var{template} as a single file relative to the value of +...@env{tmpdir} if available, or to the directory specified by +...@option{-p}, otherwise to @samp{/tmp}. @var{template} must not +contain slashes. This option is deprecated; the use of @option{-p} +without @option{-t} offers better defaults (by favoring the command +line over @env{TMPDIR}) and more flexibility (by allowing intermediate +directories). + +...@end table + +...@cindex exit status of @command{mktemp} +Exit status: + +...@display +0 if the file was created, +1 otherwise. +...@end display + @node Working context @chapter Working context -- 1.6.4.2