Date: Wed, 15 Oct 1997 15:13:26 +0200 (IST) From: Eli Zaretskii To: djgpp-workers AT delorie DOT com Subject: Enhanced tempnam Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk The latest snapshot already solves the problem whereby `tempnam' didn't return malloc'ed buffer. But I wrote a version which doesn't ignore its arguments, and updated the docs accordingly. Here's the diffs against the latest snapshot: *** src/libc/compat/stdio/tempnam.c~2 Fri Oct 10 02:11:10 1997 --- src/libc/compat/stdio/tempnam.c Wed Oct 15 14:46:42 1997 *************** *** 1,11 **** /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include - #include #include - /* ARGSUSED */ char * ! tempnam(const char *_dir, const char *_prefix) { ! return strdup(tmpnam(0)); } --- 1,98 ---- + /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include + #include + #include + + #ifndef P_tmpdir + #define P_tmpdir "c:/" + #endif + + static const char *tdirs[] = {"TMPDIR", "TEMP", "TMP", 0}; + static const char x8[] = "XXXXXXXX"; + static const size_t x8len = sizeof (x8) - 1; char * ! tempnam(const char *tmpdir, const char *pfx) ! { ! char template[FILENAME_MAX]; ! size_t lastc; ! char *s, *fname; ! const char **p = tdirs; ! ! /* Supply a default directory, if they didn't. */ ! while (!tmpdir || !*tmpdir || access (tmpdir, D_OK)) ! { ! if (!*p) ! { ! tmpdir = P_tmpdir; ! if (access (tmpdir, D_OK)) ! return (char *)0; /* can this ever happen? */ ! break; ! } ! tmpdir = getenv (*p++); ! } ! ! /* Append a slash, if needed. */ ! lastc = strlen (strcpy (template, tmpdir)) - 1; ! if (template[lastc] != '/' && template[lastc] != '\\') ! template[++lastc] = '/'; ! ! /* Append the prefix. */ ! if (!pfx || !*pfx) ! pfx = "tm"; ! strcpy (template + lastc + 1, pfx); ! ! /* Create the template. */ ! strncat (template, x8, 8 - strlen (pfx)); ! ! s = mktemp (template); ! if (s) ! { ! fname = (char *)malloc (strlen (s) + 1); ! ! if (fname) ! return strcpy (fname, s); ! } ! return (char *)0; ! } ! ! #ifdef TEST ! ! #include ! ! int main (void) { ! cprintf ("tempnam (\"c:/tmp/\", \"foo\") -> \"%s\"\r\n", ! tempnam ("c:/tmp/", "foo")); getch(); ! cprintf ("tempnam (\"c:/tmp\", \"foo\") -> \"%s\"\r\n", ! tempnam ("c:/tmp", "foo")); getch(); ! cprintf ("tempnam (\"c:/tmp\", \"zoobarically-long\") -> \"%s\"\r\n", ! tempnam ("c:/tmp", "zoobarically-long")); getch(); ! cprintf ("tempnam (\"c:/tmp/\", NULL) -> \"%s\"\r\n", ! tempnam ("c:/tmp/", 0)); getch(); ! cprintf ("tempnam (\"c:/tmp/\", \"\") -> \"%s\"\r\n", ! tempnam ("c:/tmp/", "")); getch(); ! cprintf ("tempnam (\"x:/no:such:dir/\", \"foo\") -> \"%s\"\r\n", ! tempnam ("x:/no:such:dir/", "foo")); getch(); ! cprintf ("tempnam (\"\", \"foo\") -> \"%s\"\r\n", ! tempnam ("", "foo")); getch(); ! cprintf ("tempnam (NULL, \"foo\") -> \"%s\"\r\n", ! tempnam (0, "foo")); getch(); ! putenv ("TMPDIR="); cprintf ("no TMPDIR: "); ! cprintf ("tempnam (\"x:/no:such:dir/\", \"foo\") -> \"%s\"\r\n", ! tempnam ("x:/no:such:dir/", "foo")); getch(); ! putenv ("TEMP="); cprintf ("no TMPDIR, no TEMP: "); ! cprintf ("tempnam (\"x:/no:such:dir/\", \"foo\") -> \"%s\"\r\n", ! tempnam ("x:/no:such:dir/", "foo")); getch(); ! putenv ("TMP="); cprintf ("no TMPDIR, no TEMP, no TMP: "); ! cprintf ("tempnam (\"x:/no:such:dir/\", \"foo\") -> \"%s\"\r\n", ! tempnam ("x:/no:such:dir/", "foo")); getch(); ! putenv ("TEMP=."); cprintf ("TEMP=.: "); ! cprintf ("tempnam (\"x:/no:such:dir/\", \"foo\") -> \"%s\"\r\n", ! tempnam ("x:/no:such:dir/", "foo")); getch(); ! return 0; } + + #endif *** src/libc/compat/stdio/tempnam.t~0 Sun Aug 31 20:13:18 1997 --- src/libc/compat/stdio/tempnam.txh Wed Oct 15 14:49:14 1997 *************** *** 1,19 **** ! @node tempnam, stdio @subheading Syntax @example #include ! char *tempnam(const char *dir, const char *prefix); @end example @subheading Description ! Currently, this function ignores its arguments and just calls ! @pxref{tmpnam}. @subheading Return Value ! Pointer to internal static buffer that contains currently unused ! valid filename. --- 1,63 ---- ! @c ---------------------------------------------------------------------- ! ! @node tempnam, file system @subheading Syntax @example #include ! char * tempnam(const char *tmpdir, const char *prefix); @end example @subheading Description ! This function generates a file name which can be used for a temporary ! file, and makes sure that no other file by that name exists. ! ! The caller has control on the choice of the temporary file's directory, ! and the initial letters of the file's basename. If the argument ! @var{tmpdir} points to the name of the directory in which the temporary ! file will be created, @code{tempnam} will ensure that the generate name ! is unique @strong{in that directory}. If the argument @var{prefix} ! points to a string, then that string will be used as the first few ! characters of the file's basename. Due to limitations of the DOS 8.3 ! file namespace, only up to two first characters in @var{prefix} will be ! used. ! ! If @var{tmpdir} is @code{NULL}, or empty, or points to a non-existent ! directory, @code{tempnam} will use a default directory. the default ! directory is determined by testing, in sequence, the directories ! defiuned by the values of environment variables @code{TMPDIR}, ! @code{TEMP} and @code{TMP}. The first variable that is found to point ! to an existing directory will be used. If none of these variables ! specify a valid directory, @code{tempnam} will use the static default ! path prefix defined by @code{P_tmpdir} on @file{}, or ! @code{"c:/"}, in that order. ! ! If @var{prefix} is @code{NULL} or empty, @code{tempnam} will supply its ! own default prefix @code{"tm"}. ! ! @code{tempnam} puts the generated name into space allocated by ! @code{malloc}. It is up to the caller to free that space when it is no ! longer needed. ! ! Note that @code{tempnam} does not actually create the file, nor does it ! ensure in any way that the file will be automatically deleted when it's ! no longer used. It is the user's responsibility to do that. @subheading Return Value ! On success, @code{tempnam} returns a pointer to space (allocated with a ! call to @code{malloc}) where the file name is constructed. If ! @code{malloc} failed to provide sufficient memory buffer, or if no valid ! directory to hold the file was found, @code{tempnam} returns a ! @code{NULL} pointer. + @subheading Example + + @example + #include + + tempnam ("c:/tmp/", "foo"); + + @end example *** include/stdio.h~0 Mon Aug 28 00:04:36 1995 --- include/stdio.h Wed Oct 15 14:51:16 1997 *************** *** 114,119 **** --- 114,121 ---- #define stdprn (&__dj_stdprn) #define stdaux (&__dj_stdaux) + #define P_tmpdir "c:/" + void _djstat_describe_lossage(FILE *_to_where); int _doprnt(const char *_fmt, va_list _args, FILE *_f); int _doscan(FILE *_f, const char *_fmt, void **_argp);