2 * Copyright (c) 2020 Apple Inc. All rights reserved.
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 #include <sys/param.h>
27 #include <sys/types.h>
28 #include <TargetConditionals.h>
30 #if !defined(__i386__)
36 * On macOS we have support for shimming calls to open the SystemVersion plist.
37 * This support is enabled for specific (generally older) binaries from
38 * libSystem_initializer()/__libkernel_init_late() by populating these function pointers
39 * with the corresponding functions built into libsyscall_dynamic (see open-compat-shim.c).
41 extern bool (*system_version_compat_check_path_suffix
)(const char *orig_path
);
42 extern int (*system_version_compat_open_shim
)(int opened_fd
, int openat_fd
, const char *orig_path
, int oflag
, mode_t mode
,
43 int (*close_syscall
)(int), int (*open_syscall
)(const char *, int, mode_t
),
44 int (*openat_syscall
)(int, const char *, int, mode_t
),
45 int (*fcntl_syscall
)(int, int, long));
46 #endif /* TARGET_OS_OSX */
48 #ifdef VARIANT_CANCELABLE
49 int __open(const char *path
, int oflag
, mode_t mode
);
50 int __openat(int fd
, const char *path
, int oflag
, mode_t mode
);
52 #define OPEN_SYSCALL __open
53 #define OPENAT_SYSCALL __openat
56 int __fcntl(int fd
, int cmd
, long arg
);
59 #define FCNTL_SYSCALL __fcntl
60 #define CLOSE_SYSCALL close
61 #endif /* TARGET_OS_OSX */
63 #else /* VARIANT_CANCELABLE */
64 int __open_nocancel(const char *path
, int oflag
, mode_t mode
);
65 int __openat_nocancel(int fd
, const char *path
, int oflag
, mode_t mode
);
67 #define OPEN_SYSCALL __open_nocancel
68 #define OPENAT_SYSCALL __openat_nocancel
71 int __fcntl_nocancel(int fd
, int cmd
, long arg
);
72 int __close_nocancel(int fd
);
74 #define FCNTL_SYSCALL __fcntl_nocancel
75 #define CLOSE_SYSCALL __close_nocancel
76 #endif /* TARGET_OS_OSX */
77 #endif /* VARIANT_CANCELABLE */
79 #ifdef VARIANT_CANCELABLE
81 open(const char *path
, int oflag
, ...)
82 #else /* VARIANT_CANCELABLE */
84 open$
NOCANCEL(const char *path
, int oflag
, ...)
90 if (oflag
& O_CREAT
) {
93 /* compiler warns to pass int (not mode_t) to va_arg */
94 mode
= va_arg(ap
, int);
98 opened_fd
= OPEN_SYSCALL(path
, oflag
, mode
);
101 #else /* TARGET_OS_OSX */
106 /* check to see if system_version_compat is enabled for this process */
107 if (system_version_compat_check_path_suffix
== NULL
) {
111 /* check to see if the suffix of the path we opened matches one we are shimming */
112 if (!system_version_compat_check_path_suffix(path
)) {
116 /* at this point we call into the version compat open shim and return values from there */
117 return system_version_compat_open_shim(opened_fd
, -1, path
, oflag
, mode
, CLOSE_SYSCALL
, OPEN_SYSCALL
,
118 NULL
, FCNTL_SYSCALL
);
119 #endif /* TARGET_OS_OSX */
122 #ifdef VARIANT_CANCELABLE
124 openat(int fd
, const char *path
, int oflag
, ...)
125 #else /* VARIANT_CANCELABLE */
127 openat$
NOCANCEL(int fd
, const char *path
, int oflag
, ...)
133 if (oflag
& O_CREAT
) {
136 // compiler warns to pass int (not mode_t) to va_arg
137 mode
= va_arg(ap
, int);
141 opened_fd
= OPENAT_SYSCALL(fd
, path
, oflag
, mode
);
149 /* check to see if system_version_compat is enabled for this process */
150 if (system_version_compat_check_path_suffix
== NULL
) {
154 /* check to see if the suffix of the path we opened matches one we are shimming */
155 if (!system_version_compat_check_path_suffix(path
)) {
159 /* at this point we call into the version compat open shim and return values from there */
160 return system_version_compat_open_shim(opened_fd
, fd
, path
, oflag
, mode
, CLOSE_SYSCALL
, NULL
,
161 OPENAT_SYSCALL
, FCNTL_SYSCALL
);
162 #endif /* !TARGET_OS_OSX */
164 #endif /* !defined(__i386__) */