]> git.saurik.com Git - apple/hfs.git/blob - tests/cases/test-quotas.c
hfs-522.0.9.tar.gz
[apple/hfs.git] / tests / cases / test-quotas.c
1 //
2 // quotas.c
3 // hfs
4 //
5 // Created by Chris Suter on 8/13/15.
6 //
7 //
8
9 #include <TargetConditionals.h>
10
11 #if !TARGET_OS_IPHONE
12
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <sys/types.h>
17 #include <sys/quota.h>
18 #include <sys/stat.h>
19
20 #include "hfs-tests.h"
21 #include "disk-image.h"
22 #include "test-utils.h"
23
24 #define QUOTA_DMG "/tmp/quota-test.sparseimage"
25 #define QUOTA_DMG_MOUNT_POINT "/tmp/quota-test-mount"
26
27 TEST(quotas, .run_as_root = true)
28
29 // This is what the quota file looks like after running edquota
30 char quota_file[] = {
31 0xff, 0x31, 0xff, 0x35, 0x00, 0x00, 0x00, 0x01,
32 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x09, 0x3a, 0x80, 0x00, 0x09, 0x3a, 0x80,
35 0x51, 0x55, 0x4f, 0x54, 0x41, 0x20, 0x48, 0x41,
36 0x53, 0x48, 0x20, 0x46, 0x49, 0x4c, 0x45, 0x00,
37 // Zero padding up to 131136 bytes
38 };
39
40 int run_quotas(__unused test_ctx_t *ctx)
41 {
42 disk_image_t *di = disk_image_create(QUOTA_DMG,
43 &(disk_image_opts_t) {
44 #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
45 .mount_point = QUOTA_DMG_MOUNT_POINT,
46 #endif
47 .size = 64 * 1024 * 1024,
48 .enable_owners = true
49 });
50
51 char *path;
52 asprintf(&path, "%s/.quota.ops.user", di->mount_point);
53 int fd = open(path, O_CREAT | O_RDWR, 0777);
54 assert_with_errno(fd >= 0);
55 free(path);
56 assert_no_err(close(fd));
57
58 asprintf(&path, "%s/.quota.user", di->mount_point);
59 fd = open(path, O_CREAT | O_RDWR, 0777);
60 assert_with_errno(fd >= 0);
61 check_io(write(fd, quota_file, lengthof(quota_file)), lengthof(quota_file));
62 assert_no_err(ftruncate(fd, 131136));
63 assert_no_err(close(fd));
64
65 assert_no_err(quotactl(di->mount_point, QCMD(Q_QUOTAON, USRQUOTA), 0, path));
66 free(path);
67
68 struct dqblk dqb = {
69 .dqb_bhardlimit = 1024 * 1024,
70 .dqb_ihardlimit = 10,
71 .dqb_isoftlimit = 10,
72 };
73
74 assert_no_err(quotactl(di->mount_point, QCMD(Q_SETQUOTA, USRQUOTA),
75 501, (caddr_t)&dqb));
76
77 assert_no_err(chmod(di->mount_point, 0777));
78
79 // Now try and create a 2 MB file as UID 501
80 assert_no_err(seteuid(501));
81
82 asprintf(&path, "%s/test-file", di->mount_point);
83
84 fd = open(path, O_CREAT | O_RDWR, 0777);
85 assert_with_errno(fd >= 0);
86 free(path);
87
88 /*
89 * Not sure why we can't do the full 4 KB, but it's not a big deal
90 * so let's not worry about it.
91 */
92 assert_no_err(ftruncate(fd, 1024 * 1024 - 4096));
93
94 assert(ftruncate(fd, 2 * 1024 * 1024) == -1 && errno == EDQUOT);
95
96 assert_no_err(close(fd));
97
98 for (int i = 0; i < 10; ++i) {
99 asprintf(&path, "%s/test-file.%u", di->mount_point, i);
100 /*
101 * There might be an off by one error. It's not a big deal,
102 * so we let it go for now.
103 */
104 fd = open(path, O_CREAT | O_RDWR, 0777);
105 if (fd == -1) {
106 assert(i >= 8);
107 assert_with_errno(errno == EDQUOT);
108 } else {
109 assert(i < 8);
110 free(path);
111 assert_no_err(close(fd));
112 }
113 }
114
115 return 0;
116 }
117 #endif // !TARGET_OS_EMBEDDED