aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2023-04-19 22:46:42 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-04-19 22:46:42 +0000
commit0ea424a7ecc20027eed6e996dd69e30bc6c1686c (patch)
treed7f806ae93252dfce1f7029983186a3c0623ceca
parent01a90e088345b6489617c53c78c4e40780c5bd32 (diff)
parent2aefec48a50ff4ef914b865cb89af18d4a9ded4d (diff)
downloadbionic-0ea424a7ecc20027eed6e996dd69e30bc6c1686c.tar.gz
Merge "Make tmpfile() respect $TMPDIR." am: 17b2bae190 am: 4260d4d7eb am: 2aefec48a5
Original change: https://android-review.googlesource.com/c/platform/bionic/+/2545855 Change-Id: Ic4ac021444440a0cfc5c029f0d5f4c5d211b748b Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--libc/bionic/tmpfile.cpp37
-rw-r--r--tests/stdio_test.cpp17
2 files changed, 31 insertions, 23 deletions
diff --git a/libc/bionic/tmpfile.cpp b/libc/bionic/tmpfile.cpp
index 3d04610a4..4d6a1fbe0 100644
--- a/libc/bionic/tmpfile.cpp
+++ b/libc/bionic/tmpfile.cpp
@@ -51,6 +51,9 @@ static FILE* __fd_to_fp(int fd) {
return nullptr;
}
+// O_TMPFILE isn't available until Linux 3.11, so we fall back to this on
+// older kernels. AOSP was on a new enough kernel in the Lollipop timeframe,
+// so this code should be obsolete by 2025.
static FILE* __tmpfile_dir_legacy(const char* tmp_dir) {
char* path = nullptr;
if (asprintf(&path, "%s/tmp.XXXXXXXXXX", tmp_dir) == -1) {
@@ -79,25 +82,18 @@ static FILE* __tmpfile_dir_legacy(const char* tmp_dir) {
return __fd_to_fp(fd);
}
-static FILE* __tmpfile_dir(const char* tmp_dir) {
- int fd = open(tmp_dir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
- if (fd == -1) return __tmpfile_dir_legacy(tmp_dir);
- return __fd_to_fp(fd);
+const char* __get_TMPDIR() {
+ // Use $TMPDIR if set, or fall back to /data/local/tmp otherwise.
+ // Useless for apps, but good enough for the shell.
+ const char* tmpdir = getenv("TMPDIR");
+ return (tmpdir == nullptr) ? "/data/local/tmp" : tmpdir;
}
FILE* tmpfile() {
- // TODO: get this app's temporary directory from the framework ("/data/data/app/cache").
-
- // $EXTERNAL_STORAGE turns out not to be very useful because it doesn't support hard links.
- // This means we can't do the usual trick of calling unlink before handing the file back.
-
- FILE* fp = __tmpfile_dir("/data/local/tmp");
- if (fp == nullptr) {
- // P_tmpdir is "/tmp/", but POSIX explicitly says that tmpdir(3) should try P_tmpdir before
- // giving up. This is potentially useful for bionic on the host anyway.
- fp = __tmpfile_dir(P_tmpdir);
- }
- return fp;
+ const char* tmpdir = __get_TMPDIR();
+ int fd = open(tmpdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd == -1) return __tmpfile_dir_legacy(tmpdir);
+ return __fd_to_fp(fd);
}
__strong_alias(tmpfile64, tmpfile);
@@ -107,7 +103,7 @@ char* tempnam(const char* dir, const char* prefix) {
// since we can't easily remove it...
// $TMPDIR overrides any directory passed in.
- char* tmpdir = getenv("TMPDIR");
+ const char* tmpdir = getenv("TMPDIR");
if (tmpdir != nullptr) dir = tmpdir;
// If we still have no directory, we'll give you a default.
@@ -136,12 +132,7 @@ char* tmpnam(char* s) {
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);
+ snprintf(s, L_tmpnam, "%s/tmpnam.XXXXXXXXXX", __get_TMPDIR());
return mktemp(s);
}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index fb6bce918..c5ffe2423 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -36,6 +36,7 @@
#include <android-base/file.h>
#include <android-base/silent_death_test.h>
+#include <android-base/strings.h>
#include <android-base/test_utils.h>
#include <android-base/unique_fd.h>
@@ -140,6 +141,22 @@ TEST(STDIO_TEST, tmpfile64) {
fclose(fp);
}
+TEST(STDIO_TEST, tmpfile_TMPDIR) {
+ TemporaryDir td;
+ setenv("TMPDIR", td.path, 1);
+
+ FILE* fp = tmpfile();
+ ASSERT_TRUE(fp != nullptr);
+
+ std::string fd_path = android::base::StringPrintf("/proc/self/fd/%d", fileno(fp));
+ char path[PATH_MAX];
+ ASSERT_GT(readlink(fd_path.c_str(), path, sizeof(path)), 0);
+ // $TMPDIR influenced where our temporary file ended up?
+ ASSERT_TRUE(android::base::StartsWith(path, td.path)) << path;
+ // And we used O_TMPFILE, right?
+ ASSERT_TRUE(android::base::EndsWith(path, " (deleted)")) << path;
+}
+
TEST(STDIO_TEST, dprintf) {
TemporaryFile tf;