]> git.saurik.com Git - apple/libc.git/blob - tests/subsystem_test_helper.c
Libc-1439.100.3.tar.gz
[apple/libc.git] / tests / subsystem_test_helper.c
1 /*
2 * Copyright (c) 2019 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <fcntl.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <subsystem.h>
33 #include <sys/stat.h>
34 #include <sys/errno.h>
35 #include "subsystem_test.h"
36
37 #include <stdio.h>
38
39 /*
40 * main expects 3 arguments:
41 * 1: Requested behavior (see subsystem_test.h)
42 * 2: Filepath to operate on
43 * 3: String to write to the file (if applicable)
44 */
45 int
46 main(int argc, char **argv)
47 {
48 struct stat stat_buf;
49 int syscall_return = 0;
50 int retval = 1;
51 ino_t inode;
52 ino_t main_inode;
53
54 if (argc != 4) {
55 return retval;
56 }
57
58 char * behavior = argv[1];
59 char * filepath = argv[2];
60 char * write_string = argv[3];
61 size_t write_string_len = strlen(write_string) + 1;
62
63 if (!strcmp(behavior, HELPER_BEHAVIOR_OPEN_OVERFLOW)) {
64 /*
65 * Open with overflow case; expects a filepath longer
66 * than PATH_MAX.
67 */
68 syscall_return = open_with_subsystem(filepath, O_RDWR);
69
70 if (syscall_return < 0) {
71 if (errno == ENAMETOOLONG) {
72 retval = 0;
73 }
74 } else {
75 close(syscall_return);
76 }
77 } else if (!strcmp(behavior, HELPER_BEHAVIOR_STAT_OVERFLOW)) {
78 /*
79 * Stat with overflow case; expects a filepath longer
80 * than PATH_MAX.
81 */
82 syscall_return = stat_with_subsystem(filepath, &stat_buf);
83
84 if ((syscall_return < 0) && (errno == ENAMETOOLONG)) {
85 retval = 0;
86 }
87 }
88 if (!strcmp(behavior, HELPER_BEHAVIOR_OPEN_O_CREAT)) {
89 /*
90 * Open with O_CREAT case; O_CREAT should never work
91 * with open_with_subsystem.
92 */
93 syscall_return = open_with_subsystem(filepath, O_CREAT | O_RDWR);
94
95 if ((syscall_return < 0) && (errno == EINVAL)) {
96 retval = 0;
97 } else {
98 close(syscall_return);
99 }
100 } else if (!strcmp(behavior, HELPER_BEHAVIOR_STAT_NONE)) {
101 /*
102 * Stat when neither file is present.
103 */
104 syscall_return = stat_with_subsystem(filepath, &stat_buf);
105
106 if (syscall_return) {
107 retval = 0;
108 }
109 } else if (!strcmp(behavior, HELPER_BEHAVIOR_STAT_MAIN) ||
110 !strcmp(behavior, HELPER_BEHAVIOR_STAT_NOT_MAIN)) {
111 /*
112 * Stat when at least one file is present.
113 */
114 syscall_return = stat_with_subsystem(filepath, &stat_buf);
115
116 if (!syscall_return) {
117 inode = stat_buf.st_ino;
118
119 syscall_return = stat(filepath, &stat_buf);
120 if (!syscall_return) {
121 main_inode = stat_buf.st_ino;
122
123 /* Compare inodes based on the requested behavior. */
124 if (!strcmp(behavior, HELPER_BEHAVIOR_STAT_MAIN)) {
125 if (inode == main_inode) {
126 /* It was the main file. */
127 retval = 0;
128 }
129 } else if (!strcmp(behavior, HELPER_BEHAVIOR_STAT_NOT_MAIN)) {
130 if (inode != main_inode) {
131 /* It was the subsystem file. */
132 retval = 0;
133 }
134 }
135 } else if (!strcmp(behavior, HELPER_BEHAVIOR_STAT_NOT_MAIN)) {
136 /* If main doesn't exist, we found the subsystem file. */
137 retval = 0;
138 }
139 }
140 } else if (!strcmp(behavior, HELPER_BEHAVIOR_OPEN_AND_WRITE)) {
141 /*
142 * Open and write case; it is on the client to check that this
143 * wrote to the expected file.
144 */
145 syscall_return = open_with_subsystem(filepath, O_RDWR | O_TRUNC);
146
147 if (syscall_return >= 0) {
148 write(syscall_return, write_string, write_string_len);
149 close(syscall_return);
150 retval = 0;
151 }
152 }
153
154 return retval;
155 }