www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2014/01/10/19:56:23

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
Message-ID: <52D08912.4080904@gmx.de>
Date: Sat, 11 Jan 2014 00:58:10 +0100
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Re: Implementation of mkdtemp.
References: <52BDF3B8 DOT 5020205 AT gmx DOT de>
In-Reply-To: <52BDF3B8.5020205@gmx.de>
X-Provags-ID: V03:K0:F6JwZa7e3GNdcem9otAINTvnigxUB1ew/RSaDHu2adSezCkUt+A
FKhpmkRKZ7n4r8vT1iU+1ifbhe/M00zkB5YEcjxPyJoF5fiQbU8ey/stwsuXq/FCndpASr9
g0OfttIsVWstTIMHFO47+IHdI290zUV0WEsetXKhDfKT74hGK5gwzEerECDe42YA8GC6FVz
iC230QJ33ONmLTYbx1LEQ==
Reply-To: djgpp-workers AT delorie DOT com

Am 27.12.2013 22:40, schrieb Juan Manuel Guerrero:
> The patch below provides an implementation of mkdtemp together with a small
> test program.  AFAIK the function is POSIX.1-2008.
> The implementation uses mktemp to create a directory from the template.
> This makes that the implementation deviates from the posix standard:
>  - due to the 8.3 file name limitation the string before XXXXXX is truncated
>    to 2 characters by mktemp.
>  - mktemp appends a .tmp extension to the created file name.
> Make mkdtemp fully POSIX posix conform would impose either to change mktemp
> or to write a new mktemp version for mkdtemp.  Changing mktemp may break old
> so I have decided to accept these deviations from standard.
> As usual, suggestions, objections, comments are welcome.
[snip]

OFYI, I committed the patch below that makes mktemp a little bit more POSIX
compliant.  Both mkstemp and mkdtemp use it to create an unique file name.
Now mktemp first checks if LFN support is available or not.  If LFN is
available mktemp will check if the passed template has at least six upper
case trailing 'X's as POSIX mandates.  If this is not the case it will abort
without changing the name template but setting EINVAL.  If the template is
valid then a file name will be created without truncating the leading part
of the template.  This means that the file name will not fit into the 8.3
limits of DOS.  If LFN support is available there is no reason to accept
the 8.3 file name limitation.  E.g.:  the prefix "foobar" in the template
foobarXXXXXX will not be truncated to "fo" as it used to be.
Also mktemp will no longer append a trailing ".tmp" extension to the file
name as this may be the case under certain circumstances.

If LFN support is not available, then mktemp behavior will be identical as it
has been before.  IOW, if only SFN support is available mktemp will work in
exactly the same way as before.  In this case there will be no user visible
changes.  I have added some checks too.


Regards,
Juan M. Guerrero


# cvs ci -m"Info about POSIX compliant behavior of mktemp added." djgpp/src/docs/kb/wc204.txi
# cvs ci -m"Copyright updated." djgpp/src/libc/compat/stdio/mkstemp.c
# cvs ci -m"Added POSIX compliant behavior to mktemp if LFN support is available." djgpp/src/libc/compat/stdio/mktemp.c
# cvs ci -m"Added documentation about POSIX compliant behavior of mktemp if LFN support is available." djgpp/src/libc/compat/stdio/mktemp.txh


2013-12-31  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>

     * djgpp/src/docs/kb/wc204.txi:  Info about POSIX compliant behavior of mktemp and mkstemp added.

     * djgpp/src/libc/compat/stdio/mkstemp.c:  Copyright updated.

     * djgpp/src/libc/compat/stdio/mktemp.c:  Added POSIX compliant behavior to mktemp if LFN support is available.

     * djgpp/src/libc/compat/stdio/mktemp.txh:  Added documentation about POSIX compliant behavior of mktemp if LFN support is available.

     * djgpp/src/libc/compat/stdio/mkstemp.txh:  Added documentation about POSIX compliant behavior of mkstemp if LFN support is available.





2013-12-23  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>


     * djgpp/include/stdlib.h:  Prototype for mkdtemp added.

     * djgpp/src/libc/posix/stdlib/mkdtemp.c:  Implementation of mkdtemp.

     * djgpp/src/libc/posix/stdlib/mkdtemp.txh:  Documentation of mkdtemp.

     * djgpp/src/libc/posix/stdlib/makefile:  mkdtemp added to target list.

     * djgpp/src/docs/kb/wc204.txi:  Info about mkdtemp added.

     * djgpp/tests/libc/posix/stdlib/makefile:  Check for mkdtemp added to target list.

     * djgpp/tests/libc/posix/stdlib/mkdtemp.c:  Checks for mkdtemp.





diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi    2013-12-31 17:31:22 +0100
+++ djgpp/src/docs/kb/wc204.txi    2014-01-09 22:21:30 +0100
@@ -1366,5 +1366,14 @@ A bug was fixed in @code{memalign} and @
  with linux and other @acronym{POSIX} compliant systems.  This has been changed
  so that the argument order now is the same that on @acronym{POSIX} compliant
  systems.  @code{valloc}, that calls @code{memalign}, has been adjusted accordingly.
  The @code{memalign} declaration has been moved from @file{stdlib.h} to
  @file{malloc.h} to comply with the @acronym{C99} standard.
+
+@findex mktemp AT r{, and @acronym{SUS} compliance}
+@findex mkstemp AT r{, and @acronym{SUS} compliance}
+The behavior of @code{mktemp} and @code{mkstemp} now depends on if @acronym{LFN} support
+is available or not.  If @acronym{LFN} support is available the generated file names
+will comply with the @acronym{POSIX} standard.  This means all characters of the template
+before the trailing six upper case @code{X}s will not be truncated to create a valid
+short file name.  If @acronym{LFN} support is not available @code{mktemp} will behave
+as before.  This means only two characters before the trailing @code{X}s will be possible.
diff -aprNU5 djgpp.orig/src/libc/compat/stdio/mkstemp.c djgpp/src/libc/compat/stdio/mkstemp.c
--- djgpp.orig/src/libc/compat/stdio/mkstemp.c    2013-12-31 18:56:00 +0100
+++ djgpp/src/libc/compat/stdio/mkstemp.c    2014-01-09 22:24:04 +0100
@@ -1,5 +1,6 @@
+/* Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
diff -aprNU5 djgpp.orig/src/libc/compat/stdio/mkstemp.txh djgpp/src/libc/compat/stdio/mkstemp.txh
--- djgpp.orig/src/libc/compat/stdio/mkstemp.txh    2009-04-13 12:35:04 +0100
+++ djgpp/src/libc/compat/stdio/mkstemp.txh    2014-01-09 22:21:30 +0100
@@ -14,13 +14,16 @@ int mkstemp(char *template);
  @code{X} characters.  This function replaces the @code{XXXXXX} with a
  set of characters such that the resulting file name names a nonexisting
  file.  It then creates and opens the file in a way which guarantees that
  no other process can access this file.

-Note that since MS-DOS is limited to eight characters for the file name,
-and since none of the @code{X}'s get replaced by a dot, you can only
-have two additional characters before the @code{X}'s.
+Note that since MS-DOS and file systems that lack of @acronym{LFN} support
+are limited to eight characters for the file name, and since none of the @code{X}'s
+get replaced by a dot, you can only have two additional characters before
+the @code{X}'s.  But if the file systems offers @acronym{LFN} support no limitation
+concerning the number of characters before the @code{X}'s is given and the
+created file names will be @acronym{POSIX} compliant.

  Note also that the path you give will be modified in place.

  @subheading Return Value

@@ -36,9 +39,9 @@ prototype is also kept in @code{<stdio.h

  @subheading Example

  @example
  char path[100];
-strcpy(path, "/tmp/ccXXXXXX");
+strcpy(path, _USE_LFN ? "/tmp/c_compilerXXXXXX" : "/tmp/ccXXXXXX");
  int fd = mkstemp(path);
  @end example

diff -aprNU5 djgpp.orig/src/libc/compat/stdio/mktemp.c djgpp/src/libc/compat/stdio/mktemp.c
--- djgpp.orig/src/libc/compat/stdio/mktemp.c    2013-12-31 14:54:02 +0100
+++ djgpp/src/libc/compat/stdio/mktemp.c    2014-01-09 22:24:06 +0100
@@ -1,82 +1,99 @@
+/* Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <libc/stubs.h>
  #include <libc/bss.h>
  #include <libc/symlink.h>
+#include <fcntl.h>
  #include <unistd.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
+#include <errno.h>

  static int mktemp_count = -1;

  char *
  mktemp(char *_template)
  {
-  static int count = 0;
-  char *cp, *dp;
-  int i, len, xcount, loopcnt;
-  char real_path[FILENAME_MAX];
+  register int i, len, xcount;
+  unsigned int use_lfn = _USE_LFN;

-  /* Reinitialize counter if we were restarted (emacs).  */
-  if (__bss_count != mktemp_count)
+  for (i = 0; _template[i]; i++)
+    ;
+  for (xcount = 0, len = i; xcount < 6  && _template[--i] == 'X'; xcount++)
+    ;
+  if (use_lfn && xcount < 6)
    {
-    mktemp_count = __bss_count;
-    count = 0;
+    errno = EINVAL;
+    return NULL;
    }
-
-  len = strlen(_template);
-  cp = _template + len;
-
-  xcount = 0;
-  while (xcount < 6 && cp > _template && cp[-1] == 'X')
-    xcount++, cp--;
-
-  if (xcount)
+  else
    {
-    dp = cp;
-    while (dp > _template && dp[-1] != '/' && dp[-1] != '\\' && dp[-1] != ':')
-      dp--;
-
-    /* Keep the first characters of the template, but turn the rest into
-       Xs.  */
-    while (cp > dp + 8 - xcount)
+    static int count = 0;
+
+    /* Reinitialize counter if we were restarted (emacs).  */
+    if (__bss_count != mktemp_count)
      {
-      *--cp = 'X';
-      xcount = (xcount >= 6) ? 6 : 1 + xcount;
+      mktemp_count = __bss_count;
+      count = 0;
      }

-    /* If dots occur too early -- squash them.  */
-    while (dp < cp)
+    if (xcount)
      {
-      if (*dp == '.') *dp = 'a';
-      dp++;
-    }
+      char *cp, *dp;
+      char real_path[FILENAME_MAX];
+      int loopcnt;

-    /* Try to add ".tmp" to the filename.  Truncate unused Xs.  */
-    if (cp + xcount + 3 < _template + len)
-      strcpy (cp + xcount, ".tmp");
-    else
-      cp[xcount] = 0;
+      dp = cp = _template + i;

-    /* This loop can run up to 2<<(5*6) times, or about 10^9 times.  */
-    for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++)
-    {
-      int c = count++;
-      for (i = 0; i < xcount; i++, c >>= 5)
-        cp[i] = "abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f];
-      if (!__solve_symlinks(_template, real_path))
+      while (dp > _template && dp[-1] != '/' && dp[-1] != '\\' && dp[-1] != ':')
+        dp--;
+
+      if (!use_lfn)
+      {
+        /* Keep the first characters of the template,
+           but turn the rest into Xs.  */
+        while (cp > dp + 8 - xcount)
+        {
+          *--cp = 'X';
+          xcount = (xcount >= 6) ? 6 : 1 + xcount;
+        }
+
+        /* If dots occur too early -- squash them.  */
+        while (dp < cp)
+        {
+          if (*dp == '.') *dp = 'a';
+          dp++;
+        }
+
+        /* Try to add ".tmp" to the filename.  Truncate unused Xs. */
+        if (cp + xcount + 3 < _template + len)
+          strcpy (cp + xcount, ".tmp");
+        else
+          cp[xcount] = 0;
+
+      }
+
+      /* This loop can run up to 2<<(5*6) times, or about 10^9 times.  */
+      for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++)
        {
-        *_template = 0;
-        return NULL;
+        int c = count++;
+        for (i = 0; i < xcount; i++, c >>= 5)
+          cp[i] = "abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f];
+        if (!__solve_symlinks(_template, real_path))
+        {
+          *_template = 0;
+          return NULL;
+        }
+        if (!__file_exists(real_path))
+          return _template;
        }
-      if (!__file_exists(real_path))
-        return _template;
      }
    }

    /* Failure:  truncate the template and return NULL.  */
    *_template = 0;
@@ -90,44 +107,52 @@ int
  main(void)
  {
    char *s, *s0;

    s = strdup (s0 = "/usr/foo/dddddddXXXXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    s = strdup (s0 = "/usr/foo/ddddddXXXXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    s = strdup (s0 = "/usr/foo/dddddXXXXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    s = strdup (s0 = "/usr/foo/ddddXXXXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    s = strdup (s0 = "/usr/foo/dddXXXXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    s = strdup (s0 = "/usr/foo/.dddXXXXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    s = strdup (s0 = "/usr/foo/dddXXYXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    s = strdup (s0 = "/usr/foo/XXXXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    s = strdup (s0 = "/usr/foo/XXXXXXXX");
+  errno = 0;
    mktemp (s);
-  printf ("%s -> %s\n", s0, s);
+  printf ("%s -> %s  errno = %d\n", s0, s, errno);

    return 0;
  }
  #endif
-
diff -aprNU5 djgpp.orig/src/libc/compat/stdio/mktemp.txh djgpp/src/libc/compat/stdio/mktemp.txh
--- djgpp.orig/src/libc/compat/stdio/mktemp.txh    2009-04-13 12:35:10 +0100
+++ djgpp/src/libc/compat/stdio/mktemp.txh    2014-01-09 22:21:30 +0100
@@ -13,13 +13,16 @@ char *mktemp(char *template);
  @var{template} is a file specification that ends with six trailing
  @code{X} characters.  This function replaces the @code{XXXXXX} with a
  set of characters such that the resulting file name names a nonexisting
  file.

-Note that since MS-DOS is limited to eight characters for the file name,
-and since none of the @code{X}'s get replaced by a dot, you can only
-have two additional characters before the @code{X}'s.
+Note that since MS-DOS and file systems that lack of @acronym{LFN} support
+are limited to eight characters for the file name, and since none of the @code{X}'s
+get replaced by a dot, you can only have two additional characters before
+the @code{X}'s.  But if the file systems offers @acronym{LFN} support no limitation
+concerning the number of characters before the @code{X}'s is given and the
+created file names will be @acronym{POSIX} compliant.

  @subheading Return Value

  If a unique name cannot be chosen, @code{NULL} is returned. Otherwise
  the resulting filename is returned.
@@ -33,11 +36,11 @@ prototype is also kept in @code{<stdio.h
  @portability !ansi, !posix

  @subheading Example

  @example
-char template[] = "/tmp/ccXXXXXX";
+char template[] = _USE_LFN ? "/tmp/c_compilerXXXXXX" : "/tmp/ccXXXXXX";
  if (mktemp(template) != NULL)
    @{
      FILE *q = fopen(template, "w");
      @dots{}
    @}

diff -aprNU5 djgpp.orig/include/stdlib.h djgpp/include/stdlib.h
--- djgpp.orig/include/stdlib.h    2013-12-03 14:39:02 +0100
+++ djgpp/include/stdlib.h    2014-01-09 22:43:18 +0100
@@ -1,5 +1,6 @@
+/* Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
@@ -107,10 +108,11 @@ unsigned long long int    strtoull(const ch
  #ifndef __STRICT_ANSI__

  long    a64l(const char *_string);
  char *    l64a(long _value);
  char *    mktemp(char *_template);
+char *    mkdtemp(char *_template);
  int    mkstemp(char *_template);
  int    putenv(char *_val);
  char *    realpath(const char *_path, char *_resolved);
  int    setenv(const char *_var, const char *_val, int _overwrite);
  int    unsetenv(const char *_var);
diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi    2014-01-09 22:36:14 +0100
+++ djgpp/src/docs/kb/wc204.txi    2014-01-09 22:42:40 +0100
@@ -1381,5 +1381,10 @@ as before.  This means only two characte
  @cindex @acronym{SUS} compliance, @code{stdio.h}
  @findex dprintf AT r{ added to the library}
  @findex vdprintf AT r{ added to the library}
  The functions @code{dprintf} and @code{vdprintf} were added to comply with
  the @acronym{POSIX} 1003.1-2008 standard.
+
+@cindex @acronym{SUS} compliance, @code{stdlib.h}
+@findex mkdtemp AT r{ added to the library}
+The function @code{mkdtemp} was added to comply with the
+@acronym{POSIX} 1003.1-2008 standard.
diff -aprNU5 djgpp.orig/src/libc/posix/stdlib/makefile djgpp/src/libc/posix/stdlib/makefile
--- djgpp.orig/src/libc/posix/stdlib/makefile    2002-10-17 23:00:24 +0100
+++ djgpp/src/libc/posix/stdlib/makefile    2014-01-09 22:44:58 +0100
@@ -1,11 +1,14 @@
+# Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details
+# Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details
  # Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details
  # Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details

  TOP=../..

  SRC += a64l.c
  SRC += l64a.c
+SRC += mkdtemp.c
  SRC += realpath.c
  SRC += unsetenv.c

  include $(TOP)/../makefile.inc
diff -aprNU5 djgpp.orig/src/libc/posix/stdlib/mkdtemp.c djgpp/src/libc/posix/stdlib/mkdtemp.c
--- djgpp.orig/src/libc/posix/stdlib/mkdtemp.c    1970-01-01 01:00:00 +0100
+++ djgpp/src/libc/posix/stdlib/mkdtemp.c    2014-01-09 22:45:00 +0100
@@ -0,0 +1,33 @@
+/* Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+#include <libc/symlink.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+char *
+mkdtemp(char *_template)
+{
+  char tmp_name[FILENAME_MAX];
+  char real_path[FILENAME_MAX];
+  int  rv;
+
+
+  do {
+    strcpy(tmp_name, _template);
+    errno = 0;
+  } while (mktemp(tmp_name) != NULL
+           && __solve_symlinks(tmp_name, real_path)
+           && (rv = mkdir(real_path, S_IWUSR))
+           && errno == EEXIST);
+
+  if (rv == 0)
+  {
+    strcpy(_template, tmp_name);
+    return _template;
+  }
+  else
+    return NULL;
+}
diff -aprNU5 djgpp.orig/src/libc/posix/stdlib/mkdtemp.txh djgpp/src/libc/posix/stdlib/mkdtemp.txh
--- djgpp.orig/src/libc/posix/stdlib/mkdtemp.txh    1970-01-01 01:00:00 +0100
+++ djgpp/src/libc/posix/stdlib/mkdtemp.txh    2014-01-09 22:42:40 +0100
@@ -0,0 +1,45 @@
+@node mkdtemp, file system
+@findex mkdtemp
+@subheading Syntax
+
+@example
+#include <stdlib.h>
+
+char *mkdtemp(char *template);
+@end example
+
+@subheading Description
+
+The @code{mkdtemp} function generates an uniquely named temporary directory
+from template.  @var{template} is a file specification that ends with six
+trailing @code{X} characters.  This function replaces the @code{XXXXXX} with
+a set of characters such that the resulting directory name names a nonexisting
+directory.  It then creates the directory.
+
+Note that since MS-DOS and file systems that lack of @acronym{LFN} support
+are limited to eight characters for the file name, and since none of the @code{X}'s
+get replaced by a dot, you can only have two additional characters before
+the @code{X}'s.  But if the file systems offers @acronym{LFN} support no limitation
+concerning the number of characters before the @code{X}'s is given and the
+created file names will be @acronym{POSIX} compliant.
+
+Note also that the path you give will be modified in place.
+
+@subheading Return Value
+
+The pointer to the modified template string on success,
+and @code{NULL} on failure, in which case @code{errno} is set
+appropriately.
+
+
+@subheading Portability
+
+@portability !ansi, posix
+
+@subheading Example
+
+@example
+char temp_dir, path[100];
+strcpy(path, _USE_LFN ? "/tmp/temp_directoryXXXXXX" : "/tmp/tdXXXXXX");
+temp_dir = mkdtemp(path);
+@end example
diff -aprNU5 djgpp.orig/tests/libc/posix/stdlib/makefile djgpp/tests/libc/posix/stdlib/makefile
--- djgpp.orig/tests/libc/posix/stdlib/makefile    1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/posix/stdlib/makefile    2014-01-09 22:42:40 +0100
@@ -0,0 +1,5 @@
+TOP=../..
+
+SRC += mkdtemp.c
+
+include $(TOP)/../makefile.inc
diff -aprNU5 djgpp.orig/tests/libc/posix/stdlib/mkdtemp.c djgpp/tests/libc/posix/stdlib/mkdtemp.c
--- djgpp.orig/tests/libc/posix/stdlib/mkdtemp.c    1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/posix/stdlib/mkdtemp.c    2014-01-09 22:42:40 +0100
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+
+int
+main(void)
+{
+  char *s;
+  const char *s0[] = {
+    "/dev/env/TMPDIR/foobarXXXXXX",
+    "/dev/env/TMPDIR/foobarXXXXXX",
+    "/dev/env/TMPDIR/foobarXXXXX",
+    "/dev/env/TMPDIR/foobarXXXXXY",
+    "/dev/env/TMPDIR/foo/barXXXXXX",
+    "/dev/env/TMPDIR/XXXXXX",
+    "/dev/env/TMPDIR/XXXXXXXX"
+  };
+  unsigned int i;
+
+
+  for (i = 0; i < sizeof s0 / sizeof s0[0]; i++)
+  {
+    s = strdup(s0[i]);
+    errno = 0;
+    mkdtemp(s);
+    printf("%s -> %s  errno = %d\n", s0[i], s, errno);
+  }
+
+  return 0;
+}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019