Merge "tmpfile(3): use O_TMPFILE where available."
This commit is contained in:
commit
0361a4f867
|
@ -31,6 +31,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -39,18 +40,23 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "private/ErrnoRestorer.h"
|
#include "private/ErrnoRestorer.h"
|
||||||
#include "private/ScopedSignalBlocker.h"
|
|
||||||
|
|
||||||
static FILE* __tmpfile_dir(const char* tmp_dir) {
|
static FILE* __fd_to_fp(int fd) {
|
||||||
|
FILE* fp = fdopen(fd, "w+");
|
||||||
|
if (fp != nullptr) return fp;
|
||||||
|
|
||||||
|
ErrnoRestorer errno_restorer;
|
||||||
|
close(fd);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FILE* __tmpfile_dir_legacy(const char* tmp_dir) {
|
||||||
char* path = nullptr;
|
char* path = nullptr;
|
||||||
if (asprintf(&path, "%s/tmp.XXXXXXXXXX", tmp_dir) == -1) {
|
if (asprintf(&path, "%s/tmp.XXXXXXXXXX", tmp_dir) == -1) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd;
|
int fd = mkstemp(path);
|
||||||
{
|
|
||||||
ScopedSignalBlocker ssb;
|
|
||||||
fd = mkstemp(path);
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
free(path);
|
free(path);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -63,24 +69,19 @@ static FILE* __tmpfile_dir(const char* tmp_dir) {
|
||||||
// Can we still use the file now it's unlinked?
|
// Can we still use the file now it's unlinked?
|
||||||
// File systems without hard link support won't have the usual Unix semantics.
|
// File systems without hard link support won't have the usual Unix semantics.
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
int rc = fstat(fd, &sb);
|
if (fstat(fd, &sb) == -1) {
|
||||||
if (rc == -1) {
|
|
||||||
ErrnoRestorer errno_restorer;
|
ErrnoRestorer errno_restorer;
|
||||||
close(fd);
|
close(fd);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Turn the file descriptor into a FILE*.
|
return __fd_to_fp(fd);
|
||||||
FILE* fp = fdopen(fd, "w+");
|
}
|
||||||
if (fp != nullptr) {
|
|
||||||
return fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Failure. Clean up. We already unlinked, so we just need to close.
|
static FILE* __tmpfile_dir(const char* tmp_dir) {
|
||||||
ErrnoRestorer errno_restorer;
|
int fd = open(tmp_dir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
|
||||||
close(fd);
|
if (fd == -1) return __tmpfile_dir_legacy(tmp_dir);
|
||||||
return nullptr;
|
return __fd_to_fp(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* tmpfile() {
|
FILE* tmpfile() {
|
||||||
|
|
Loading…
Reference in New Issue