Simplify and improve tempnam() and tmpnam().
They're both obsolescent in POSIX.1-2008, and you really shouldn't be
using them, but since we can't actually delete them...
This change makes them both obey $TMPDIR if set, and fall back to
/data/local/tmp otherwise. That's as good as we've managed for anything
else such as tmpfile(3).
Also add some tests.
Bug: http://b/174682340
Test: treehugger
Change-Id: Ieef99dcc2062f84b2b7cbae046787fdfe975e772
diff --git a/libc/bionic/tmpfile.cpp b/libc/bionic/tmpfile.cpp
index d7ce897..3d04610 100644
--- a/libc/bionic/tmpfile.cpp
+++ b/libc/bionic/tmpfile.cpp
@@ -35,6 +35,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -99,3 +100,48 @@
return fp;
}
__strong_alias(tmpfile64, tmpfile);
+
+char* tempnam(const char* dir, const char* prefix) {
+ // This function is a terrible idea, marked deprecated in our headers,
+ // and marked obsolescent by POSIX.1-2008, but we make some effort anyway
+ // since we can't easily remove it...
+
+ // $TMPDIR overrides any directory passed in.
+ char* tmpdir = getenv("TMPDIR");
+ if (tmpdir != nullptr) dir = tmpdir;
+
+ // If we still have no directory, we'll give you a default.
+ // It's useless for apps, but good enough for the shell.
+ if (dir == nullptr) dir = "/data/local/tmp";
+
+ // Default prefix?
+ if (prefix == nullptr) prefix = "tempnam.";
+
+ // Make up a mktemp(3) template and defer to it for the real work.
+ char* path = nullptr;
+ if (asprintf(&path, "%s/%sXXXXXXXXXX", dir, prefix) == -1) return nullptr;
+ if (mktemp(path) == nullptr) {
+ free(path);
+ return nullptr;
+ }
+ return path;
+}
+
+char* tmpnam(char* s) {
+ // This function is a terrible idea, marked deprecated in our headers,
+ // and marked obsolescent by POSIX-1.2008, but we make some effort anyway
+ // since we can't easily remove it...
+
+ // Default buffer?
+ static char buf[L_tmpnam];
+ if (s == nullptr) s = buf;
+
+ // Use $TMPDIR if set, or fall back to /data/local/tmp otherwise.
+ // Useless for apps, but good enough for the shell.
+ const char* dir = getenv("TMPDIR");
+ if (dir == nullptr) dir = "/data/local/tmp";
+
+ // Make up a mktemp(3) template and defer to it for the real work.
+ snprintf(s, L_tmpnam, "%s/tmpnam.XXXXXXXXXX", dir);
+ return mktemp(s);
+}