sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

commit 347f0828f3b13f3ddca7ca74edce7cf1cd298d73
parent 590f34c4a9a4dd41becb8868240f3c3151ae3f93
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Sat,  9 May 2015 20:38:20 +0200

mktemp improvements

- add -p dir, -t and -u.
- fix dirname(tmp) check (did not check null terminator).

the semantics of mktemp is now the same as OpenBSD mktemp.

Diffstat:
Mmktemp.1 | 22++++++++++++++++++++--
Mmktemp.c | 47++++++++++++++++++++++++++++++++++-------------
2 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/mktemp.1 b/mktemp.1 @@ -1,4 +1,4 @@ -.Dd January 31, 2015 +.Dd May 8, 2015 .Dt MKTEMP 1 .Os sbase .Sh NAME @@ -6,7 +6,8 @@ .Nd create temporary file or directory .Sh SYNOPSIS .Nm -.Op Fl dq +.Op Fl dqtu +.Op Fl p Ar directory .Op Ar template .Sh DESCRIPTION .Nm @@ -20,8 +21,25 @@ tmpdir set to '/tmp' or, if set, the TMPDIR environment variable. .Bl -tag -width Ds .It Fl d Create a temporary directory instead of a file. +.It Fl p Ar directory +Use the specified +.Ar directory +as a prefix when generating the temporary filename. The directory will be +overridden by the user's +.Ev TMPDIR +environment variable if it is set. This option implies the +.Fl t +flag (see below). .It Fl q Fail silently if an error occurs. +.It Fl t +Generate a path rooted in a temporary directory. +.It Fl u +Unlink file before +.Nm +exits. This is slightly better than +.Xr mktemp 3 +but still introduces a race condition. Use of this option is not encouraged. .El .Sh SEE ALSO .Xr mkdtemp 3 , diff --git a/mktemp.c b/mktemp.c @@ -2,6 +2,7 @@ #include <libgen.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include "util.h" @@ -9,24 +10,34 @@ static void usage(void) { - eprintf("usage: %s [-dq] [template]\n", argv0); + eprintf("usage: %s [-dqtu] [-p directory] [template]\n", argv0); } int main(int argc, char *argv[]) { - int dflag = 0, qflag = 0, fd; - char *template = "tmp.XXXXXXXXXX", - *tmpdir = "/tmp", *p, - path[PATH_MAX], tmp[PATH_MAX]; + int dflag = 0, pflag = 0, qflag = 0, tflag = 0, uflag = 0, fd; + char *template = "tmp.XXXXXXXXXX", *tmpdir = "", *pdir, + *p, path[PATH_MAX], tmp[PATH_MAX]; + size_t len; ARGBEGIN { case 'd': dflag = 1; break; + case 'p': + pflag = 1; + pdir = EARGF(usage()); + break; case 'q': qflag = 1; break; + case 't': + tflag = 1; + break; + case 'u': + uflag = 1; + break; default: usage(); } ARGEND; @@ -36,18 +47,26 @@ main(int argc, char *argv[]) else if (argc == 1) template = argv[0]; - if ((p = getenv("TMPDIR"))) - tmpdir = p; + if (!argc || pflag || tflag) { + if ((p = getenv("TMPDIR"))) + tmpdir = p; + else if (pflag) + tmpdir = pdir; + else + tmpdir = "/tmp"; + } + + len = estrlcpy(path, tmpdir, sizeof(path)); + if (path[0] && path[len - 1] != '/') + estrlcat(path, "/", sizeof(path)); estrlcpy(tmp, template, sizeof(tmp)); p = dirname(tmp); - if (p[0] != '.') { - estrlcpy(path, template, sizeof(path)); - } else { - estrlcpy(path, tmpdir, sizeof(path)); - estrlcat(path, "/", sizeof(path)); - estrlcat(path, template, sizeof(path)); + if (!(p[0] == '.' && p[1] == '\0')) { + if (tflag && !pflag) + eprintf("template must not contain directory separators in -t mode\n"); } + estrlcat(path, template, sizeof(path)); if (dflag) { if (!mkdtemp(path)) { @@ -64,6 +83,8 @@ main(int argc, char *argv[]) if (close(fd)) eprintf("close %s:", path); } + if (uflag) + unlink(path); puts(path); efshut(stdout, "<stdout>");