X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Ftest-bus-memfd.c;h=b9d6a250c36b17ac25b049e2e917d3134e24f0e5;hp=4c5ae21a8c5d13a09c616381feabce1c7e2dac80;hb=872c8faaf2009422a91d227ae0b5c6f04c9d2c69;hpb=ddeb424198649c3993a54efc81652325b6e3bfa5;ds=sidebyside diff --git a/src/libsystemd-bus/test-bus-memfd.c b/src/libsystemd-bus/test-bus-memfd.c index 4c5ae21a8..b9d6a250c 100644 --- a/src/libsystemd-bus/test-bus-memfd.c +++ b/src/libsystemd-bus/test-bus-memfd.c @@ -20,6 +20,7 @@ ***/ #include +#include #include "log.h" #include "macro.h" @@ -32,6 +33,10 @@ int main(int argc, char *argv[]) { char *s; uint64_t sz; int r, fd; + FILE *f; + char buf[3] = {}; + struct iovec iov[3] = {}; + char bufv[3][3] = {}; log_set_max_level(LOG_DEBUG); @@ -39,47 +44,131 @@ int main(int argc, char *argv[]) { if (r == -ENOENT) return EXIT_TEST_SKIP; - r = sd_memfd_map(m, 0, 6, (void**) &s); + r = sd_memfd_map(m, 0, 12, (void**) &s); assert_se(r >= 0); - strcpy(s, "hallo"); - assert_se(munmap(s, 6) == 0); + strcpy(s, "----- world"); + + r = sd_memfd_set_sealed(m, 1); + assert_se(r == -ETXTBSY); assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2); + assert_se(write(sd_memfd_get_fd(m), "XXX", 3) == 3); + assert_se(streq(s, "heXXX world")); - r = sd_memfd_get_sealed(m); - assert_se(r == 0); + /* fix "hello" */ + assert_se(lseek(sd_memfd_get_fd(m), 2, SEEK_SET) == 2); + assert_se(write(sd_memfd_get_fd(m), "ll", 2) == 2); - r = sd_memfd_set_sealed(m, 1); - assert_se(r >= 0); + assert_se(sd_memfd_get_file(m, &f) >= 0); + fputc('o', f); + fflush(f); + + /* check content */ + assert_se(streq(s, "hello world")); + + assert_se(munmap(s, 12) == 0); r = sd_memfd_get_sealed(m); - assert_se(r == 1); + assert_se(r == 0); r = sd_memfd_get_size(m, &sz); assert_se(r >= 0); assert_se(sz = page_size()); + /* truncate it */ r = sd_memfd_set_size(m, 6); assert_se(r >= 0); + /* get back new value */ + r = sd_memfd_get_size(m, &sz); + assert_se(r >= 0); + assert_se(sz == 6); + + r = sd_memfd_set_sealed(m, 1); + assert_se(r >= 0); + + r = sd_memfd_get_sealed(m); + assert_se(r == 1); + fd = sd_memfd_dup_fd(m); assert_se(fd >= 0); sd_memfd_free(m); + /* new sd_memfd, same underlying memfd */ r = sd_memfd_make(fd, &m); assert_se(r >= 0); + /* we did truncate it to 6 */ r = sd_memfd_get_size(m, &sz); - assert_se(r >= 0); - assert_se(sz = 6); + assert_se(r >= 0 && sz == 6); - r = sd_memfd_map(m, 0, 6, (void**) &s); + /* map it, check content */ + r = sd_memfd_map(m, 0, 12, (void **)&s); assert_se(r >= 0); - assert_se(streq(s, "hello")); - assert_se(munmap(s, 6) == 0); + /* we only see the truncated size */ + assert_se(streq(s, "hello ")); + + /* it was already sealed */ + r = sd_memfd_set_sealed(m, 1); + assert_se(r == -EALREADY); + + /* we cannot break the seal, it is mapped */ + r = sd_memfd_set_sealed(m, 0); + assert_se(r == -ETXTBSY); + + /* unmap it; become the single owner */ + assert_se(munmap(s, 12) == 0); + + /* now we can do flip the sealing */ + r = sd_memfd_set_sealed(m, 0); + assert_se(r == 0); + r = sd_memfd_get_sealed(m); + assert_se(r == 0); + + r = sd_memfd_set_sealed(m, 1); + assert_se(r == 0); + r = sd_memfd_get_sealed(m); + assert_se(r == 1); + + r = sd_memfd_set_sealed(m, 0); + assert_se(r == 0); + r = sd_memfd_get_sealed(m); + assert_se(r == 0); + + /* seek at 2, read() 2 bytes */ + assert_se(lseek(fd, 2, SEEK_SET) == 2); + assert_se(read(fd, buf, 2) == 2); + + /* check content */ + assert_se(memcmp(buf, "ll", 2) == 0); + + /* writev it out*/ + iov[0].iov_base = (char *)"ABC"; + iov[0].iov_len = 3; + iov[1].iov_base = (char *)"DEF"; + iov[1].iov_len = 3; + iov[2].iov_base = (char *)"GHI"; + iov[2].iov_len = 3; + assert_se(pwritev(fd, iov, 3, 0) == 9); + + /* readv it back */ + iov[0].iov_base = bufv[0]; + iov[0].iov_len = 3; + iov[1].iov_base = bufv[1]; + iov[1].iov_len = 3; + iov[2].iov_base = bufv[2]; + iov[2].iov_len = 3; + assert_se(preadv(fd, iov, 3, 0) == 9); + + /* check content */ + assert_se(memcmp(bufv[0], "ABC", 3) == 0); + assert_se(memcmp(bufv[1], "DEF", 3) == 0); + assert_se(memcmp(bufv[2], "GHI", 3) == 0); + + sd_memfd_free(m); return 0; }