]>
Commit | Line | Data |
---|---|---|
558d2836 A |
1 | #include <pthread.h> |
2 | #include <unistd.h> | |
3 | #include <hfs/hfs_mount.h> | |
4 | #include <sys/param.h> | |
5 | #include <sys/mount.h> | |
6 | #include <assert.h> | |
7 | #include <fcntl.h> | |
8 | #include <stdio.h> | |
9 | #include <stdbool.h> | |
10 | #include <TargetConditionals.h> | |
11 | #include <sys/socket.h> | |
12 | #include <sys/un.h> | |
13 | #include <sys/stat.h> | |
14 | ||
15 | #include "hfs-tests.h" | |
16 | #include "test-utils.h" | |
17 | #include "disk-image.h" | |
18 | ||
19 | TEST(fsync, .run_as_root = true) | |
20 | ||
21 | static int fd; | |
22 | volatile bool stop_thread; | |
23 | ||
24 | void *sync_thread(__unused void *arg) | |
25 | { | |
26 | while (!stop_thread) | |
27 | assert_no_err(fsync(fd)); | |
28 | ||
29 | return NULL; | |
30 | } | |
31 | ||
32 | int run_fsync(__unused test_ctx_t *ctx) | |
33 | { | |
34 | disk_image_t *di = NULL; | |
35 | const char *tstdir; | |
36 | ||
37 | #if TARGET_OS_EMBEDDED | |
38 | struct statfs sfs; | |
39 | bool hfs_root; | |
40 | ||
41 | assert(statfs("/tmp", &sfs) == 0); | |
42 | if (strcmp(sfs.f_fstypename, "hfs")) { | |
43 | hfs_root = false; | |
44 | di = disk_image_get(); | |
45 | tstdir = di->mount_point; | |
46 | } else { | |
47 | hfs_root = true; | |
48 | tstdir = "/tmp"; | |
49 | } | |
50 | #else // !TARGET_OS_EMBEDDED | |
51 | di = disk_image_get(); | |
52 | tstdir = di->mount_point; | |
53 | #endif | |
54 | ||
55 | char *file; | |
56 | asprintf(&file, "%s/fsync.data", tstdir); | |
57 | ||
58 | pthread_t thread; | |
59 | ||
60 | fd = open(file, O_RDWR | O_CREAT, 0666); | |
61 | ||
62 | assert_with_errno(fd >= 0); | |
63 | ||
64 | ||
65 | pthread_create(&thread, NULL, sync_thread, NULL); | |
66 | ||
67 | void *buf = valloc(65536); | |
68 | ||
69 | assert_no_err(fcntl(fd, F_NOCACHE, 1)); | |
70 | ||
71 | struct timeval start, now; | |
72 | gettimeofday(&start, NULL); | |
73 | do { | |
74 | check_io(pwrite(fd, buf, 65536, 0), 65536); | |
75 | ||
76 | gettimeofday(&now, NULL); | |
77 | } while (now.tv_sec < start.tv_sec + 10); | |
78 | ||
79 | stop_thread = true; | |
80 | pthread_join(thread, NULL); | |
81 | ||
82 | assert_no_err(close(fd)); | |
83 | assert_no_err(unlink(file)); | |
84 | ||
85 | assert_with_errno((fd = socket(PF_UNIX, SOCK_STREAM, 0)) >= 0); | |
86 | ||
87 | struct sockaddr_un addr = { | |
88 | .sun_family = AF_UNIX | |
89 | }; | |
90 | ||
91 | char *sock; | |
92 | asprintf(&sock, "%s/socket", tstdir); | |
93 | unlink(sock); | |
94 | strcpy(addr.sun_path, sock); | |
95 | ||
96 | assert_no_err(bind(fd, (struct sockaddr *)&addr, sizeof(addr))); | |
97 | ||
98 | // And a fifo | |
99 | char *fifo; | |
100 | asprintf(&fifo, "%s/fifo", tstdir); | |
101 | unlink(fifo); | |
102 | assert_no_err(mkfifo(fifo, 0666)); | |
103 | ||
104 | sync(); | |
105 | ||
106 | assert_no_err(unlink(sock)); | |
107 | assert_no_err(unlink(fifo)); | |
108 | ||
109 | free(file); | |
110 | free(sock); | |
111 | free(fifo); | |
112 | ||
113 | return 0; | |
114 | } |