]>
Commit | Line | Data |
---|---|---|
f427ee49 A |
1 | #include <darwintest.h> |
2 | #include <errno.h> | |
3 | #include <fcntl.h> | |
4 | #include <signal.h> | |
5 | #include <stdio.h> | |
6 | #include <sys/resource.h> | |
7 | #include <unistd.h> | |
8 | ||
9 | T_GLOBAL_META(T_META_NAMESPACE("xnu.vfs")); | |
10 | ||
11 | #define FSIZE_CUR (10*1024) | |
12 | #define TMP_FILE_PATH "/tmp/ftruncate_test" | |
13 | ||
14 | static int sigcount = 0; | |
15 | ||
16 | static void | |
17 | xfsz_signal_handler(__unused int signo) | |
18 | { | |
19 | sigcount++; | |
20 | } | |
21 | ||
22 | static void | |
23 | fsize_test(bool use_fd) | |
24 | { | |
25 | struct rlimit rlim; | |
26 | int fd, ret; | |
27 | ||
28 | T_SETUPBEGIN; | |
29 | ||
30 | signal(SIGXFSZ, xfsz_signal_handler); | |
31 | ||
32 | rlim.rlim_cur = FSIZE_CUR; | |
33 | rlim.rlim_max = RLIM_INFINITY; | |
34 | ret = setrlimit(RLIMIT_FSIZE, &rlim); | |
35 | T_ASSERT_POSIX_SUCCESS(ret, "set soft RLIMIT_FSIZE to %d", FSIZE_CUR); | |
36 | ||
37 | fd = open(TMP_FILE_PATH, O_RDWR | O_CREAT, 0777); | |
38 | T_ASSERT_POSIX_SUCCESS(ret, "create temp file: %s", TMP_FILE_PATH); | |
39 | ||
40 | T_SETUPEND; | |
41 | ||
42 | if (use_fd) { | |
43 | ret = ftruncate(fd, FSIZE_CUR); | |
44 | T_EXPECT_POSIX_SUCCESS(ret, "ftruncate() with length RLIMIT_FSIZE"); | |
45 | } else { | |
46 | ret = truncate(TMP_FILE_PATH, FSIZE_CUR); | |
47 | T_EXPECT_POSIX_SUCCESS(ret, "truncate() with length RLIMIT_FSIZE"); | |
48 | } | |
49 | T_EXPECT_EQ(sigcount, 0, "no signal received"); | |
50 | ||
51 | if (use_fd) { | |
52 | ret = ftruncate(fd, FSIZE_CUR + 1); | |
53 | T_EXPECT_POSIX_FAILURE(ret, EFBIG, "ftruncate() with length RLIMIT_FSIZE + 1"); | |
54 | } else { | |
55 | ret = truncate(TMP_FILE_PATH, FSIZE_CUR + 1); | |
56 | T_EXPECT_POSIX_FAILURE(ret, EFBIG, "truncate() with length RLIMIT_FSIZE + 1"); | |
57 | } | |
58 | T_EXPECT_EQ(sigcount, 1, "SIGXFSZ signal received"); | |
59 | ||
60 | ret = close(fd); | |
61 | T_ASSERT_POSIX_SUCCESS(ret, "close temp file"); | |
62 | ||
63 | ret = unlink(TMP_FILE_PATH); | |
64 | T_ASSERT_POSIX_SUCCESS(ret, "unlink temp file"); | |
65 | } | |
66 | ||
67 | T_DECL(ftruncate_fsize, | |
68 | "ftruncate() should fail with EFBIG and send SIGXFSZ signal when length > RLIMIT_FSIZE") | |
69 | { | |
70 | fsize_test(true); | |
71 | } | |
72 | ||
73 | T_DECL(truncate_fsize, | |
74 | "truncate() should fail with EFBIG and send SIGXFSZ signal when length > RLIMIT_FSIZE") | |
75 | { | |
76 | fsize_test(false); | |
77 | } |