static void test_unoctchar(void) { assert_se(unoctchar('0') == 00); assert_se(unoctchar('7') == 07); }
static void test_socket_address_parse(void) { SocketAddress a; assert_se(socket_address_parse(&a, "junk") < 0); assert_se(socket_address_parse(&a, "192.168.1.1") < 0); assert_se(socket_address_parse(&a, ".168.1.1") < 0); assert_se(socket_address_parse(&a, "989.168.1.1") < 0); assert_se(socket_address_parse(&a, "192.168.1.1:65536") < 0); assert_se(socket_address_parse(&a, "192.168.1.1:0") < 0); assert_se(socket_address_parse(&a, "0") < 0); assert_se(socket_address_parse(&a, "65536") < 0); assert_se(socket_address_parse(&a, "65535") >= 0); if (socket_ipv6_is_supported()) { assert_se(socket_address_parse(&a, "[::1]") < 0); assert_se(socket_address_parse(&a, "[::1]8888") < 0); assert_se(socket_address_parse(&a, "::1") < 0); assert_se(socket_address_parse(&a, "[::1]:0") < 0); assert_se(socket_address_parse(&a, "[::1]:65536") < 0); assert_se(socket_address_parse(&a, "[a:b:1]:8888") < 0); assert_se(socket_address_parse(&a, "8888") >= 0); assert_se(a.sockaddr.sa.sa_family == AF_INET6); assert_se(socket_address_parse(&a, "[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888") >= 0); assert_se(a.sockaddr.sa.sa_family == AF_INET6); assert_se(socket_address_parse(&a, "[::1]:8888") >= 0); assert_se(a.sockaddr.sa.sa_family == AF_INET6); } else { assert_se(socket_address_parse(&a, "[::1]:8888") < 0); assert_se(socket_address_parse(&a, "8888") >= 0); assert_se(a.sockaddr.sa.sa_family == AF_INET); } assert_se(socket_address_parse(&a, "192.168.1.254:8888") >= 0); assert_se(a.sockaddr.sa.sa_family == AF_INET); assert_se(socket_address_parse(&a, "/foo/bar") >= 0); assert_se(a.sockaddr.sa.sa_family == AF_UNIX); assert_se(socket_address_parse(&a, "@abstract") >= 0); assert_se(a.sockaddr.sa.sa_family == AF_UNIX); }
static void test_address_equality(void) { _cleanup_address_free_ Address *a1 = NULL, *a2 = NULL; assert_se(address_new_dynamic(&a1) >= 0); assert_se(address_new_dynamic(&a2) >= 0); assert_se(address_equal(NULL, NULL)); assert_se(!address_equal(a1, NULL)); assert_se(!address_equal(NULL, a2)); assert_se(address_equal(a1, a2)); a1->family = AF_INET; assert_se(!address_equal(a1, a2)); a2->family = AF_INET; assert_se(address_equal(a1, a2)); assert_se(inet_pton(AF_INET, "192.168.3.9", &a1->in_addr.in)); assert_se(address_equal(a1, a2)); assert_se(inet_pton(AF_INET, "192.168.3.9", &a2->in_addr.in)); assert_se(address_equal(a1, a2)); a1->prefixlen = 10; assert_se(!address_equal(a1, a2)); a2->prefixlen = 10; assert_se(address_equal(a1, a2)); assert_se(inet_pton(AF_INET, "192.168.3.10", &a2->in_addr.in)); assert_se(address_equal(a1, a2)); a1->family = AF_INET6; assert_se(!address_equal(a1, a2)); a2->family = AF_INET6; assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a1->in_addr.in6)); assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a2->in_addr.in6)); assert_se(address_equal(a1, a2)); a2->prefixlen = 8; assert_se(address_equal(a1, a2)); assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::1", &a2->in_addr.in6)); assert_se(!address_equal(a1, a2)); }
static void test_strextend(void) { _cleanup_free_ char *str = strdup("0123"); strextend(&str, "456", "78", "9", NULL); assert_se(streq(str, "0123456789")); }
static void test_ascii_strcasecmp_n(void) { assert_se(ascii_strcasecmp_n("", "", 0) == 0); assert_se(ascii_strcasecmp_n("", "", 1) == 0); assert_se(ascii_strcasecmp_n("", "a", 1) < 0); assert_se(ascii_strcasecmp_n("", "a", 2) < 0); assert_se(ascii_strcasecmp_n("a", "", 1) > 0); assert_se(ascii_strcasecmp_n("a", "", 2) > 0); assert_se(ascii_strcasecmp_n("a", "a", 1) == 0); assert_se(ascii_strcasecmp_n("a", "a", 2) == 0); assert_se(ascii_strcasecmp_n("a", "b", 1) < 0); assert_se(ascii_strcasecmp_n("a", "b", 2) < 0); assert_se(ascii_strcasecmp_n("b", "a", 1) > 0); assert_se(ascii_strcasecmp_n("b", "a", 2) > 0); assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxYxxxx", 9) == 0); assert_se(ascii_strcasecmp_n("xxxxxxxxx", "xxxxyxxxx", 9) < 0); assert_se(ascii_strcasecmp_n("xxxxXxxxx", "xxxxyxxxx", 9) < 0); assert_se(ascii_strcasecmp_n("xxxxxxxxx", "xxxxYxxxx", 9) < 0); assert_se(ascii_strcasecmp_n("xxxxXxxxx", "xxxxYxxxx", 9) < 0); assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxYxxxx", 9) == 0); assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxxxxxx", 9) > 0); assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxXxxxx", 9) > 0); assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxxxxxx", 9) > 0); assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxXxxxx", 9) > 0); }
int uname_architecture(void) { /* Return a sanitized enum identifying the architecture we are * running on. This is based on uname(), and the user may * hence control what this returns by using * personality(). This puts the user in control on systems * that can run binaries of multiple architectures. * * We do not translate the string returned by uname() * 1:1. Instead we try to clean it up and break down the * confusion on x86 and arm in particular. * * We do not try to distinguish CPUs not CPU features, but * actual architectures, i.e. that have genuinely different * code. */ static const struct { const char *machine; int arch; } arch_map[] = { #if defined(__x86_64__) || defined(__i386__) { "x86_64", ARCHITECTURE_X86_64 }, { "i686", ARCHITECTURE_X86 }, { "i586", ARCHITECTURE_X86 }, { "i486", ARCHITECTURE_X86 }, { "i386", ARCHITECTURE_X86 }, #elif defined(__powerpc__) || defined(__powerpc64__) { "ppc64", ARCHITECTURE_PPC64 }, { "ppc64le", ARCHITECTURE_PPC64_LE }, { "ppc", ARCHITECTURE_PPC }, { "ppcle", ARCHITECTURE_PPC_LE }, #elif defined(__ia64__) { "ia64", ARCHITECTURE_IA64 }, #elif defined(__hppa__) || defined(__hppa64__) { "parisc64", ARCHITECTURE_PARISC64 }, { "parisc", ARCHITECTURE_PARISC }, #elif defined(__s390__) || defined(__s390x__) { "s390x", ARCHITECTURE_S390X }, { "s390", ARCHITECTURE_S390 }, #elif defined(__sparc__) { "sparc64", ARCHITECTURE_SPARC64 }, { "sparc", ARCHITECTURE_SPARC }, #elif defined(__mips__) || defined(__mips64__) { "mips64", ARCHITECTURE_MIPS64 }, { "mips", ARCHITECTURE_MIPS }, #elif defined(__alpha__) { "alpha" , ARCHITECTURE_ALPHA }, #elif defined(__arm__) || defined(__aarch64__) { "aarch64", ARCHITECTURE_ARM64 }, { "aarch64_be", ARCHITECTURE_ARM64_BE }, { "armv4l", ARCHITECTURE_ARM }, { "armv4b", ARCHITECTURE_ARM_BE }, { "armv4tl", ARCHITECTURE_ARM }, { "armv4tb", ARCHITECTURE_ARM_BE }, { "armv5tl", ARCHITECTURE_ARM }, { "armv5tb", ARCHITECTURE_ARM_BE }, { "armv5tel", ARCHITECTURE_ARM }, { "armv5teb" , ARCHITECTURE_ARM_BE }, { "armv5tejl", ARCHITECTURE_ARM }, { "armv5tejb", ARCHITECTURE_ARM_BE }, { "armv6l", ARCHITECTURE_ARM }, { "armv6b", ARCHITECTURE_ARM_BE }, { "armv7l", ARCHITECTURE_ARM }, { "armv7b", ARCHITECTURE_ARM_BE }, { "armv7ml", ARCHITECTURE_ARM }, { "armv7mb", ARCHITECTURE_ARM_BE }, { "armv4l", ARCHITECTURE_ARM }, { "armv4b", ARCHITECTURE_ARM_BE }, { "armv4tl", ARCHITECTURE_ARM }, { "armv4tb", ARCHITECTURE_ARM_BE }, { "armv5tl", ARCHITECTURE_ARM }, { "armv5tb", ARCHITECTURE_ARM_BE }, { "armv5tel", ARCHITECTURE_ARM }, { "armv5teb", ARCHITECTURE_ARM_BE }, { "armv5tejl", ARCHITECTURE_ARM }, { "armv5tejb", ARCHITECTURE_ARM_BE }, { "armv6l", ARCHITECTURE_ARM }, { "armv6b", ARCHITECTURE_ARM_BE }, { "armv7l", ARCHITECTURE_ARM }, { "armv7b", ARCHITECTURE_ARM_BE }, { "armv7ml", ARCHITECTURE_ARM }, { "armv7mb", ARCHITECTURE_ARM_BE }, { "armv8l", ARCHITECTURE_ARM }, { "armv8b", ARCHITECTURE_ARM_BE }, #elif defined(__sh__) || defined(__sh64__) { "sh5", ARCHITECTURE_SH64 }, { "sh2", ARCHITECTURE_SH }, { "sh2a", ARCHITECTURE_SH }, { "sh3", ARCHITECTURE_SH }, { "sh4", ARCHITECTURE_SH }, { "sh4a", ARCHITECTURE_SH }, #elif defined(__m68k__) { "m68k", ARCHITECTURE_M68K }, #elif defined(__tilegx__) { "tilegx", ARCHITECTURE_TILEGX }, #elif defined(__cris__) { "crisv32", ARCHITECTURE_CRIS }, #elif defined(__nios2__) { "nios2", ARCHITECTURE_NIOS2 }, #elif defined(__riscv__) || defined(__riscv) /* __riscv__ is obsolete, remove in 2018 */ { "riscv32", ARCHITECTURE_RISCV32 }, { "riscv64", ARCHITECTURE_RISCV64 }, # if __SIZEOF_POINTER__ == 4 { "riscv", ARCHITECTURE_RISCV32 }, # elif __SIZEOF_POINTER__ == 8 { "riscv", ARCHITECTURE_RISCV64 }, # endif #else #error "Please register your architecture here!" #endif }; static int cached = _ARCHITECTURE_INVALID; struct utsname u; unsigned i; if (cached != _ARCHITECTURE_INVALID) return cached; assert_se(uname(&u) >= 0); for (i = 0; i < ELEMENTSOF(arch_map); i++) if (streq(arch_map[i].machine, u.machine)) return cached = arch_map[i].arch; assert_not_reached("Couldn't identify architecture. You need to patch systemd."); return _ARCHITECTURE_INVALID; }
static void test_one( const char *path, const char *interface, const char *member, bool as_list, const char *arg0, const char *match, bool good) { _cleanup_close_ int bus_ref = -1; _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; sd_bus *a, *b; int r; assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0); bus_ref = bus_kernel_create_bus(name, false, &bus_name); if (bus_ref == -ENOENT) exit(EXIT_TEST_SKIP); assert_se(bus_ref >= 0); address = strappend("kernel:path=", bus_name); assert_se(address); r = sd_bus_new(&a); assert_se(r >= 0); r = sd_bus_new(&b); assert_se(r >= 0); r = sd_bus_set_address(a, address); assert_se(r >= 0); r = sd_bus_set_address(b, address); assert_se(r >= 0); r = sd_bus_start(a); assert_se(r >= 0); r = sd_bus_start(b); assert_se(r >= 0); log_debug("match"); r = sd_bus_add_match(b, NULL, match, NULL, NULL); assert_se(r >= 0); log_debug("signal"); if (as_list) r = sd_bus_emit_signal(a, path, interface, member, "as", 1, arg0); else r = sd_bus_emit_signal(a, path, interface, member, "s", arg0); assert_se(r >= 0); r = sd_bus_process(b, &m); assert_se(r >= 0 && (good == !!m)); sd_bus_unref(a); sd_bus_unref(b); }
static void test_nameinfo_pretty(void) { _cleanup_free_ char *stdin_name = NULL, *localhost = NULL; union sockaddr_union s = { .in.sin_family = AF_INET, .in.sin_port = 0, .in.sin_addr.s_addr = htonl(INADDR_ANY), }; int r; union sockaddr_union c = {}; socklen_t slen = sizeof(c.in), clen = sizeof(c.in); _cleanup_close_ int sfd = -1, cfd = -1; r = getnameinfo_pretty(STDIN_FILENO, &stdin_name); log_info_errno(r, "No connection remote: %m"); assert_se(r < 0); sfd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0); assert_se(sfd >= 0); assert_se(bind(sfd, &s.sa, sizeof(s.in)) == 0); /* find out the port number */ assert_se(getsockname(sfd, &s.sa, &slen) == 0); assert_se(listen(sfd, 1) == 0); assert_se(asynchronous_job(connect_thread, &s) == 0); log_debug("Accepting new connection on fd:%d", sfd); cfd = accept4(sfd, &c.sa, &clen, SOCK_CLOEXEC); assert_se(cfd >= 0); r = getnameinfo_pretty(cfd, &localhost); log_info("Connection from %s", localhost); assert_se(r == 0); } static void test_sockaddr_equal(void) { union sockaddr_union a = { .in.sin_family = AF_INET, .in.sin_port = 0, .in.sin_addr.s_addr = htonl(INADDR_ANY), }; union sockaddr_union b = { .in.sin_family = AF_INET, .in.sin_port = 0, .in.sin_addr.s_addr = htonl(INADDR_ANY), }; union sockaddr_union c = { .in.sin_family = AF_INET, .in.sin_port = 0, .in.sin_addr.s_addr = htonl(1234), }; union sockaddr_union d = { .in6.sin6_family = AF_INET6, .in6.sin6_port = 0, .in6.sin6_addr = IN6ADDR_ANY_INIT, }; assert_se(sockaddr_equal(&a, &a)); assert_se(sockaddr_equal(&a, &b)); assert_se(sockaddr_equal(&d, &d)); assert_se(!sockaddr_equal(&a, &c)); assert_se(!sockaddr_equal(&b, &c)); } int main(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); test_socket_address_parse(); test_socket_address_parse_netlink(); test_socket_address_equal(); test_socket_address_get_path(); test_socket_address_is(); test_socket_address_is_netlink(); test_in_addr_is_null(); test_in_addr_prefix_intersect(); test_in_addr_prefix_next(); test_in_addr_to_string(); test_nameinfo_pretty(); test_sockaddr_equal(); return 0; }
int stub_pid1(sd_id128_t uuid) { enum { STATE_RUNNING, STATE_REBOOT, STATE_POWEROFF, } state = STATE_RUNNING; sigset_t fullmask, oldmask, waitmask; usec_t quit_usec = USEC_INFINITY; pid_t pid; int r; /* The new environment we set up, on the stack. */ char new_environment[] = "container=systemd-nspawn\0" "container_uuid=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; /* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful * for allowing arbitrary processes run in a container, and still have all zombies reaped. */ assert_se(sigfillset(&fullmask) >= 0); assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0); pid = fork(); if (pid < 0) return log_error_errno(errno, "Failed to fork child pid: %m"); if (pid == 0) { /* Return in the child */ assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) >= 0); setsid(); return 0; } reset_all_signal_handlers(); log_close(); close_all_fds(NULL, 0); log_open(); /* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also, * set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ * find them set. */ sd_id128_to_string(uuid, new_environment + sizeof(new_environment) - SD_ID128_STRING_MAX); reset_environ(new_environment, sizeof(new_environment)); rename_process("STUBINIT"); assert_se(sigemptyset(&waitmask) >= 0); assert_se(sigset_add_many(&waitmask, SIGCHLD, /* posix: process died */ SIGINT, /* sysv: ctrl-alt-del */ SIGRTMIN+3, /* systemd: halt */ SIGRTMIN+4, /* systemd: poweroff */ SIGRTMIN+5, /* systemd: reboot */ SIGRTMIN+6, /* systemd: kexec */ SIGRTMIN+13, /* systemd: halt */ SIGRTMIN+14, /* systemd: poweroff */ SIGRTMIN+15, /* systemd: reboot */ SIGRTMIN+16, /* systemd: kexec */ -1) >= 0); /* Note that we ignore SIGTERM (sysv's reexec), SIGHUP (reload), and all other signals here, since we don't * support reexec/reloading in this stub process. */ for (;;) { siginfo_t si; usec_t current_usec; si.si_pid = 0; r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG); if (r < 0) { r = log_error_errno(errno, "Failed to reap children: %m"); goto finish; } current_usec = now(CLOCK_MONOTONIC); if (si.si_pid == pid || current_usec >= quit_usec) { /* The child we started ourselves died or we reached a timeout. */ if (state == STATE_REBOOT) { /* dispatch a queued reboot */ (void) reboot(RB_AUTOBOOT); r = log_error_errno(errno, "Failed to reboot: %m"); goto finish; } else if (state == STATE_POWEROFF) (void) reboot(RB_POWER_OFF); /* if this fails, fall back to normal exit. */ if (si.si_pid == pid && si.si_code == CLD_EXITED) r = si.si_status; /* pass on exit code */ else r = 255; /* signal, coredump, timeout, … */ goto finish; } if (si.si_pid != 0) /* We reaped something. Retry until there's nothing more to reap. */ continue; if (quit_usec == USEC_INFINITY) r = sigwaitinfo(&waitmask, &si); else { struct timespec ts; r = sigtimedwait(&waitmask, &si, timespec_store(&ts, quit_usec - current_usec)); } if (r < 0) { if (errno == EINTR) /* strace -p attach can result in EINTR, let's handle this nicely. */ continue; if (errno == EAGAIN) /* timeout reached */ continue; r = log_error_errno(errno, "Failed to wait for signal: %m"); goto finish; } if (si.si_signo == SIGCHLD) continue; /* Let's reap this */ if (state != STATE_RUNNING) continue; /* Would love to use a switch() statement here, but SIGRTMIN is actually a function call, not a * constant… */ if (si.si_signo == SIGRTMIN+3 || si.si_signo == SIGRTMIN+4 || si.si_signo == SIGRTMIN+13 || si.si_signo == SIGRTMIN+14) state = STATE_POWEROFF; else if (si.si_signo == SIGINT || si.si_signo == SIGRTMIN+5 || si.si_signo == SIGRTMIN+6 || si.si_signo == SIGRTMIN+15 || si.si_signo == SIGRTMIN+16) state = STATE_REBOOT; else assert_not_reached("Got unexpected signal"); r = kill_and_sigcont(pid, SIGTERM); /* Let's send a SIGHUP after the SIGTERM, as shells tend to ignore SIGTERM but do react to SIGHUP. We * do it strictly in this order, so that the SIGTERM is dispatched first, and SIGHUP second for those * processes which handle both. That's because services tend to bind configuration reload or something * else to SIGHUP. */ if (r != -ESRCH) (void) kill(pid, SIGHUP); quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC; } finish: _exit(r < 0 ? EXIT_FAILURE : r); }
static void test_align_power2(void) { unsigned long i, p2; assert_se(ALIGN_POWER2(0) == 0); assert_se(ALIGN_POWER2(1) == 1); assert_se(ALIGN_POWER2(2) == 2); assert_se(ALIGN_POWER2(3) == 4); assert_se(ALIGN_POWER2(12) == 16); assert_se(ALIGN_POWER2(ULONG_MAX) == 0); assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0); assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0); assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1); assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0); for (i = 1; i < 131071; ++i) { for (p2 = 1; p2 < i; p2 <<= 1) /* empty */ ; assert_se(ALIGN_POWER2(i) == p2); } for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) { for (p2 = 1; p2 && p2 < i; p2 <<= 1) /* empty */ ; assert_se(ALIGN_POWER2(i) == p2); } }
static int setup_machine_raw(uint64_t size, sd_bus_error *error) { _cleanup_free_ char *tmp = NULL; _cleanup_close_ int fd = -1; struct statvfs ss; pid_t pid = 0; siginfo_t si; int r; /* We want to be able to make use of btrfs-specific file * system features, in particular subvolumes, reflinks and * quota. Hence, if we detect that /var/lib/machines.raw is * not located on btrfs, let's create a loopback file, place a * btrfs file system into it, and mount it to * /var/lib/machines. */ fd = open("/var/lib/machines.raw", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); if (fd >= 0) { r = fd; fd = -1; return r; } if (errno != ENOENT) return sd_bus_error_set_errnof(error, errno, "Failed to open /var/lib/machines.raw: %m"); r = tempfn_xxxxxx("/var/lib/machines.raw", &tmp); if (r < 0) return r; (void) mkdir_p_label("/var/lib", 0755); fd = open(tmp, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0600); if (fd < 0) return sd_bus_error_set_errnof(error, errno, "Failed to create /var/lib/machines.raw: %m"); if (fstatvfs(fd, &ss) < 0) { r = sd_bus_error_set_errnof(error, errno, "Failed to determine free space on /var/lib/machines.raw: %m"); goto fail; } if (ss.f_bsize * ss.f_bavail < VAR_LIB_MACHINES_FREE_MIN) { r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Not enough free disk space to set up /var/lib/machines."); goto fail; } if (ftruncate(fd, size) < 0) { r = sd_bus_error_set_errnof(error, errno, "Failed to enlarge /var/lib/machines.raw: %m"); goto fail; } pid = fork(); if (pid < 0) { r = sd_bus_error_set_errnof(error, errno, "Failed to fork mkfs.btrfs: %m"); goto fail; } if (pid == 0) { /* Child */ (void) reset_all_signal_handlers(); (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); fd = safe_close(fd); execlp("mkfs.btrfs", "-Lvar-lib-machines", tmp, NULL); if (errno == ENOENT) return 99; _exit(EXIT_FAILURE); } r = wait_for_terminate(pid, &si); if (r < 0) { sd_bus_error_set_errnof(error, r, "Failed to wait for mkfs.btrfs: %m"); goto fail; } pid = 0; if (si.si_code != CLD_EXITED) { r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs died abnormally."); goto fail; } if (si.si_status == 99) { r = sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing"); goto fail; } if (si.si_status != 0) { r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs failed with error code %i", si.si_status); goto fail; } r = rename_noreplace(AT_FDCWD, tmp, AT_FDCWD, "/var/lib/machines.raw"); if (r < 0) { sd_bus_error_set_errnof(error, r, "Failed to move /var/lib/machines.raw into place: %m"); goto fail; } r = fd; fd = -1; return r; fail: unlink_noerrno(tmp); if (pid > 1) kill_and_sigcont(pid, SIGKILL); return r; }
static void test_cunescape(void) { _cleanup_free_ char *unescaped; unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"); assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313")); }
static void test_undecchar(void) { assert_se(undecchar('0') == 0); assert_se(undecchar('9') == 9); }
static void test_decchar(void) { assert_se(decchar(0) == '0'); assert_se(decchar(9) == '9'); }
static int manager_send_request(Manager *m) { _cleanup_free_ char *pretty = NULL; struct ntp_msg ntpmsg = { /* * "The client initializes the NTP message header, sends the request * to the server, and strips the time of day from the Transmit * Timestamp field of the reply. For this purpose, all the NTP * header fields are set to 0, except the Mode, VN, and optional * Transmit Timestamp fields." */ .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT), }; ssize_t len; int r; assert(m); assert(m->current_server_name); assert(m->current_server_address); m->event_timeout = sd_event_source_unref(m->event_timeout); /* * Set transmit timestamp, remember it; the server will send that back * as the origin timestamp and we have an indication that this is the * matching answer to our request. * * The actual value does not matter, We do not care about the correct * NTP UINT_MAX fraction; we just pass the plain nanosecond value. */ assert_se(clock_gettime(clock_boottime_or_monotonic(), &m->trans_time_mon) >= 0); assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0); ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970); ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec); server_address_pretty(m->current_server_address, &pretty); len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &m->current_server_address->sockaddr.sa, m->current_server_address->socklen); if (len == sizeof(ntpmsg)) { m->pending = true; log_debug("Sent NTP request to %s (%s).", strna(pretty), m->current_server_name->string); } else { log_debug("Sending NTP request to %s (%s) failed: %m", strna(pretty), m->current_server_name->string); return manager_connect(m); } /* re-arm timer with increasing timeout, in case the packets never arrive back */ if (m->retry_interval > 0) { if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC) m->retry_interval *= 2; } else m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC; r = manager_arm_timer(m, m->retry_interval); if (r < 0) { log_error("Failed to rearm timer: %s", strerror(-r)); return r; } r = sd_event_add_time( m->event, &m->event_timeout, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + TIMEOUT_USEC, 0, manager_timeout, m); if (r < 0) { log_error("Failed to arm timeout timer: %s", strerror(-r)); return r; } return 0; } static int manager_timer(sd_event_source *source, usec_t usec, void *userdata) { Manager *m = userdata; assert(m); return manager_send_request(m); }
static void test_strv_join_prefix(void) { _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL; p = strv_join_prefix((char **)input_table_multiple, ", ", "foo"); assert_se(p); assert_se(streq(p, "fooone, footwo, foothree")); q = strv_join_prefix((char **)input_table_multiple, ";", "foo"); assert_se(q); assert_se(streq(q, "fooone;footwo;foothree")); r = strv_join_prefix((char **)input_table_multiple, NULL, "foo"); assert_se(r); assert_se(streq(r, "fooone footwo foothree")); s = strv_join_prefix((char **)input_table_one, ", ", "foo"); assert_se(s); assert_se(streq(s, "fooone")); t = strv_join_prefix((char **)input_table_none, ", ", "foo"); assert_se(t); assert_se(streq(t, "")); v = strv_join_prefix((char **)input_table_two_empties, ", ", "foo"); assert_se(v); assert_se(streq(v, "foo, foo")); w = strv_join_prefix((char **)input_table_one_empty, ", ", "foo"); assert_se(w); assert_se(streq(w, "foo")); }
static int manager_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) { Manager *m = userdata; struct ntp_msg ntpmsg; struct iovec iov = { .iov_base = &ntpmsg, .iov_len = sizeof(ntpmsg), }; union { struct cmsghdr cmsghdr; uint8_t buf[CMSG_SPACE(sizeof(struct timeval))]; } control; union sockaddr_union server_addr; struct msghdr msghdr = { .msg_iov = &iov, .msg_iovlen = 1, .msg_control = &control, .msg_controllen = sizeof(control), .msg_name = &server_addr, .msg_namelen = sizeof(server_addr), }; struct cmsghdr *cmsg; struct timespec now_ts; struct timeval *recv_time; ssize_t len; double origin, receive, trans, dest; double delay, offset; bool spike; int leap_sec; int r; assert(source); assert(m); if (revents & (EPOLLHUP|EPOLLERR)) { log_warning("Server connection returned error."); return manager_connect(m); } len = recvmsg(fd, &msghdr, MSG_DONTWAIT); if (len < 0) { if (errno == EAGAIN) return 0; log_warning("Error receiving message. Disconnecting."); return manager_connect(m); } if (iov.iov_len < sizeof(struct ntp_msg)) { log_warning("Invalid response from server. Disconnecting."); return manager_connect(m); } if (!m->current_server_name || !m->current_server_address || !sockaddr_equal(&server_addr, &m->current_server_address->sockaddr)) { log_debug("Response from unknown server."); return 0; } recv_time = NULL; for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) continue; switch (cmsg->cmsg_type) { case SCM_TIMESTAMP: recv_time = (struct timeval *) CMSG_DATA(cmsg); break; } } if (!recv_time) { log_error("Invalid packet timestamp."); return -EINVAL; } if (!m->pending) { log_debug("Unexpected reply. Ignoring."); return 0; } /* check our "time cookie" (we just stored nanoseconds in the fraction field) */ if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 || be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) { log_debug("Invalid reply; not our transmit time. Ignoring."); return 0; } m->event_timeout = sd_event_source_unref(m->event_timeout); if (be32toh(ntpmsg.recv_time.sec) < TIME_EPOCH + OFFSET_1900_1970 || be32toh(ntpmsg.trans_time.sec) < TIME_EPOCH + OFFSET_1900_1970) { log_debug("Invalid reply, returned times before epoch. Ignoring."); return manager_connect(m); } if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) { log_debug("Server is not synchronized. Disconnecting."); return manager_connect(m); } if (!IN_SET(NTP_FIELD_VERSION(ntpmsg.field), 3, 4)) { log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field)); return manager_connect(m); } if (NTP_FIELD_MODE(ntpmsg.field) != NTP_MODE_SERVER) { log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg.field)); return manager_connect(m); } /* valid packet */ m->pending = false; m->retry_interval = 0; /* announce leap seconds */ if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC) leap_sec = 1; else if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_MINUSSEC) leap_sec = -1; else leap_sec = 0; /* * "Timestamp Name ID When Generated * ------------------------------------------------------------ * Originate Timestamp T1 time request sent by client * Receive Timestamp T2 time request received by server * Transmit Timestamp T3 time reply sent by server * Destination Timestamp T4 time reply received by client * * The round-trip delay, d, and system clock offset, t, are defined as: * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2" */ assert_se(clock_gettime(clock_boottime_or_monotonic(), &now_ts) >= 0); origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970; receive = ntp_ts_to_d(&ntpmsg.recv_time); trans = ntp_ts_to_d(&ntpmsg.trans_time); dest = tv_to_d(recv_time) + OFFSET_1900_1970; offset = ((receive - origin) + (trans - dest)) / 2; delay = (dest - origin) - (trans - receive); spike = manager_sample_spike_detection(m, offset, delay); manager_adjust_poll(m, offset, spike); log_debug("NTP response:\n" " leap : %u\n" " version : %u\n" " mode : %u\n" " stratum : %u\n" " precision : %.6f sec (%d)\n" " reference : %.4s\n" " origin : %.3f\n" " receive : %.3f\n" " transmit : %.3f\n" " dest : %.3f\n" " offset : %+.3f sec\n" " delay : %+.3f sec\n" " packet count : %"PRIu64"\n" " jitter : %.3f%s\n" " poll interval: " USEC_FMT "\n", NTP_FIELD_LEAP(ntpmsg.field), NTP_FIELD_VERSION(ntpmsg.field), NTP_FIELD_MODE(ntpmsg.field), ntpmsg.stratum, exp2(ntpmsg.precision), ntpmsg.precision, ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a", origin - OFFSET_1900_1970, receive - OFFSET_1900_1970, trans - OFFSET_1900_1970, dest - OFFSET_1900_1970, offset, delay, m->packet_count, m->samples_jitter, spike ? " spike" : "", m->poll_interval_usec / USEC_PER_SEC); if (!spike) { m->sync = true; r = manager_adjust_clock(m, offset, leap_sec); if (r < 0) log_error("Failed to call clock_adjtime(): %m"); } log_info("interval/delta/delay/jitter/drift " USEC_FMT "s/%+.3fs/%.3fs/%.3fs/%+ippm%s", m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm, spike ? " (ignored)" : ""); r = manager_arm_timer(m, m->poll_interval_usec); if (r < 0) { log_error("Failed to rearm timer: %s", strerror(-r)); return r; } return 0; } static int manager_listen_setup(Manager *m) { union sockaddr_union addr = {}; static const int tos = IPTOS_LOWDELAY; static const int on = 1; int r; assert(m); assert(m->server_socket < 0); assert(!m->event_receive); assert(m->current_server_address); addr.sa.sa_family = m->current_server_address->sockaddr.sa.sa_family; m->server_socket = socket(addr.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (m->server_socket < 0) return -errno; r = bind(m->server_socket, &addr.sa, m->current_server_address->socklen); if (r < 0) return -errno; r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)); if (r < 0) return -errno; setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m); } static int manager_begin(Manager *m) { _cleanup_free_ char *pretty = NULL; int r; assert(m); assert_return(m->current_server_name, -EHOSTUNREACH); assert_return(m->current_server_address, -EHOSTUNREACH); m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC; server_address_pretty(m->current_server_address, &pretty); log_info("Using NTP server %s (%s).", strna(pretty), m->current_server_name->string); sd_notifyf(false, "STATUS=Using Time Server %s (%s).", strna(pretty), m->current_server_name->string); r = manager_listen_setup(m); if (r < 0) { log_warning("Failed to setup connection socket: %s", strerror(-r)); return r; } r = manager_clock_watch_setup(m); if (r < 0) return r; return manager_send_request(m); } void manager_set_server_name(Manager *m, ServerName *n) { assert(m); if (m->current_server_name == n) return; m->current_server_name = n; m->current_server_address = NULL; manager_disconnect(m); if (n) log_debug("Selected server %s.", n->string); }
static void test_strv_split(void) { _cleanup_strv_free_ char **l = NULL; const char str[] = "one,two,three"; l = strv_split(str, ","); assert_se(l); assert_se(strv_equal(l, (char**) input_table_multiple)); strv_free(l); l = strv_split(" one two\t three", WHITESPACE); assert_se(l); assert_se(strv_equal(l, (char**) input_table_multiple)); strv_free(l); /* Setting NULL for separator is equivalent to WHITESPACE */ l = strv_split(" one two\t three", NULL); assert_se(l); assert_se(strv_equal(l, (char**) input_table_multiple)); strv_free(l); l = strv_split_full(" one two\t three", NULL, 0); assert_se(l); assert_se(strv_equal(l, (char**) input_table_multiple)); strv_free(l); l = strv_split_full(" 'one' \" two\t three \" ' four five'", NULL, SPLIT_QUOTES); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); strv_free(l); /* missing last quote ignores the last element. */ l = strv_split_full(" 'one' \" two\t three \" ' four five' ' ignored element ", NULL, SPLIT_QUOTES); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); strv_free(l); /* missing last quote, but the last element is _not_ ignored with SPLIT_RELAX. */ l = strv_split_full(" 'one' \" two\t three \" ' four five", NULL, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); strv_free(l); /* missing separator between */ l = strv_split_full(" 'one' \" two\t three \"' four five'", NULL, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); strv_free(l); l = strv_split_full(" 'one' \" two\t three \"' four five", NULL, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); }
int main(int argc, char *argv[]) { _cleanup_journal_close_ sd_journal*j; _cleanup_free_ char *t; log_set_max_level(LOG_DEBUG); assert_se(sd_journal_open(&j, 0) >= 0); assert_se(sd_journal_add_match(j, "foobar", 0) < 0); assert_se(sd_journal_add_match(j, "foobar=waldo", 0) < 0); assert_se(sd_journal_add_match(j, "", 0) < 0); assert_se(sd_journal_add_match(j, "=", 0) < 0); assert_se(sd_journal_add_match(j, "=xxxxx", 0) < 0); assert_se(sd_journal_add_match(j, "HALLO=WALDO", 0) >= 0); assert_se(sd_journal_add_match(j, "QUUX=mmmm", 0) >= 0); assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0); assert_se(sd_journal_add_match(j, "HALLO=", 0) >= 0); assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0); assert_se(sd_journal_add_match(j, "QUUX=yyyyy", 0) >= 0); assert_se(sd_journal_add_match(j, "PIFF=paff", 0) >= 0); assert_se(sd_journal_add_disjunction(j) >= 0); assert_se(sd_journal_add_match(j, "ONE=one", 0) >= 0); assert_se(sd_journal_add_match(j, "ONE=two", 0) >= 0); assert_se(sd_journal_add_match(j, "TWO=two", 0) >= 0); assert_se(sd_journal_add_conjunction(j) >= 0); assert_se(sd_journal_add_match(j, "L4_1=yes", 0) >= 0); assert_se(sd_journal_add_match(j, "L4_1=ok", 0) >= 0); assert_se(sd_journal_add_match(j, "L4_2=yes", 0) >= 0); assert_se(sd_journal_add_match(j, "L4_2=ok", 0) >= 0); assert_se(sd_journal_add_disjunction(j) >= 0); assert_se(sd_journal_add_match(j, "L3=yes", 0) >= 0); assert_se(sd_journal_add_match(j, "L3=ok", 0) >= 0); assert_se(t = journal_make_match_string(j)); printf("resulting match expression is: %s\n", t); assert_se(streq(t, "(((L3=ok OR L3=yes) OR ((L4_2=ok OR L4_2=yes) AND (L4_1=ok OR L4_1=yes))) AND ((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO))))")); return 0; }
static void test_strv_split_empty(void) { _cleanup_strv_free_ char **l = NULL; l = strv_split("", WHITESPACE); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split("", NULL); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split_full("", NULL, 0); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split_full("", NULL, SPLIT_QUOTES); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split_full("", WHITESPACE, SPLIT_QUOTES); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split_full("", WHITESPACE, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split(" ", WHITESPACE); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split(" ", NULL); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split_full(" ", NULL, 0); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split_full(" ", WHITESPACE, SPLIT_QUOTES); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split_full(" ", NULL, SPLIT_QUOTES); assert_se(l); assert_se(strv_isempty(l)); strv_free(l); l = strv_split_full(" ", NULL, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_isempty(l)); }
static void test_streq_ptr(void) { assert_se(streq_ptr(NULL, NULL)); assert_se(!streq_ptr("abc", "cdef")); }
static void test_str_in_set(void) { assert_se(STR_IN_SET("x", "x", "y", "z")); assert_se(!STR_IN_SET("X", "x", "y", "z")); assert_se(!STR_IN_SET("", "x", "y", "z")); assert_se(STR_IN_SET("x", "w", "x")); }
static void test_ascii_strlower(void) { char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK"; assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk")); }
static void test_strv_find(void) { assert_se(strv_find((char **)input_table_multiple, "three")); assert_se(!strv_find((char **)input_table_multiple, "four")); }
static void test_ascii_strcasecmp_nn(void) { assert_se(ascii_strcasecmp_nn("", 0, "", 0) == 0); assert_se(ascii_strcasecmp_nn("", 0, "", 1) < 0); assert_se(ascii_strcasecmp_nn("", 1, "", 0) > 0); assert_se(ascii_strcasecmp_nn("", 1, "", 1) == 0); assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaAa", 4) == 0); assert_se(ascii_strcasecmp_nn("aaa", 3, "aaAa", 4) < 0); assert_se(ascii_strcasecmp_nn("aaa", 4, "aaAa", 4) < 0); assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaA", 3) > 0); assert_se(ascii_strcasecmp_nn("aaaa", 4, "AAA", 4) > 0); assert_se(ascii_strcasecmp_nn("aaaa", 4, "bbbb", 4) < 0); assert_se(ascii_strcasecmp_nn("aaAA", 4, "BBbb", 4) < 0); assert_se(ascii_strcasecmp_nn("BBbb", 4, "aaaa", 4) > 0); }
sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) { if (lease) assert_se(REFCNT_INC(lease->n_ref) >= 2); return lease; }
static void test_socket_address_equal(void) { SocketAddress a; SocketAddress b; assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0); assert_se(!socket_address_equal(&a, &b)); assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0); assert_se(!socket_address_equal(&a, &b)); assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); assert_se(socket_address_parse(&b, "8888") >= 0); assert_se(!socket_address_equal(&a, &b)); assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); assert_se(socket_address_parse(&b, "/foo/bar/") >= 0); assert_se(!socket_address_equal(&a, &b)); assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0); assert_se(socket_address_equal(&a, &b)); assert_se(socket_address_parse(&a, "/foo/bar") >= 0); assert_se(socket_address_parse(&b, "/foo/bar") >= 0); assert_se(socket_address_equal(&a, &b)); assert_se(socket_address_parse(&a, "[::1]:8888") >= 0); assert_se(socket_address_parse(&b, "[::1]:8888") >= 0); assert_se(socket_address_equal(&a, &b)); assert_se(socket_address_parse(&a, "@abstract") >= 0); assert_se(socket_address_parse(&b, "@abstract") >= 0); assert_se(socket_address_equal(&a, &b)); assert_se(socket_address_parse_netlink(&a, "firewall") >= 0); assert_se(socket_address_parse_netlink(&b, "firewall") >= 0); assert_se(socket_address_equal(&a, &b)); }
int main(int argc, char *argv[]) { _cleanup_close_ int bus_ref = -1; _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; const char *ua = NULL, *ub = NULL, *the_string = NULL; sd_bus *a, *b; int r, pipe_fds[2]; const char *nn; log_set_max_level(LOG_DEBUG); assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0); bus_ref = bus_kernel_create_bus(name, false, &bus_name); if (bus_ref == -ENOENT) return EXIT_TEST_SKIP; assert_se(bus_ref >= 0); address = strappend("kernel:path=", bus_name); assert_se(address); r = sd_bus_new(&a); assert_se(r >= 0); r = sd_bus_new(&b); assert_se(r >= 0); r = sd_bus_set_name(a, "a"); assert_se(r >= 0); r = sd_bus_set_address(a, address); assert_se(r >= 0); r = sd_bus_set_address(b, address); assert_se(r >= 0); assert_se(sd_bus_negotiate_timestamp(a, 1) >= 0); assert_se(sd_bus_negotiate_creds(a, _SD_BUS_CREDS_ALL) >= 0); assert_se(sd_bus_negotiate_timestamp(b, 1) >= 0); assert_se(sd_bus_negotiate_creds(b, _SD_BUS_CREDS_ALL) >= 0); r = sd_bus_start(a); assert_se(r >= 0); r = sd_bus_start(b); assert_se(r >= 0); r = sd_bus_get_unique_name(a, &ua); assert_se(r >= 0); printf("unique a: %s\n", ua); r = sd_bus_get_name(a, &nn); assert_se(r >= 0); printf("name of a: %s\n", nn); r = sd_bus_get_unique_name(b, &ub); assert_se(r >= 0); printf("unique b: %s\n", ub); r = sd_bus_get_name(b, &nn); assert_se(r >= 0); printf("name of b: %s\n", nn); r = sd_bus_call_method(a, "this.doesnt.exist", "/foo", "meh.mah", "muh", &error, NULL, "s", "yayayay"); assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_SERVICE_UNKNOWN)); assert_se(r == -EHOSTUNREACH); r = sd_bus_add_match(b, "interface='waldo.com',member='Piep'", NULL, NULL); assert_se(r >= 0); r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name"); assert_se(r >= 0); r = sd_bus_try_close(b); assert_se(r == -EBUSY); r = sd_bus_process_priority(b, -10, &m); assert_se(r == -ENOMSG); r = sd_bus_process(b, &m); assert_se(r > 0); assert_se(m); bus_message_dump(m, stdout, true); assert_se(sd_bus_message_rewind(m, true) >= 0); r = sd_bus_message_read(m, "s", &the_string); assert_se(r >= 0); assert_se(streq(the_string, "I am a string")); sd_bus_message_unref(m); m = NULL; r = sd_bus_request_name(a, "net.x0pointer.foobar", 0); assert_se(r >= 0); r = sd_bus_message_new_method_call(b, &m, "net.x0pointer.foobar", "/a/path", "an.inter.face", "AMethod"); assert_se(r >= 0); assert_se(pipe2(pipe_fds, O_CLOEXEC) >= 0); assert_se(write(pipe_fds[1], "x", 1) == 1); pipe_fds[1] = safe_close(pipe_fds[1]); r = sd_bus_message_append(m, "h", pipe_fds[0]); assert_se(r >= 0); pipe_fds[0] = safe_close(pipe_fds[0]); r = sd_bus_send(b, m, NULL); assert_se(r >= 0); for (;;) { sd_bus_message_unref(m); m = NULL; r = sd_bus_process(a, &m); assert_se(r > 0); assert_se(m); bus_message_dump(m, stdout, true); assert_se(sd_bus_message_rewind(m, true) >= 0); if (sd_bus_message_is_method_call(m, "an.inter.face", "AMethod")) { int fd; char x; r = sd_bus_message_read(m, "h", &fd); assert_se(r >= 0); assert_se(read(fd, &x, 1) == 1); assert_se(x == 'x'); break; } } r = sd_bus_release_name(a, "net.x0pointer.foobar"); assert_se(r >= 0); r = sd_bus_release_name(a, "net.x0pointer.foobar"); assert_se(r == -ESRCH); r = sd_bus_try_close(a); assert_se(r >= 0); sd_bus_unref(a); sd_bus_unref(b); return 0; }
static void test_deserialize_in_addr(void) { _cleanup_free_ struct in_addr *addresses = NULL; _cleanup_free_ struct in6_addr *addresses6 = NULL; struct in_addr a, b, c; struct in6_addr d, e, f; int size; const char *addresses_string = "192.168.0.1 0:0:0:0:0:FFFF:204.152.189.116 192.168.0.2 ::1 192.168.0.3 1:0:0:0:0:0:0:8"; assert_se(inet_pton(AF_INET, "0:0:0:0:0:FFFF:204.152.189.116", &a) == 0); assert_se(inet_pton(AF_INET6, "192.168.0.1", &d) == 0); assert_se(inet_pton(AF_INET, "192.168.0.1", &a) == 1); assert_se(inet_pton(AF_INET, "192.168.0.2", &b) == 1); assert_se(inet_pton(AF_INET, "192.168.0.3", &c) == 1); assert_se(inet_pton(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116", &d) == 1); assert_se(inet_pton(AF_INET6, "::1", &e) == 1); assert_se(inet_pton(AF_INET6, "1:0:0:0:0:0:0:8", &f) == 1); assert_se((size = deserialize_in_addrs(&addresses, addresses_string)) >= 0); assert_se(size == 3); assert_se(!memcmp(&a, &addresses[0], sizeof(struct in_addr))); assert_se(!memcmp(&b, &addresses[1], sizeof(struct in_addr))); assert_se(!memcmp(&c, &addresses[2], sizeof(struct in_addr))); assert_se((size = deserialize_in6_addrs(&addresses6, addresses_string)) >= 0); assert_se(size == 3); assert_se(!memcmp(&d, &addresses6[0], sizeof(struct in6_addr))); assert_se(!memcmp(&e, &addresses6[1], sizeof(struct in6_addr))); assert_se(!memcmp(&f, &addresses6[2], sizeof(struct in6_addr))); }
static void test_octchar(void) { assert_se(octchar(00) == '0'); assert_se(octchar(07) == '7'); }