skip to content
==> tests/shm.c <==
1/* shm.rs's tests: two mappings share words; a child's writes land in the parent's mapping. */
2#include "mesh/check.h"
3#include "mesh/shm.h"
4
5#include <fcntl.h>
6#include <stdatomic.h>
7#include <stdint.h>
8#include <stdlib.h>
9#include <sys/mman.h>
10#include <sys/wait.h>
11#include <unistd.h>
12
13int main(void) {
14    mesh_shm s;
15    char *err = NULL;
16    CHECK(mesh_shm_with_len(1 << 16, &s, &err));
17    CHECK_U((uintptr_t)s.base % 4096, 0);
18    int fd = dup(s.fd);
19    uint8_t *q = mmap(NULL, 1 << 16, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
20    CHECK(q != MAP_FAILED);
21    _Atomic uint32_t *a = (_Atomic uint32_t *)(s.base + 0x100), *b = (_Atomic uint32_t *)(q + 0x100);
22    CHECK_U(atomic_load(b), 0);
23    atomic_store(a, 0xfeed);
24    CHECK_U(atomic_load(b), 0xfeed);
25    atomic_fetch_add(b, 1);
26    CHECK_U(atomic_load(a), 0xfeee);
27    /* close-on-exec: children get it only by dup2 */
28    CHECK((fcntl(s.fd, F_GETFD) & FD_CLOEXEC) != 0);
29    munmap(q, 1 << 16);
30    close(fd);
31    /* across a fork */
32    _Atomic uint32_t *w = (_Atomic uint32_t *)(s.base + 0x40);
33    pid_t pid = fork();
34    if (pid == 0) {
35        atomic_store(w, 77);
36        _exit(0);
37    }
38    int st;
39    waitpid(pid, &st, 0);
40    CHECK_U(atomic_load(w), 77);
41    char *path = mesh_shm_path(&s);
42    int pfd = open(path, O_RDWR);
43    CHECK(pfd >= 0);
44    close(pfd);
45    free(path);
46    mesh_shm_close(&s);
47    /* The full mailbox. */
48    mesh_shm mb;
49    CHECK(mesh_shm_new(&mb, &err));
50    CHECK_U(mb.len, 0x800000);
51    mesh_shm_close(&mb);
52    return mesh_check_done();
53}