On Thu, Feb 25, 2010 at 6:50 PM, Garrett Cooper <yanef...@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.
>
> [r...@left4dead /usr/home/garrcoop]# mktemp fooXXXXXX
> foovE3FLt
> [r...@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);
 }

Attachment: more-gnuish-mktemp.diff
Description: Binary data

_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to