From 1e4f0fdb8d684007fa0c9747181a8ca70da5eaae Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Mon, 10 Apr 2023 15:18:33 +0200 Subject: [PATCH] generator: add generator_open_unit_file_full to allow creating temporary units This function is like `generator_open_unit_file`, but if `ret_temp_path` is passed, a temporary unit is created instead. (cherry picked from commit 8a84e0d7960b7970c16a4efd4c5b0b26c810d22d) Related: RHEL-27512 --- src/shared/generator.c | 46 ++++++++++++++++++++++++++++-------------- src/shared/generator.h | 10 ++++----- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/shared/generator.c b/src/shared/generator.c index 284e5fc580..29de8ada6b 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -20,42 +20,58 @@ #include "specifier.h" #include "string-util.h" #include "time-util.h" +#include "tmpfile-util.h" #include "unit-name.h" #include "util.h" -int generator_open_unit_file( +int generator_open_unit_file_full( const char *dir, const char *source, const char *fn, - FILE **ret) { + FILE **ret_file, + char **ret_temp_path) { _cleanup_free_ char *p = NULL; FILE *f; int r; assert(dir); - assert(fn); - assert(ret); + assert(ret_file); - p = path_join(dir, fn); - if (!p) - return log_oom(); + /* If is specified, it creates a temporary unit file and also returns its + * temporary path. */ - r = fopen_unlocked(p, "wxe", &f); - if (r < 0) { - if (source && r == -EEXIST) - return log_error_errno(r, - "Failed to create unit file '%s', as it already exists. Duplicate entry in '%s'?", - p, source); + if (ret_temp_path) { + r = fopen_temporary(dir, &f, &p); + if (r < 0) + return log_error_errno(r, "Failed to create temporary unit file in '%s': %m", dir); + + (void) fchmod(fileno(f), 0644); - return log_error_errno(r, "Failed to create unit file '%s': %m", p); + *ret_temp_path = TAKE_PTR(p); + } else { + assert(fn); + + p = path_join(dir, fn); + if (!p) + return log_oom(); + + r = fopen_unlocked(p, "wxe", &f); + if (r < 0) { + if (source && r == -EEXIST) + return log_error_errno(r, + "Failed to create unit file '%s', as it already exists. Duplicate entry in '%s'?", + p, source); + + return log_error_errno(r, "Failed to create unit file '%s': %m", p); + } } fprintf(f, "# Automatically generated by %s\n\n", program_invocation_short_name); - *ret = f; + *ret_file = f; return 0; } diff --git a/src/shared/generator.h b/src/shared/generator.h index 111900fd45..d97d6edc67 100644 --- a/src/shared/generator.h +++ b/src/shared/generator.h @@ -6,11 +6,11 @@ #include "macro.h" #include "main-func.h" -int generator_open_unit_file( - const char *dest, - const char *source, - const char *name, - FILE **file); +int generator_open_unit_file_full(const char *dest, const char *source, const char *name, FILE **ret_file, char **ret_temp_path); + +static inline int generator_open_unit_file(const char *dest, const char *source, const char *name, FILE **ret_file) { + return generator_open_unit_file_full(dest, source, name, ret_file, NULL); +} int generator_add_symlink_full(const char *dir, const char *dst, const char *dep_type, const char *src, const char *instance);