X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f X-Recipient: djgpp-workers AT delorie DOT com Message-ID: <52BDF3B8.5020205@gmx.de> Date: Fri, 27 Dec 2013 22:40:08 +0100 From: Juan Manuel Guerrero 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: Implementation of mkdtemp. Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K0:+H01p/cohkRfCMTpioNyxhzakiP7y7KlL0IwdkzJ5oWt7AuRHDl jsMjptGqhU9S03XHW8tO1I5q1MtlVrH/xhRHyfMu1yjnZtcuLqwVHDYdsWfrP7Pm1h6950K hN00TIgrDJ1uADBIrbvnTYqqz+FAPV0HneJ5aW32DdkSnMByfgDb2fubkGdsT2Tc45DoeNo 6lBegpmv1crrf77M7vstw== Reply-To: djgpp-workers AT delorie DOT com 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. Regards, Juan M. Guerrero 2013-12-23 Juan Manuel Guerrero * 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 targets. * djgpp/tests/libc/posix/stdlib/mkdtemp.c: Checks for mkdtemp. 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 2013-12-23 23:05:30 +0100 @@ -107,10 +107,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 2013-12-23 23:02:18 +0100 +++ djgpp/src/docs/kb/wc204.txi 2013-12-23 23:05:30 +0100 @@ -1372,5 +1372,10 @@ The @code{memalign} declaration has been @cindex @acronym{POSIX} 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{POSIX} 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 2013-12-23 23:05:30 +0100 @@ -1,11 +1,13 @@ +# 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 2013-12-23 23:08:24 +0100 @@ -0,0 +1,47 @@ +/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */ +#include +#include +#include +#include +#include +#include + +char * +mkdtemp(char *_template) +{ + register int i, len; + + + for (i = 0; _template[i]; i++) + ; + for (len = i; len - i < 7 && _template[--i] == 'X';) + ; + if (len - i < 7) + { + errno = EINVAL; + return NULL; + } + else + { + 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 2013-12-23 23:09:56 +0100 @@ -0,0 +1,42 @@ +@node mkdtemp, file system +@findex mkdtemp +@subheading Syntax + +@example +#include + +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 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 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, "/tmp/ddXXXXXX"); +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 2013-12-23 23:05:30 +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 2013-12-23 23:05:30 +0100 @@ -0,0 +1,32 @@ +#include +#include +#include +#include + + +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; +}