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(a)redhat.com>
---
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