assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(fname);
- r = fopen_temporary_at(dir_fd, fname, &f, &p);
+ r = fopen_tmpfile_linkable_at(dir_fd, fname, O_WRONLY|O_CLOEXEC, &p, &f);
if (r < 0)
return r;
- (void) fchmod_umask(fileno(f), 0644);
+ r = fchmod_umask(fileno(f), 0644);
+ if (r < 0)
+ goto fail;
STRV_FOREACH(i, headers) {
assert(isempty(*i) || startswith(*i, "#"));
STRV_FOREACH(i, l)
write_env_var(f, *i);
- r = fflush_and_check(f);
- if (r >= 0) {
- if (renameat(dir_fd, p, dir_fd, fname) >= 0)
- return 0;
+ r = flink_tmpfile_at(f, dir_fd, p, fname, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC);
+ if (r < 0)
+ goto fail;
- r = -errno;
- }
+ return 0;
+
+fail:
+ if (p)
+ (void) unlinkat(dir_fd, p, 0);
- (void) unlinkat(dir_fd, p, 0);
return r;
}
return fd;
}
-int fopen_tmpfile_linkable(const char *target, int flags, char **ret_path, FILE **ret_file) {
+int fopen_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **ret_path, FILE **ret_file) {
_cleanup_free_ char *path = NULL;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_close_ int fd = -EBADF;
assert(ret_file);
assert(ret_path);
- fd = open_tmpfile_linkable(target, flags, &path);
+ fd = open_tmpfile_linkable_at(dir_fd, target, flags, &path);
if (fd < 0)
return fd;
return 0;
}
-int flink_tmpfile(FILE *f, const char *path, const char *target, LinkTmpfileFlags flags) {
+int flink_tmpfile_at(FILE *f, int dir_fd, const char *path, const char *target, LinkTmpfileFlags flags) {
int fd, r;
assert(f);
if (r < 0)
return r;
- return link_tmpfile(fd, path, target, flags);
+ return link_tmpfile_at(fd, dir_fd, path, target, flags);
}
int mkdtemp_malloc(const char *template, char **ret) {
static inline int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
return open_tmpfile_linkable_at(AT_FDCWD, target, flags, ret_path);
}
-int fopen_tmpfile_linkable(const char *target, int flags, char **ret_path, FILE **ret_file);
+int fopen_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **ret_path, FILE **ret_file);
+static inline int fopen_tmpfile_linkable(const char *target, int flags, char **ret_path, FILE **ret_file) {
+ return fopen_tmpfile_linkable_at(AT_FDCWD, target, flags, ret_path, ret_file);
+}
typedef enum LinkTmpfileFlags {
LINK_TMPFILE_REPLACE = 1 << 0,
static inline int link_tmpfile(int fd, const char *path, const char *target, LinkTmpfileFlags flags) {
return link_tmpfile_at(fd, AT_FDCWD, path, target, flags);
}
-int flink_tmpfile(FILE *f, const char *path, const char *target, LinkTmpfileFlags flags);
+int flink_tmpfile_at(FILE *f, int dir_fd, const char *path, const char *target, LinkTmpfileFlags flags);
+static inline int flink_tmpfile(FILE *f, const char *path, const char *target, LinkTmpfileFlags flags) {
+ return flink_tmpfile_at(f, AT_FDCWD, path, target, flags);
+}
int mkdtemp_malloc(const char *template, char **ret);
int mkdtemp_open(const char *template, int flags, char **ret);