]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/darwintests/pwrite_avoid_sigxfsz_28581610.c
xnu-3789.51.2.tar.gz
[apple/xnu.git] / tools / tests / darwintests / pwrite_avoid_sigxfsz_28581610.c
1 /*
2 * testname: pwrite_avoid_sigxfsz_28581610
3 */
4
5 #include <darwintest.h>
6 #include <fcntl.h>
7 #include <limits.h>
8 #include <setjmp.h>
9 #include <signal.h>
10 #include <sys/resource.h>
11 #include <sys/stat.h>
12 #include <unistd.h>
13
14 #define TMP_FILE_PATH "/tmp/test_pwrite"
15
16 static sigjmp_buf xfsz_jmpbuf;
17
18 void xfsz_signal(int);
19
20 void
21 xfsz_signal(__unused int signo)
22 {
23 siglongjmp(xfsz_jmpbuf, 1);
24 }
25
26 T_DECL(pwrite, "Tests avoiding SIGXFSZ with pwrite and odd offsets",
27 T_META_ASROOT(true))
28 {
29 int fd, x;
30 off_t ret;
31 struct stat f_stat;
32 struct rlimit crl;
33 static const int offs[] = { -1, -1 * 1024, -1 * 1024 * 16, -1 * 1024 * 1024 * 16, 0 };
34 static unsigned char buffer[1048576];
35
36 T_SETUPBEGIN;
37 /* We expect zero SIGXFSZ signals because we have no file size limits */
38 crl.rlim_cur = crl.rlim_max = RLIM_INFINITY;
39 ret = setrlimit(RLIMIT_FSIZE, &crl);
40 T_ASSERT_POSIX_SUCCESS(ret, "setting infinite file size limit");
41
42 /* we just needed root to setup unlimited file size */
43 remove(TMP_FILE_PATH);
44 setuid(5000);
45
46 /* We just want an empty regular file to test with */
47 fd = open(TMP_FILE_PATH, O_RDWR | O_CREAT | O_EXCL, 0777);
48 T_ASSERT_POSIX_SUCCESS(fd, "opening fd on temp file %s.", TMP_FILE_PATH);
49
50 /* sanity check that this new file is really zero bytes in size */
51 ret = fstat(fd, &f_stat);
52 T_ASSERT_POSIX_SUCCESS(ret, "stat() fd on temp file.");
53 T_ASSERT_TRUE(0 == f_stat.st_size, "ensure %s is empty", TMP_FILE_PATH);
54
55 /* sanity check that ftruncate() considers negative offsets an error */
56 for (x = 0; offs[x] != 0; x++) {
57 ret = ftruncate(fd, offs[x]);
58 T_ASSERT_TRUE(((ret == -1) && (errno == EINVAL)),
59 "negative offset %d", offs[x]);
60 }
61
62 T_SETUPEND;
63
64 /* we want to get the EFBIG errno but without a SIGXFSZ signal */
65 T_EXPECTFAIL;
66 if (!sigsetjmp(xfsz_jmpbuf, 1)) {
67 signal(SIGXFSZ, xfsz_signal);
68 ret = pwrite(fd, buffer, sizeof buffer, LONG_MAX);
69 T_ASSERT_TRUE(((ret == -1) && (errno == EFBIG)),
70 "large offset %d", 13);
71 } else {
72 signal(SIGXFSZ, SIG_DFL);
73 T_FAIL("%s unexpected SIGXFSZ with offset %lX",
74 "<rdar://problem/28581610>", LONG_MAX);
75 }
76
77 /* Negative offsets are invalid, no SIGXFSZ signals required */
78 for (x = 0; offs[x] != 0; x++) {
79 /* only -1 gives the correct result */
80 if (-1 != offs[x]) {
81 T_EXPECTFAIL;
82 }
83
84 if (!sigsetjmp(xfsz_jmpbuf, 1)) {
85 signal(SIGXFSZ, xfsz_signal);
86 ret = pwrite(fd, buffer, sizeof buffer, offs[x]);
87 T_ASSERT_TRUE(((ret == -1) && (errno == EINVAL)),
88 "negative offset %d", offs[x]);
89 } else {
90 signal(SIGXFSZ, SIG_DFL);
91 T_FAIL("%s unexpected SIGXFSZ with negative offset %d",
92 "<rdar://problem/28581610>", offs[x]);
93 }
94 }
95
96 remove(TMP_FILE_PATH);
97 }