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); }
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"