2 * Copyright (c) 2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 #include <subsystem.h>
34 #include <sys/errno.h>
35 #include "subsystem_test.h"
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)
46 main(int argc
, char **argv
)
49 int syscall_return
= 0;
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;
63 if (!strcmp(behavior
, HELPER_BEHAVIOR_OPEN_OVERFLOW
)) {
65 * Open with overflow case; expects a filepath longer
68 syscall_return
= open_with_subsystem(filepath
, O_RDWR
);
70 if (syscall_return
< 0) {
71 if (errno
== ENAMETOOLONG
) {
75 close(syscall_return
);
77 } else if (!strcmp(behavior
, HELPER_BEHAVIOR_STAT_OVERFLOW
)) {
79 * Stat with overflow case; expects a filepath longer
82 syscall_return
= stat_with_subsystem(filepath
, &stat_buf
);
84 if ((syscall_return
< 0) && (errno
== ENAMETOOLONG
)) {
88 if (!strcmp(behavior
, HELPER_BEHAVIOR_OPEN_O_CREAT
)) {
90 * Open with O_CREAT case; O_CREAT should never work
91 * with open_with_subsystem.
93 syscall_return
= open_with_subsystem(filepath
, O_CREAT
| O_RDWR
);
95 if ((syscall_return
< 0) && (errno
== EINVAL
)) {
98 close(syscall_return
);
100 } else if (!strcmp(behavior
, HELPER_BEHAVIOR_STAT_NONE
)) {
102 * Stat when neither file is present.
104 syscall_return
= stat_with_subsystem(filepath
, &stat_buf
);
106 if (syscall_return
) {
109 } else if (!strcmp(behavior
, HELPER_BEHAVIOR_STAT_MAIN
) ||
110 !strcmp(behavior
, HELPER_BEHAVIOR_STAT_NOT_MAIN
)) {
112 * Stat when at least one file is present.
114 syscall_return
= stat_with_subsystem(filepath
, &stat_buf
);
116 if (!syscall_return
) {
117 inode
= stat_buf
.st_ino
;
119 syscall_return
= stat(filepath
, &stat_buf
);
120 if (!syscall_return
) {
121 main_inode
= stat_buf
.st_ino
;
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. */
129 } else if (!strcmp(behavior
, HELPER_BEHAVIOR_STAT_NOT_MAIN
)) {
130 if (inode
!= main_inode
) {
131 /* It was the subsystem file. */
135 } else if (!strcmp(behavior
, HELPER_BEHAVIOR_STAT_NOT_MAIN
)) {
136 /* If main doesn't exist, we found the subsystem file. */
140 } else if (!strcmp(behavior
, HELPER_BEHAVIOR_OPEN_AND_WRITE
)) {
142 * Open and write case; it is on the client to check that this
143 * wrote to the expected file.
145 syscall_return
= open_with_subsystem(filepath
, O_RDWR
| O_TRUNC
);
147 if (syscall_return
>= 0) {
148 write(syscall_return
, write_string
, write_string_len
);
149 close(syscall_return
);