Index: uspace/lib/posix/src/stdio.c
===================================================================
--- uspace/lib/posix/src/stdio.c	(revision 296890f3fa17c85aea7be46fe09298847901f160)
+++ uspace/lib/posix/src/stdio.c	(revision bfe90b6b7580ea944610d1ef63bd58ffa1dba441)
@@ -2,4 +2,5 @@
  * Copyright (c) 2011 Jiri Zarevucky
  * Copyright (c) 2011 Petr Koupy
+ * Copyright (c) 2018 Jiri Svoboda
  * All rights reserved.
  *
@@ -38,9 +39,12 @@
 
 #include <assert.h>
-
 #include <errno.h>
-
+#include <stdbool.h>
+#include <tmpfile.h>
+
+#include "posix/fcntl.h"
 #include "posix/stdlib.h"
 #include "posix/string.h"
+#include "posix/sys/stat.h"
 #include "posix/sys/types.h"
 #include "posix/unistd.h"
@@ -353,32 +357,38 @@
 }
 
-/**
- * Get a unique temporary file name (obsolete).
- *
- * @param s Buffer for the file name. Must be at least L_tmpnam bytes long.
- * @return The value of s on success, NULL on failure.
- */
-char *tmpnam(char *s)
-{
-	assert(L_tmpnam >= strlen("/tmp/tnXXXXXX"));
-
-	static char buffer[L_tmpnam + 1];
-	if (s == NULL) {
-		s = buffer;
-	}
-
-	strcpy(s, "/tmp/tnXXXXXX");
-	mktemp(s);
-
-	if (*s == '\0') {
-		/* Errno set by mktemp(). */
-		return NULL;
-	}
-
-	return s;
-}
-
-/**
- * Get an unique temporary file name with additional constraints (obsolete).
+/** Determine if directory is an 'appropriate' temporary directory.
+ *
+ * @param dir Directory path
+ * @return @c true iff directory is appropriate.
+ */
+static bool is_appropriate_tmpdir(const char *dir)
+{
+	struct stat sbuf;
+
+	/* Must not be NULL */
+	if (dir == NULL)
+		return false;
+
+	/* Must not be empty */
+	if (dir[0] == '\0')
+		return false;
+
+	if (stat(dir, &sbuf) != 0)
+		return false;
+
+	/* Must be a directory */
+	if ((sbuf.st_mode & S_IFMT) != S_IFDIR)
+		return false;
+
+	/* Must be writable */
+	if (access(dir, W_OK) != 0)
+		return false;
+
+	return true;
+}
+
+/** Construct unique file name.
+ *
+ * Never use this function.
  *
  * @param dir Path to directory, where the file should be created.
@@ -388,77 +398,34 @@
 char *tempnam(const char *dir, const char *pfx)
 {
-	/* Sequence number of the filename. */
-	static int seq = 0;
-
-	size_t dir_len = strlen(dir);
-	if (dir[dir_len - 1] == '/') {
-		dir_len--;
-	}
-
-	size_t pfx_len = strlen(pfx);
-	if (pfx_len > 5) {
-		pfx_len = 5;
-	}
-
-	char *result = malloc(dir_len + /* slash*/ 1 +
-	    pfx_len + /* three-digit seq */ 3 + /* .tmp */ 4 + /* nul */ 1);
-
-	if (result == NULL) {
-		errno = ENOMEM;
+	const char *dpref;
+	char *d;
+	char *buf;
+	int rc;
+
+	d = getenv("TMPDIR");
+	if (is_appropriate_tmpdir(d))
+		dpref = d;
+	else if (is_appropriate_tmpdir(dir))
+		dpref = dir;
+	else if (is_appropriate_tmpdir(P_tmpdir))
+		dpref = P_tmpdir;
+	else
+		dpref = "/";
+
+	if (dpref[strlen(dpref) - 1] != '/')
+		rc = asprintf(&buf, "%s/%sXXXXXX", dpref, pfx);
+	else
+		rc = asprintf(&buf, "%s%sXXXXXX", dpref, pfx);
+
+	if (rc < 0)
+		return NULL;
+
+	rc = __tmpfile_templ(buf, false);
+	if (rc != 0) {
+		free(buf);
 		return NULL;
 	}
 
-	char *res_ptr = result;
-	strncpy(res_ptr, dir, dir_len);
-	res_ptr += dir_len;
-	strncpy(res_ptr, pfx, pfx_len);
-	res_ptr += pfx_len;
-
-	for (; seq < 1000; ++seq) {
-		snprintf(res_ptr, 8, "%03d.tmp", seq);
-
-		int orig_errno = errno;
-		errno = EOK;
-		/* Check if the file exists. */
-		if (access(result, F_OK) == -1) {
-			if (errno == ENOENT) {
-				errno = orig_errno;
-				break;
-			} else {
-				/* errno set by access() */
-				return NULL;
-			}
-		}
-	}
-
-	if (seq == 1000) {
-		free(result);
-		errno = EINVAL;
-		return NULL;
-	}
-
-	return result;
-}
-
-/**
- * Create and open an unique temporary file.
- * The file is automatically removed when the stream is closed.
- *
- * @param dir Path to directory, where the file should be created.
- * @param pfx Optional prefix up to 5 characters long.
- * @return Newly allocated unique path for temporary file. NULL on failure.
- */
-FILE *tmpfile(void)
-{
-	char filename[] = "/tmp/tfXXXXXX";
-	int fd = mkstemp(filename);
-	if (fd == -1) {
-		/* errno set by mkstemp(). */
-		return NULL;
-	}
-
-	/* Unlink the created file, so that it's removed on close(). */
-	unlink(filename);
-	return fdopen(fd, "w+");
+	return buf;
 }
 
Index: uspace/lib/posix/src/stdlib.c
===================================================================
--- uspace/lib/posix/src/stdlib.c	(revision 296890f3fa17c85aea7be46fe09298847901f160)
+++ uspace/lib/posix/src/stdlib.c	(revision bfe90b6b7580ea944610d1ef63bd58ffa1dba441)
@@ -38,4 +38,5 @@
 
 #include <errno.h>
+#include <tmpfile.h>
 
 #include "posix/fcntl.h"
@@ -163,23 +164,26 @@
 int mkstemp(char *tmpl)
 {
-	int fd = -1;
-
-	char *tptr = tmpl + strlen(tmpl) - 6;
-
-	while (fd < 0) {
-		if (*mktemp(tmpl) == '\0') {
-			/* Errno set by mktemp(). */
-			return -1;
-		}
-
-		fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
-
-		if (fd == -1) {
-			/* Restore template to it's original state. */
-			snprintf(tptr, 7, "XXXXXX");
-		}
-	}
-
-	return fd;
+	int tmpl_len;
+	int file;
+
+	tmpl_len = strlen(tmpl);
+	if (tmpl_len < 6) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	char *tptr = tmpl + tmpl_len - 6;
+	if (strcmp(tptr, "XXXXXX") != 0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	file = __tmpfile_templ(tmpl, true);
+	if (file < 0) {
+		errno = EIO; // XXX could be more specific
+		return -1;
+	}
+
+	return file;
 }
 
@@ -194,5 +198,8 @@
 char *mktemp(char *tmpl)
 {
-	int tmpl_len = strlen(tmpl);
+	int tmpl_len;
+	int rc;
+
+	tmpl_len = strlen(tmpl);
 	if (tmpl_len < 6) {
 		errno = EINVAL;
@@ -208,26 +215,7 @@
 	}
 
-	static int seq = 0;
-
-	for (; seq < 1000000; ++seq) {
-		snprintf(tptr, 7, "%06d", seq);
-
-		int orig_errno = errno;
-		errno = 0;
-		/* Check if the file exists. */
-		if (access(tmpl, F_OK) == -1) {
-			if (errno == ENOENT) {
-				errno = orig_errno;
-				break;
-			} else {
-				/* errno set by access() */
-				*tmpl = '\0';
-				return tmpl;
-			}
-		}
-	}
-
-	if (seq == 10000000) {
-		errno = EEXIST;
+	rc = __tmpfile_templ(tmpl, false);
+	if (rc != 0) {
+		errno = EIO; // XXX could be more specific
 		*tmpl = '\0';
 		return tmpl;
Index: uspace/lib/posix/src/unistd.c
===================================================================
--- uspace/lib/posix/src/unistd.c	(revision 296890f3fa17c85aea7be46fe09298847901f160)
+++ uspace/lib/posix/src/unistd.c	(revision bfe90b6b7580ea944610d1ef63bd58ffa1dba441)
@@ -39,5 +39,7 @@
 #include <errno.h>
 
+#include "posix/dirent.h"
 #include "posix/string.h"
+#include "posix/sys/types.h"
 #include "posix/fcntl.h"
 
@@ -368,8 +370,14 @@
 		 */
 		int fd = open(path, O_RDONLY);
-		if (fd < 0)
-			return -1;
-		close(fd);
-		return 0;
+		if (fd >= 0) {
+			close(fd);
+			return 0;
+		}
+		DIR *dir = opendir(path);
+		if (dir != NULL) {
+			closedir(dir);
+			return 0;
+		}
+		return -1;
 	} else {
 		/* Invalid amode argument. */
