mktemp(1) in /tmp or $PWD?
Garrett Cooper
yanefbsd at gmail.com
Fri Feb 26 05:00:46 UTC 2010
On Thu, Feb 25, 2010 at 6:50 PM, Garrett Cooper <yanefbsd at gmail.com> wrote:
> Hi Hackers,
> Really basic question (because I'm relatively new to the Unix
> scene -- only been using it for the last 10 years, so I don't know if
> this was done for backwards compatibility with SysV) -- is mktemp(1)
> without -t supposed to default to $PWD instead of /tmp if a template
> is specified, e.g.
>
> [root at left4dead /usr/home/garrcoop]# mktemp fooXXXXXX
> foovE3FLt
> [root at left4dead /usr/home/garrcoop]# ls foovE3FLt
> foovE3FLt
>
> I ask because GNU coreutils' copy of mktemp (I know... I know...)
> defaults to /tmp if $TMPDIR isn't specified.
And this is the reason why I asked...
I was getting annoyed when I ran out of space in /usr today
iteratively trying to generate mfsroots because I expected the default
temp directory to be /tmp. Turns out it wasn't, and the reason why is
that $PWD is the assumed $TMPDIR iff an argument with -t isn't
specified.
So what I did was I wrote up a patch to be *I know... here it comes*
more like GNU coreutils' copy of mktemp.
Three behavioral changes I'm proposing are:
1. If mktemp is called without a prefix or template, it will
automatically generate one file (or directory) instead of erroring
out. That way if someone wants to call mktemp, they will automatically
get a file instead of having to produce a template or prefix.
2. $TMPDIR (or /tmp if not specified) will automatically get tacked
onto each file, instead of it being implicitly $PWD; that way a bunch
of temporary files will be generated _in_ /tmp (and subsequently wiped
on each reboot if the sysadmin sets it up that way) instead of having
a boatload of temporary files spread across a machine, which the user
must clean up based on the current working directory for their
applications.
3. All files will be prefixed with `tmp' by default instead of
`mktemp' (for consistency with GNU coreutils, and also because it
allows folks to increase the size of the random string in the files).
If folks like it, I'll create a PR with this change and also update
the manpage to reflect the change.
Thanks,
-Garrett
Index: mktemp.c
===================================================================
--- mktemp.c (revision 204344)
+++ mktemp.c (working copy)
@@ -48,6 +48,12 @@
static void usage(void);
+#define MK_TEMPLATE(template) \
+ asprintf(&name, "%s%s%s", \
+ (tmpdir == NULL ? _PATH_TMP : tmpdir), \
+ (tmpdir == NULL ? "" : "/" ), \
+ template)
+
int
main(int argc, char **argv)
{
@@ -55,13 +61,13 @@
char *tmpdir;
const char *prefix;
char *name;
- int dflag, qflag, tflag, uflag;
+ int dflag, qflag, uflag;
- ret = dflag = qflag = tflag = uflag = 0;
- prefix = "mktemp";
+ ret = dflag = qflag = uflag = 0;
+ prefix = NULL;
name = NULL;
- while ((c = getopt(argc, argv, "dqt:u")) != -1)
+ while ((c = getopt(argc, argv, "dqt:u")) != -1) {
switch (c) {
case 'd':
dflag++;
@@ -73,7 +79,6 @@
case 't':
prefix = optarg;
- tflag++;
break;
case 'u':
@@ -83,16 +88,29 @@
default:
usage();
}
+ }
argc -= optind;
argv += optind;
- if (tflag) {
- tmpdir = getenv("TMPDIR");
- if (tmpdir == NULL)
- asprintf(&name, "%s%s.XXXXXXXX", _PATH_TMP, prefix);
- else
- asprintf(&name, "%s/%s.XXXXXXXX", tmpdir, prefix);
+ tmpdir = getenv("TMPDIR");
+
+ /*
+ * User didn't specify anything; let's default to a file prefixed by
+ * tmp*
+ */
+ if (prefix == NULL && argc == 0) {
+ prefix = "tmp.XXXXXX";
+ }
+
+ /*
+ * Make sure that the user specified an option with -t (or nothing
+ * at all -- which equates to a file in tmp prefixed file).
+ */
+ if (prefix != NULL) {
+
+ MK_TEMPLATE(prefix);
+
/* if this fails, the program is in big trouble already */
if (name == NULL) {
if (qflag)
@@ -100,44 +118,58 @@
else
errx(1, "cannot generate template");
}
- } else if (argc < 1) {
- usage();
+
}
-
+
/* generate all requested files */
while (name != NULL || argc > 0) {
+
if (name == NULL) {
- name = strdup(argv[0]);
+ MK_TEMPLATE(argv[0]);
argv++;
argc--;
}
- if (dflag) {
- if (mkdtemp(name) == NULL) {
- ret = 1;
- if (!qflag)
- warn("mkdtemp failed on %s", name);
+ /* Just in case asprintf(3) ala MK_TEMPLATE fails. */
+ if (name != NULL) {
+
+ if (dflag) {
+
+ if (mkdtemp(name) == NULL) {
+ ret = 1;
+ if (!qflag) {
+ warn("mkdtemp failed on %s",
+ name);
+ }
+ } else {
+ printf("%s\n", name);
+ if (uflag)
+ rmdir(name);
+ }
} else {
- printf("%s\n", name);
- if (uflag)
- rmdir(name);
+
+ fd = mkstemp(name);
+ if (fd < 0) {
+ ret = 1;
+ if (!qflag) {
+ warn("mkstemp failed on %s",
+ name);
+ }
+ } else {
+ close(fd);
+ if (uflag)
+ unlink(name);
+ printf("%s\n", name);
+ }
+
}
- } else {
- fd = mkstemp(name);
- if (fd < 0) {
- ret = 1;
- if (!qflag)
- warn("mkstemp failed on %s", name);
- } else {
- close(fd);
- if (uflag)
- unlink(name);
- printf("%s\n", name);
- }
+
+ free(name);
+
}
- if (name)
- free(name);
+
name = NULL;
+
}
return (ret);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: more-gnuish-mktemp.diff
Type: application/octet-stream
Size: 3068 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20100226/e0018ae2/more-gnuish-mktemp.obj
More information about the freebsd-hackers
mailing list