summaryrefslogtreecommitdiff
path: root/src/test/test-install-file.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-02-26 17:41:30 +0100
committerLennart Poettering <lennart@poettering.net>2021-08-17 10:08:48 +0200
commit235be6bcea86304e7538d1ff720b14beca2914e8 (patch)
tree0945ef80029fcbbd871113a35aac7074603d53c6 /src/test/test-install-file.c
parent78c23b065f11e524c6730d5afcdba0c3c8129b76 (diff)
downloadsystemd-235be6bcea86304e7538d1ff720b14beca2914e8.tar.gz
shared: add generic helper tools for installing files/dir trees
This adds a bit of generic helper tools for installing files/dir trees. "installing" is supposed to mean the final step when preparing a disk image or directory tree, where the result is renamed to its final name. It has some bells and whistles, as it is able to replace existing files sanely, can fsync() things carefully and can mark things read-only in a nice way. This is supposed to be generic, unified code that can be used eventually for any of our tools that prepare disk images/directory trees, including importd, nspawn's --template= mechanism, the discover-image.c logic, and more.
Diffstat (limited to 'src/test/test-install-file.c')
-rw-r--r--src/test/test-install-file.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/test/test-install-file.c b/src/test/test-install-file.c
new file mode 100644
index 0000000000..55d77ac236
--- /dev/null
+++ b/src/test/test-install-file.c
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "fileio.h"
+#include "install-file.h"
+#include "path-util.h"
+#include "rm-rf.h"
+#include "tests.h"
+#include "tmpfile-util.h"
+#include "umask-util.h"
+
+static void test_install_file(void) {
+ _cleanup_(rm_rf_physical_and_freep) char *p = NULL;
+ _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL;
+ struct stat stat1, stat2;
+
+ log_info("/* %s */", __func__);
+
+ assert_se(mkdtemp_malloc(NULL, &p) >= 0);
+ assert_se(a = path_join(p, "foo"));
+ assert_se(b = path_join(p, "bar"));
+
+ RUN_WITH_UMASK(0077)
+ assert_se(write_string_file(a, "wups", WRITE_STRING_FILE_CREATE) >= 0);
+
+ assert_se(lstat(a, &stat1) >= 0);
+ assert_se(S_ISREG(stat1.st_mode));
+
+ assert_se(install_file(AT_FDCWD, a, AT_FDCWD, b, 0) >= 0);
+ assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC) >= 0);
+
+ assert_se(write_string_file(b, "ttss", WRITE_STRING_FILE_CREATE) >= 0);
+ assert_se(install_file(AT_FDCWD, a, AT_FDCWD, b, INSTALL_FSYNC_FULL) == -EEXIST);
+ assert_se(install_file(AT_FDCWD, a, AT_FDCWD, b, INSTALL_FSYNC_FULL|INSTALL_REPLACE) >= 0);
+
+ assert_se(stat(b, &stat2) >= 0);
+ assert_se(stat1.st_dev == stat2.st_dev);
+ assert_se(stat1.st_ino == stat2.st_ino);
+ assert_se((stat2.st_mode & 0222) != 0); /* writable */
+
+ assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL|INSTALL_REPLACE|INSTALL_READ_ONLY) >= 0);
+
+ assert_se(stat(a, &stat2) >= 0);
+ assert_se(stat1.st_dev == stat2.st_dev);
+ assert_se(stat1.st_ino == stat2.st_ino);
+ assert_se((stat2.st_mode & 0222) == 0); /* read-only */
+
+ assert_se(mkdir(b, 0755) >= 0);
+ assert_se(c = path_join(b, "dir"));
+ assert_se(mkdir(c, 0755) >= 0);
+ free(c);
+ assert_se(c = path_join(b, "reg"));
+ assert_se(mknod(c, S_IFREG|0755, 0) >= 0);
+ free(c);
+ assert_se(c = path_join(b, "fifo"));
+ assert_se(mknod(c, S_IFIFO|0755, 0) >= 0);
+
+ assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL) == -EEXIST);
+ assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL|INSTALL_REPLACE) == 0);
+
+ assert_se(write_string_file(b, "ttss", WRITE_STRING_FILE_CREATE) >= 0);
+
+ assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL) == -EEXIST);
+ assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL|INSTALL_REPLACE) == 0);
+}
+
+int main(int argc, char *argv[]) {
+ test_setup_logging(LOG_INFO);
+
+ test_install_file();
+
+ return 0;
+}