tmpfile-util: introduce new CLEANUP_TMPFILE_AT() API
This should allow us to get rid of a bunch of "fail:" labels, because we can clean up tmpfiles relative to some atfd this way. This only ports over a small number of potential users, but there's more work to be done.
This commit is contained in:
committed by
Luca Boccassi
parent
23860b4975
commit
444af9538f
+8
-10
@@ -650,14 +650,16 @@ int write_env_file(int dir_fd, const char *fname, char **headers, char **l, Writ
|
||||
}
|
||||
|
||||
r = fopen_tmpfile_linkable_at(dir_fd, fname, O_WRONLY|O_CLOEXEC, &p, &f);
|
||||
if (call_label_ops_post)
|
||||
RET_GATHER(r, label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fname, /* created= */ !!f));
|
||||
int k = call_label_ops_post ? label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fname, /* created= */ !!f) : 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
CLEANUP_TMPFILE_AT(dir_fd, p);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
r = fchmod_umask(fileno(f), 0644);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(i, headers) {
|
||||
assert(isempty(*i) || startswith(*i, "#"));
|
||||
@@ -670,15 +672,11 @@ int write_env_file(int dir_fd, const char *fname, char **headers, char **l, Writ
|
||||
|
||||
r = flink_tmpfile_at(f, dir_fd, p, fname, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return r;
|
||||
|
||||
p = mfree(p); /* disarm CLEANUP_TMPFILE_AT() */
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (p)
|
||||
(void) unlinkat(dir_fd, p, 0);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int write_vconsole_conf(int dir_fd, const char *fname, char **l) {
|
||||
|
||||
+12
-13
@@ -240,24 +240,28 @@ static int write_string_file_atomic_at(
|
||||
}
|
||||
|
||||
r = fopen_temporary_at(dir_fd, fn, &f, &p);
|
||||
if (call_label_ops_post)
|
||||
/* If fopen_temporary_at() failed in the above, propagate the error code, and ignore failures
|
||||
* in label_ops_post(). */
|
||||
RET_GATHER(r, label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f));
|
||||
int k = call_label_ops_post ? label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f) : 0;
|
||||
/* If fopen_temporary_at() failed in the above, propagate the error code, and ignore failures in
|
||||
* label_ops_post(). */
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return r;
|
||||
CLEANUP_TMPFILE_AT(dir_fd, p);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
r = write_string_stream_full(f, line, flags, ts);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return r;
|
||||
|
||||
r = fchmod_umask(fileno(f), mode);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return r;
|
||||
|
||||
r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn));
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return r;
|
||||
|
||||
p = mfree(p); /* disarm CLEANUP_TMPFILE_AT() */
|
||||
|
||||
if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
|
||||
/* Sync the rename, too */
|
||||
@@ -267,11 +271,6 @@ static int write_string_file_atomic_at(
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (f)
|
||||
(void) unlinkat(dir_fd, p, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
int write_string_file_full(
|
||||
|
||||
@@ -436,3 +436,17 @@ int mkdtemp_open(const char *template, int flags, char **ret) {
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void cleanup_tmpfile_data_done(struct cleanup_tmpfile_data *d) {
|
||||
assert(d);
|
||||
|
||||
if (!d->dir_fd ||
|
||||
*d->dir_fd < 0 ||
|
||||
!d->filename ||
|
||||
!*d->filename)
|
||||
return;
|
||||
|
||||
(void) unlinkat(*d->dir_fd, *d->filename, 0);
|
||||
d->dir_fd = NULL;
|
||||
d->filename = NULL;
|
||||
}
|
||||
|
||||
@@ -48,3 +48,14 @@ static inline int flink_tmpfile(FILE *f, const char *path, const char *target, L
|
||||
|
||||
int mkdtemp_malloc(const char *template, char **ret);
|
||||
int mkdtemp_open(const char *template, int flags, char **ret);
|
||||
|
||||
/* A helper for removing link_tmpfile_at() via _cleanup_() */
|
||||
struct cleanup_tmpfile_data {
|
||||
int *dir_fd;
|
||||
char **filename;
|
||||
};
|
||||
void cleanup_tmpfile_data_done(struct cleanup_tmpfile_data *d);
|
||||
#define _CLEANUP_TMPFILE_AT(u, dir_fd, filename) \
|
||||
_unused_ _cleanup_(cleanup_tmpfile_data_done) struct cleanup_tmpfile_data UNIQ_T(cta, u) = { &(dir_fd), &(filename) }
|
||||
#define CLEANUP_TMPFILE_AT(dir_fd, filename) \
|
||||
_CLEANUP_TMPFILE_AT(UNIQ, dir_fd, filename)
|
||||
|
||||
Reference in New Issue
Block a user