So far we only have an API that truncates the file prior to writing it. However, experience show need for new API that just appends a string to file. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virfile.c | 57 ++++++++++++++++++++++++++++++++++++++++-------- src/util/virfile.h | 3 +++ 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0c16343..f9bdd8c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1202,6 +1202,7 @@ virBuildPathInternal; virDirCreate; virFileAbsPath; virFileAccessibleAs; +virFileAppendStr; virFileBuildPath; virFileClose; virFileDeleteTree; diff --git a/src/util/virfile.c b/src/util/virfile.c index 631cd06..9357e09 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1291,23 +1291,21 @@ virFileReadAll(const char *path, int maxlen, char **buf) return len; } -/* Truncate @path and write @str to it. If @mode is 0, ensure that - @path exists; otherwise, use @mode if @path must be created. - Return 0 for success, nonzero for failure. - Be careful to preserve any errno value upon failure. */ -int -virFileWriteStr(const char *path, const char *str, mode_t mode) +static int +virFileWriteAppendStr(const char *path, const char *str, + int o_flags, mode_t mode, bool newline) { int fd; if (mode) - fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, mode); + fd = open(path, o_flags | O_CREAT, mode); else - fd = open(path, O_WRONLY|O_TRUNC); + fd = open(path, o_flags); if (fd == -1) return -1; - if (safewrite(fd, str, strlen(str)) < 0) { + if (safewrite(fd, str, strlen(str)) < 0 || + (newline && safewrite(fd, "\n", strlen("\n")) < 0)) { VIR_FORCE_CLOSE(fd); return -1; } @@ -1319,6 +1317,47 @@ virFileWriteStr(const char *path, const char *str, mode_t mode) return 0; } +/** + * virFileWriteStr: + * @path: file to write to + * @str: string to write + * @mode: file mode used when creating @path + * + * Truncate @path and write @str to it. If @mode is 0, ensure + * that @path exists; otherwise, use @mode if @path must be + * created. Be careful to preserve any errno value upon failure. + * + * Returns 0 on success, -1 on failure. + */ +int +virFileWriteStr(const char *path, const char *str, mode_t mode) +{ + return virFileWriteAppendStr(path, str, O_WRONLY | O_TRUNC, + mode, false); +} + +/** + * virFileAppendStr: + * @path: file to write to + * @str: string to write + * @mode: file mode used when creating @path + * @newline: append the newline character after @str? + * + * Append @str to @path. If the file doesn't exist, + * it is created using @mode. Moreover, if @newline + * is true, the newline character is appended to + * @path after @str is written. + * + * Returns 0 on success, -1 on failure. + */ +int +virFileAppendStr(const char *path, const char *str, + mode_t mode, bool newline) +{ + return virFileWriteAppendStr(path, str, O_WRONLY | O_APPEND, + mode, newline); +} + int virFileMatchesNameSuffix(const char *file, const char *name, diff --git a/src/util/virfile.h b/src/util/virfile.h index 0d20cdb..bd255f4 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -131,6 +131,9 @@ int virFileReadAll(const char *path, int maxlen, char **buf) int virFileWriteStr(const char *path, const char *str, mode_t mode) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virFileAppendStr(const char *path, const char *str, + mode_t mode, bool newline) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virFileMatchesNameSuffix(const char *file, const char *name, -- 1.8.5.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list