about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2022-04-27 09:10:02 -0400
committerRich Felker <dalias@aerifal.cx>2022-05-01 23:25:21 -0400
commit9a9374955517bf731f11fd2c4a071b3cc1120526 (patch)
tree5a19aedfb9f6df8ebe9bcdad30c1446a94d5a2c4
parent12a757b3219408c5f96fd5b9daa5c551944337ee (diff)
downloadmusl-9a9374955517bf731f11fd2c4a071b3cc1120526.tar.gz
musl-9a9374955517bf731f11fd2c4a071b3cc1120526.tar.xz
musl-9a9374955517bf731f11fd2c4a071b3cc1120526.zip
drop use of stat operation in temporary file name generation
this change serves two purposes:

1. it eliminates one of the few remaining uses of the kernel stat
structure which will not be present in future archs, avoiding the need
for growing ifdef logic here.

2. it potentially makes the operations less expensive when the
candidate exists as a non-symlink by avoiding the need to read the
inode (assuming the directory tables suffice to distinguish symlinks).

this uses the idiom I discovered while rewriting realpath for commit
29ff7599a448232f2527841c2362643d246cee36 of being able to use the
readlink operation as an inexpensive probe for file existence that
doesn't following symlinks.
-rw-r--r--src/stdio/tempnam.c8
-rw-r--r--src/stdio/tmpnam.c8
2 files changed, 6 insertions, 10 deletions
diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c
index 565df6b6..0c65b1f0 100644
--- a/src/stdio/tempnam.c
+++ b/src/stdio/tempnam.c
@@ -6,7 +6,6 @@
 #include <string.h>
 #include <stdlib.h>
 #include "syscall.h"
-#include "kstat.h"
 
 #define MAXTRIES 100
 
@@ -37,11 +36,10 @@ char *tempnam(const char *dir, const char *pfx)
 
 	for (try=0; try<MAXTRIES; try++) {
 		__randname(s+l-6);
-#ifdef SYS_lstat
-		r = __syscall(SYS_lstat, s, &(struct kstat){0});
+#ifdef SYS_readlink
+		r = __syscall(SYS_readlink, s, (char[1]){0}, 1);
 #else
-		r = __syscall(SYS_fstatat, AT_FDCWD, s,
-			&(struct kstat){0}, AT_SYMLINK_NOFOLLOW);
+		r = __syscall(SYS_readlinkat, AT_FDCWD, s, (char[1]){0}, 1);
 #endif
 		if (r == -ENOENT) return strdup(s);
 	}
diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c
index d667a836..71dc8bb1 100644
--- a/src/stdio/tmpnam.c
+++ b/src/stdio/tmpnam.c
@@ -5,7 +5,6 @@
 #include <string.h>
 #include <stdlib.h>
 #include "syscall.h"
-#include "kstat.h"
 
 #define MAXTRIES 100
 
@@ -17,11 +16,10 @@ char *tmpnam(char *buf)
 	int r;
 	for (try=0; try<MAXTRIES; try++) {
 		__randname(s+12);
-#ifdef SYS_lstat
-		r = __syscall(SYS_lstat, s, &(struct kstat){0});
+#ifdef SYS_readlink
+		r = __syscall(SYS_readlink, s, (char[1]){0}, 1);
 #else
-		r = __syscall(SYS_fstatat, AT_FDCWD, s,
-			&(struct kstat){0}, AT_SYMLINK_NOFOLLOW);
+		r = __syscall(SYS_readlinkat, AT_FDCWD, s, (char[1]){0}, 1);
 #endif
 		if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
 	}