summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/ChangeLog.txt2
-rw-r--r--apps/nshlib/Kconfig11
-rw-r--r--apps/nshlib/nsh.h4
-rw-r--r--apps/nshlib/nsh_parse.c2
-rwxr-xr-xnuttx/ChangeLog8
-rw-r--r--nuttx/Documentation/NuttxUserGuide.html45
-rw-r--r--nuttx/include/stdio.h22
-rw-r--r--nuttx/include/stdlib.h4
-rw-r--r--nuttx/libc/Kconfig21
-rw-r--r--nuttx/libc/stdio/Make.defs4
-rw-r--r--nuttx/libc/stdio/lib_tempnam.c105
-rw-r--r--nuttx/libc/stdio/lib_tmpnam.c95
-rw-r--r--nuttx/libc/stdlib/Make.defs4
-rw-r--r--nuttx/libc/stdlib/lib_mkstemp.c297
-rw-r--r--nuttx/libc/stdlib/lib_mktemp.c81
15 files changed, 673 insertions, 32 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index a246f462c0..df7295df27 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -1095,3 +1095,5 @@
issues. From Radoslaw Adamczyk (2014-10-23).
* apps/examples/keypadtest/keypadtest_main.c: Fixes to keypadtest from
Pierre-Noel Bouteville (2014-10-23).
+ * apps/nshlib/nsh_parse.c, nsh.h, and Kconfig: Move CONFIG_NSH_TMPDIR
+ to CONFIG_LIBC_TMPDIR (2014-11-05).
diff --git a/apps/nshlib/Kconfig b/apps/nshlib/Kconfig
index ba9c718b4a..3e212e7462 100644
--- a/apps/nshlib/Kconfig
+++ b/apps/nshlib/Kconfig
@@ -77,17 +77,6 @@ config NSH_CMDPARMS
Because this feature commits significant resources, it is disabled by
default.
-config NSH_TMPDIR
- string "Temporary file directory"
- default "/tmp"
- depends on NSH_CMDPARMS
- ---help---
- If NSH_CMDPARMS is selected, then function output will be retained
- in a temporary file. In that case, this string must be provided to
- specify the full path to a directory where temporary files can be
- created. This would be a good application of RAM disk: To provide
- temporary storage for function output.
-
config NSH_MAXARGUMENTS
int "Maximum number of command arguments"
default 6
diff --git a/apps/nshlib/nsh.h b/apps/nshlib/nsh.h
index dc13e3753a..d726b5253e 100644
--- a/apps/nshlib/nsh.h
+++ b/apps/nshlib/nsh.h
@@ -100,8 +100,8 @@
* hold temporary files must be provided.
*/
-#if defined(CONFIG_NSH_CMDPARMS) && !defined(CONFIG_NSH_TMPDIR)
-# define CONFIG_NSH_TMPDIR "/tmp"
+#if defined(CONFIG_NSH_CMDPARMS) && !defined(CONFIG_LIBC_TMPDIR)
+# define CONFIG_LIBC_TMPDIR "/tmp"
#endif
/* Networking support. Make sure that all non-boolean configuration
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c
index 2ed9452cf6..a7a35e8f21 100644
--- a/apps/nshlib/nsh_parse.c
+++ b/apps/nshlib/nsh_parse.c
@@ -874,7 +874,7 @@ static FAR char *nsh_cmdparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
/* Create a unique file name using the task ID */
tmpfile = NULL;
- ret = asprintf(&tmpfile, "%s/TMP%d.dat", CONFIG_NSH_TMPDIR, getpid());
+ ret = asprintf(&tmpfile, "%s/TMP%d.dat", CONFIG_LIBC_TMPDIR, getpid());
if (ret < 0 || !tmpfile)
{
nsh_output(vtbl, g_fmtcmdoutofmemory, "``");
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 509d45adfc..538954973f 100755
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -8904,5 +8904,9 @@
(2014-10-29).
* configs/efm32gg-stk3700: Board support for the SiLbas EFM32GG
Giant Gecko Starter kit. Current with basic NSH configuration only.
- Testing is on hold until I receive hardware (20145-11-03).
-
+ Testing is on hold until I receive hardware (2014-11-03).
+ * libc/Kconfig: Move CONFIG_NSH_TMPDIR to CONFIG_LIBC_TMPDIR (2014-11-05).
+ * libc/stdlib/lib_mkstemp.c, lib_mktemp.c, Make.defs and include/stdlib.h:
+ Add mktemp() and mkstemp() (2014-11-05).
+ * libc/stdio/lib_tempnam.c, lib_tmpnam.c, Kconfig, Make.defs and
+ include/stdio.h: Add tmpnam() and tempnam() (2014-11-05).
diff --git a/nuttx/Documentation/NuttxUserGuide.html b/nuttx/Documentation/NuttxUserGuide.html
index fc51da5920..44445e8ce0 100644
--- a/nuttx/Documentation/NuttxUserGuide.html
+++ b/nuttx/Documentation/NuttxUserGuide.html
@@ -13,7 +13,7 @@
<h1><big><font color="#3c34ec"><i>NuttX Operating System<p>User's Manual</i></font></big></h1>
<p><small>by</small></p>
<p>Gregory Nutt<p>
- <p>Last Updated: October 4, 2014</p>
+ <p>Last Updated: November 5, 2014</p>
</td>
</tr>
</table>
@@ -7629,11 +7629,12 @@ interface of the same name.
<li><a href="#directoryoperations">2.10.3 Directory Operations</a></li>
<li><a href="#dirunistdops">2.10.4 UNIX Standard Operations</a></li>
<li><a href="#standardio">2.10.5 Standard I/O</a></li>
- <li><a href="#aio">2.10.6 Asynchronous I/O</a></li>
- <li><a href="#stdstrings">2.10.7 Standard String Operations</a></li>
- <li><a href="#PipesNFifos">2.10.8 Pipes and FIFOs</a></li>
- <li><a href="#fatsupport">2.10.9 FAT File System Support</a></li>
- <li><a href="#mmapxip">2.10.10 <code>mmap()</code> and eXecute In Place (XIP)</a></li>
+ <li><a href="#standardlib">2.10.6 Standard Library</a></li>
+ <li><a href="#aio">2.10.7 Asynchronous I/O</a></li>
+ <li><a href="#stdstrings">2.10.8 Standard String Operations</a></li>
+ <li><a href="#PipesNFifos">2.10.9 Pipes and FIFOs</a></li>
+ <li><a href="#fatsupport">2.10.10 FAT File System Support</a></li>
+ <li><a href="#mmapxip">2.10.11 <code>mmap()</code> and eXecute In Place (XIP)</a></li>
</ul>
<h3><a name="FileSystemOverview">2.10.1 NuttX File System Overview</a></h3>
@@ -7953,6 +7954,8 @@ int dprintf(int fd, FAR const char *fmt, ...);
int vdprintf(int fd, FAR const char *fmt, va_list ap);
int statfs(FAR const char *path, FAR struct statfs *buf);
+FAR char *tmpnam(FAR char *s);
+FAR char *tempnam(FAR const char *dir, FAR const char *pfx);
#include &lt;sys/stat.h&gt;
@@ -7967,7 +7970,19 @@ int statfs(const char *path, struct statfs *buf);
int fstatfs(int fd, struct statfs *buf);
</pre></ul>
-<h3><a name="aio">2.10.6 Asynchronous I/O</a></h3>
+<h3><a name="standardlib">2.10.6 Standard Library</a></h3>
+<p>
+ <code>stdlib.h</code> generally addresses other operating system interfaces.
+ However, the following may also be considered as file system interfaces:
+</p>
+<ul><pre>
+#include &lt;stdlib.h&gt;
+
+int mktemp(FAR char *template);
+int mkstemp(FAR char *template);
+</pre></ul>
+
+<h3><a name="aio">2.10.7 Asynchronous I/O</a></h3>
<ul><pre>
#include &lt;aio.h&gt;
@@ -7983,7 +7998,7 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent,
FAR struct sigevent *sig);
</pre></ul>
-<h3><a name="stdstrings">2.10.7 Standard String Operations</a></h3>
+<h3><a name="stdstrings">2.10.8 Standard String Operations</a></h3>
<ul><pre>
#include &lt;string.h&gt;
@@ -8017,9 +8032,9 @@ void *memmove(void *dest, const void *src, size_t count);
# define bzero(s,n) (void)memset(s,0,n)
</pre></ul>
-<h3><a name="PipesNFifos">2.10.8 Pipes and FIFOs</a></h3>
+<h3><a name="PipesNFifos">2.10.9 Pipes and FIFOs</a></h3>
-<h3>2.10.8.1 <a name="pipe"><code>pipe</code></a></h3>
+<h3>2.10.9.1 <a name="pipe"><code>pipe</code></a></h3>
<p>
<b>Function Prototype:</b>
</p>
@@ -8053,7 +8068,7 @@ int pipe(int fd[2]);
</ul>
</p>
-<h3>2.10.8.2 <a name="mkfifo"><code>mkfifo</code></a></h3>
+<h3>2.10.9.2 <a name="mkfifo"><code>mkfifo</code></a></h3>
<p>
<b>Function Prototype:</b>
</p>
@@ -8100,8 +8115,8 @@ int mkfifo(FAR const char *pathname, mode_t mode);
</ul>
</p>
-<h3><a name="fatsupport">2.10.9 FAT File System Support</a></h3>
-<h3>2.10.9.1 <a name="mkfatfs"><code>mkfatfs</code></a></h3>
+<h3><a name="fatsupport">2.10.10 FAT File System Support</a></h3>
+<h3>2.10.10.1 <a name="mkfatfs"><code>mkfatfs</code></a></h3>
<p>
<b>Function Prototype:</b>
</p>
@@ -8178,7 +8193,7 @@ struct fat_format_s
</ul>
</p>
-<h3><a name="mmapxip">2.10.10 <code>mmap()</code> and eXecute In Place (XIP)</a></h3>
+<h3><a name="mmapxip">2.10.11 <code>mmap()</code> and eXecute In Place (XIP)</a></h3>
<p>
NuttX operates in a flat open address space and is focused on MCUs that do
support Memory Management Units (MMUs). Therefore, NuttX generally does not
@@ -8307,7 +8322,7 @@ struct fat_format_s
</li>
</ol>
-<h3><a name="mmap">2.10.10.1 <code>mmap</code></a></h3>
+<h3><a name="mmap">2.10.11.1 <code>mmap</code></a></h3>
<p>
<b>Function Prototype:</b>
</p>
diff --git a/nuttx/include/stdio.h b/nuttx/include/stdio.h
index bc0164aa48..cb1636679e 100644
--- a/nuttx/include/stdio.h
+++ b/nuttx/include/stdio.h
@@ -78,6 +78,26 @@
#define getchar() fgetc(stdin)
#define rewind(s) ((void)fseek((s),0,SEEK_SET))
+/* Path to the directory where temporary files can be created */
+
+#ifndef CONFIG_LIBC_TMPDIR
+# define CONFIG_LIBC_TMPDIR "/tmp"
+#endif
+
+#define P_tmpdir CONFIG_LIBC_TMPDIR
+
+/* Maximum size of character array to hold tmpnam() output. */
+
+#ifndef CONFIG_LIBC_MAX_TMPFILE
+# define CONFIG_LIBC_MAX_TMPFILE 32
+#endif
+
+#define L_tmpnam CONFIG_LIBC_MAX_TMPFILE
+
+/* the maximum number of unique temporary file names that can be generated */
+
+#define TMP_MAX 56800235584ull
+
/****************************************************************************
* Public Type Definitions
****************************************************************************/
@@ -161,6 +181,8 @@ int vdprintf(int fd, FAR const char *fmt, va_list ap);
/* Operations on paths */
int statfs(FAR const char *path, FAR struct statfs *buf);
+FAR char *tmpnam(FAR char *s);
+FAR char *tempnam(FAR const char *dir, FAR const char *pfx);
#undef EXTERN
#if defined(__cplusplus)
diff --git a/nuttx/include/stdlib.h b/nuttx/include/stdlib.h
index 127b35163d..c149e0ac11 100644
--- a/nuttx/include/stdlib.h
+++ b/nuttx/include/stdlib.h
@@ -1,7 +1,7 @@
/****************************************************************************
* include/stdlib.h
*
- * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -182,6 +182,8 @@ long int labs(long int j);
#ifdef CONFIG_HAVE_LONG_LONG
long long int llabs(long long int j);
#endif
+int mktemp(FAR char *template);
+int mkstemp(FAR char *template);
/* Sorting */
diff --git a/nuttx/libc/Kconfig b/nuttx/libc/Kconfig
index 8f9569bde0..138793aadc 100644
--- a/nuttx/libc/Kconfig
+++ b/nuttx/libc/Kconfig
@@ -192,6 +192,27 @@ config LIBC_PERROR_STDOUT
be defined, however, to provide perror() output that is serialized with
other stdout messages.
+config LIBC_TMPDIR
+ string "Temporary file directory"
+ default "/tmp"
+ depends on FS_WRITABLE
+ ---help---
+ If a write-able file system is selected, this string will be
+ provided to specify the full path to a directory where temporary
+ files can be created. This would be a good application of RAM disk:
+ To provide temporary storage for application data.
+
+config LIBC_MAX_TMPFILE
+ int "Maximum size of a temporary file path"
+ default 32
+ depends on FS_WRITABLE
+ ---help---
+ If a write-able file system is selected, then temporary file may be
+ supported at the path provided by LIBC_TMPDIR. The tmpnam() interface
+ keeps a static copy of this last filename produced; this value is the
+ maximum size of that last filename. This size is the size of the full
+ file path.
+
config ARCH_LOWPUTC
bool "Low-level console output"
default "y"
diff --git a/nuttx/libc/stdio/Make.defs b/nuttx/libc/stdio/Make.defs
index 284c725c4b..66914b30f2 100644
--- a/nuttx/libc/stdio/Make.defs
+++ b/nuttx/libc/stdio/Make.defs
@@ -66,6 +66,10 @@ CSRCS += lib_stdoutstream.c lib_stdsistream.c lib_stdsostream.c lib_perror.c
CSRCS += lib_feof.c lib_ferror.c lib_clearerr.c
endif
+
+ifeq ($(CONFIG_FS_WRITABLE),y)
+CSRCS += lib_tempnam.c lib_tmpnam.c
+endif
endif
# Other support that depends on specific, configured features.
diff --git a/nuttx/libc/stdio/lib_tempnam.c b/nuttx/libc/stdio/lib_tempnam.c
new file mode 100644
index 0000000000..cf480cdff9
--- /dev/null
+++ b/nuttx/libc/stdio/lib_tempnam.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * libc/stdio/lib_tempnam.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tempnam
+ *
+ * Description:
+ * The tempnam() function generates a pathname that may be used for a
+ * temporary file.
+ *
+ * The tempnam() function allows the user to control the choice of a
+ * directory. The dir argument points to the name of the directory in which
+ * the file is to be created. If dir is a null pointer or points to a
+ * string which is not a name for an appropriate directory, the path prefix
+ * defined as P_tmpdir in the <stdio.h> header will be used. If that
+ * directory is not accessible, an implementation-defined directory may be
+ * used.
+ *
+ * Many applications prefer their temporary files to have certain initial
+ * letter sequences in their names. The pfx argument should be used for
+ * this. This argument may be a null pointer or point to a string of up
+ * to five bytes to be used as the beginning of the filename.
+ *
+ * Returned Value:
+ * Upon successful completion, tempnam() will allocate space for a string
+ * put the generated pathname in that space, and return a pointer to it.
+ * The pointer will be suitable for use in a subsequent call to free().
+ * Otherwise, it will return a null pointer and set errno to indicate the
+ * error.
+ *
+ * The tempnam() function will fail if:
+ * ENOMEM - Insufficient storage space is available.
+ *
+ ****************************************************************************/
+
+FAR char *tempnam(FAR const char *dir, FAR const char *pfx)
+{
+ FAR char *path;
+ int ret;
+
+ (void)asprintf(&path, "%s/%s-XXXXXX.tmp", dir, pfx);
+ if (path)
+ {
+ ret = mktemp(path);
+ if (ret == OK)
+ {
+ return path;
+ }
+
+ free(path);
+ }
+
+ set_errno(ENOMEM);
+ return NULL;
+}
diff --git a/nuttx/libc/stdio/lib_tmpnam.c b/nuttx/libc/stdio/lib_tmpnam.c
new file mode 100644
index 0000000000..a11080e749
--- /dev/null
+++ b/nuttx/libc/stdio/lib_tmpnam.c
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * libc/stdio/lib_tmpnam.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tmpnam
+ *
+ * Description:
+ * The tmpnam() function generates a string that is a valid filename and
+ * that is not the same as the name of an existing file. The function is
+ * potentially capable of generating TMP_MAX different strings, but any or
+ * all of them may already be in use by existing files and thus not be
+ * suitable return values.
+ *
+ * The tmpnam() function generates a different string each time it is
+ * called from the same process, up to {TMP_MAX} times. If it is called
+ * more than {TMP_MAX} times, the behavior is implementation-defined.
+ *
+ * Returned Value:
+ * Upon successful completion, tmpnam() returns a pointer to a string. I
+ * no suitable string can be generated, the tmpnam() function will
+ * return a null pointer.
+ *
+ * If the argument s is a null pointer, tmpnam() will leave its result
+ * in an internal static object and return a pointer to that object.
+ * Subsequent calls to tmpnam() may modify the same object. If the
+ * argument s is not a null pointer, it is presumed to point to an
+ * array of at least L_tmpnam chars; tmpnam() will write its result in
+ * that array and will return the argument as its value.
+ *
+ ****************************************************************************/
+
+FAR char *tmpnam(FAR char *s)
+{
+ static char path[L_tmpnam];
+ int ret;
+
+ if (s == NULL)
+ {
+ s = path;
+ }
+
+ (void)snprintf(s, L_tmpnam, "%s/XXXXXX.tmp", P_tmpdir);
+ ret = mktemp(s);
+ return (ret == OK) ? s : NULL;
+}
diff --git a/nuttx/libc/stdlib/Make.defs b/nuttx/libc/stdlib/Make.defs
index 5501ef0c16..6a0d8ad7d8 100644
--- a/nuttx/libc/stdlib/Make.defs
+++ b/nuttx/libc/stdlib/Make.defs
@@ -40,6 +40,10 @@ CSRCS += lib_llabs.c lib_rand.c lib_qsort.c
CSRCS += lib_strtol.c lib_strtoll.c lib_strtoul.c lib_strtoull.c
CSRCS += lib_strtod.c lib_checkbase.c
+ifeq ($(CONFIG_FS_WRITABLE),y)
+CSRCS += lib_mktemp.c lib_mkstemp.c
+endif
+
# Add the stdlib directory to the build
DEPPATH += --dep-path stdlib
diff --git a/nuttx/libc/stdlib/lib_mkstemp.c b/nuttx/libc/stdlib/lib_mkstemp.c
new file mode 100644
index 0000000000..3269463f5f
--- /dev/null
+++ b/nuttx/libc/stdlib/lib_mkstemp.c
@@ -0,0 +1,297 @@
+/****************************************************************************
+ * libc/stdlib/lib_mkstemp.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <semaphore.h>
+#include <errno.h>
+
+#ifdef CONFIG_FS_WRITABLE
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+ #ifndef CONFIG_LIBC_TMPDIR
+# define CONFIG_LIBC_TMPDIR "/tmp"
+#endif
+
+#define MAX_XS 6
+#define MIN_NUMERIC 0 /* 0-9: Numeric */
+#define MAX_NUMERIC 9
+#define MIN_UPPERCASE 10 /* 10-35: Upper case */
+#define MAX_UPPERCASE 35
+#define MIN_LOWERCASE 36 /* 36-61: Lower case */
+#define MAX_LOWERCASE 61
+#define MAX_BASE62 MAX_LOWERCASE
+
+/* 62**1 = 62
+ * 62**2 = 3844
+ * 62**3 = 238328
+ * 62**4 = 14776336
+ * 62**5 = 916132832
+ * 62**6 = 56800235584 > UINT32_MAX
+ */
+
+#define BIG_XS 5
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static uint8_t g_base62[MAX_XS];
+static sem_t g_b62sem = SEM_INITIALIZER(1);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: base62_to_char
+ *
+ * Description:
+ * Convert a base62 value to a printable character.
+ *
+ ****************************************************************************/
+
+static char base62_to_char(uint8_t base62)
+{
+ if (base62 <= MAX_NUMERIC)
+ {
+ return '0' + base62;
+ }
+ else if (base62 <= MAX_UPPERCASE)
+ {
+ return 'A' + base62 - MIN_UPPERCASE;
+ }
+ else /* if (base62 <= MAX_LOWERCASE) */
+ {
+ DEBUGASSERT(base62 <= MAX_LOWERCASE);
+ return 'a' + base62 - MIN_LOWERCASE;
+ }
+}
+
+/****************************************************************************
+ * Name: incr_base62
+ *
+ * Description:
+ * increment the base62 value array.
+ *
+ ****************************************************************************/
+
+static void incr_base62(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_XS; i++)
+ {
+ if (g_base62[i] < MAX_LOWERCASE)
+ {
+ g_base62[i]++;
+ return;
+ }
+ else
+ {
+ g_base62[i] = 0;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: get_base62
+ *
+ * Description:
+ * Atomically copy and increment the base62 array.
+ *
+ ****************************************************************************/
+
+static void get_base62(FAR uint8_t *ptr)
+{
+ int ret;
+
+ while ((ret = sem_wait(&g_b62sem)) < 0)
+ {
+ DEBUGASSERT(errno == EINTR);
+ }
+
+ memcpy(ptr, g_base62, MAX_XS);
+ incr_base62();
+ sem_post(&g_b62sem);
+}
+
+/****************************************************************************
+ * Name: copy_base62
+ *
+ * Description:
+ * Copy the base62 array into the template filename, converting each
+ * base62 value to a printable character.
+ *
+ ****************************************************************************/
+
+static void copy_base62(FAR char *dest, int len)
+{
+ FAR const uint8_t *src;
+
+ src = g_base62;
+ if (len < MAX_XS)
+ {
+ src += MAX_XS - len;
+ }
+
+ for (; len > 0; len--)
+ {
+ *dest++ = base62_to_char(*src++);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mkstemp
+ *
+ * Description:
+ * The mkstemp() function replaces the contents of the string pointed to
+ * by template by a unique filename, and returns a file descriptor for the
+ * file open for reading and writing. The function thus prevents any
+ * possible race condition between testing whether the file exists and
+ * opening it for use. The string in template should look like a filename
+ * with six trailing 'X' s; mkstemp() replaces each 'X' with a character
+ * from the portable filename character set. The characters are chosen
+ * such that the resulting name does not duplicate the name of an existing
+ * file at the time of a call to mkstemp().
+ *
+ * Input Parameters:
+ * template - The base file name that will be modified to produce the
+ * unique file name. This must be a full path beginning with /tmp.
+ * This function will modify only the first XXXXXX characters within
+ * that full path.
+ *
+ * Returned Value:
+ *
+ * Upon successful completion, mkstemp() returns an open file descriptor.
+ * Otherwise, -1 is returned if no suitable file could be created.
+ *
+ ****************************************************************************/
+
+int mkstemp(FAR char *template)
+{
+ uint8_t base62[MAX_XS];
+ uint32_t retries;
+ FAR char *xptr;
+ FAR char *ptr;
+ int xlen;
+ int fd;
+ int i;
+
+ /* Count the number of X's at the end of the template */
+
+ xptr = strchr(template, 'X');
+ if (!xptr)
+ {
+ /* No Xs? There should always really be 6 */
+
+ return open(template, O_RDWR | O_CREAT | O_EXCL, 0666);
+ }
+
+ /* There is at least one.. count all of them */
+
+ for (xlen = 0, ptr = xptr; xlen < MAX_XS && *ptr == 'X'; xlen++, ptr++);
+
+ /* Ignore any X's after the sixth */
+
+ if (xlen > MAX_XS)
+ {
+ xlen = MAX_XS;
+ }
+
+ /* If xlen is small, then we need to determine the maximum number of
+ * retries before the values will repeat.
+ */
+
+ if (xlen >= BIG_XS)
+ {
+ retries = UINT32_MAX;
+ }
+ else
+ {
+ for (i = 1, retries = 62; i < xlen; i++, retries *= 62);
+ }
+
+ /* Then loop until we find a unique file name */
+
+ while (retries > 0)
+ {
+ /* Sample and increment the base62 counter */
+
+ get_base62(base62);
+
+ /* Form the candidate file name */
+
+ copy_base62(xptr, xlen);
+
+ /* Attempt to open the candidate file -- creating it exclusively
+ *
+ * REVISIT: This prohibits the use of this function to create unique
+ * directories
+ */
+
+ fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0666);
+ if (fd >= 0)
+ {
+ /* We have it... return the file descriptor */
+
+ return fd;
+ }
+ }
+
+ /* We could not find an unique filename */
+
+ return ERROR;
+}
+
+#endif /* CONFIG_FS_WRITABLE */
+
diff --git a/nuttx/libc/stdlib/lib_mktemp.c b/nuttx/libc/stdlib/lib_mktemp.c
new file mode 100644
index 0000000000..705c5cb9e3
--- /dev/null
+++ b/nuttx/libc/stdlib/lib_mktemp.c
@@ -0,0 +1,81 @@
+/****************************************************************************
+ * libc/stdlib/lib_mktemp.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef CONFIG_FS_WRITABLE
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mktemp
+ *
+ * Description:
+ * The use of mktemp is dangerous; use mkstemp instead.
+ *
+ ****************************************************************************/
+
+int mktemp(FAR char *template)
+{
+ int fd = mkstemp(template);
+ if (fd < 0)
+ {
+ return ERROR;
+ }
+
+ close(fd);
+ return OK;
+}
+
+#endif /* CONFIG_FS_WRITABLE */
+