]> git.saurik.com Git - apple/libc.git/blame - darwin/subsystem.c
Libc-1439.40.11.tar.gz
[apple/libc.git] / darwin / subsystem.c
CommitLineData
a9aaacca
A
1/*
2* Copyright (c) 2019 Apple Inc. All rights reserved.
3*
4* @APPLE_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. Please obtain a copy of the License at
10* http://www.opensource.apple.com/apsl/ and read it before using this
11* file.
12*
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.
20*
21* @APPLE_LICENSE_HEADER_END@
22*/
23
24#include <fcntl.h>
25#include <stdbool.h>
26#include <string.h>
27#include <subsystem.h>
28#include <sys/errno.h>
29#include <sys/syslimits.h>
30#include <_simple.h>
31
32#define SUBSYSTEM_ROOT_PATH_KEY "subsystem_root_path"
33
34void _subsystem_init(const char *apple[]);
35
36static char * subsystem_root_path = NULL;
37static size_t subsystem_root_path_len = 0;
38
39/*
40 * Takes the apple array, and initializes subsystem
41 * support in Libc.
42 */
43void
44_subsystem_init(const char **apple)
45{
46 char * subsystem_root_path_string = _simple_getenv(apple, SUBSYSTEM_ROOT_PATH_KEY);
47 if (subsystem_root_path_string) {
48 subsystem_root_path = subsystem_root_path_string;
49 subsystem_root_path_len = strnlen(subsystem_root_path, PATH_MAX);
50 }
51}
52
53/*
54 * Takes a buffer, a subsystem path, and a file path, and constructs the
55 * subsystem path for the given file path. Assumes that the subsystem root
56 * path will be "/" terminated.
57 */
58static bool
59construct_subsystem_path(char * buf, size_t buf_size, const char * subsystem_root_path, const char * file_path)
60{
61 size_t return_a = strlcpy(buf, subsystem_root_path, buf_size);
62 size_t return_b = strlcat(buf, file_path, buf_size);
63
64 if ((return_a >= buf_size) || (return_b >= buf_size)) {
65 return false;
66 }
67
68 return true;
69}
70
71int
72open_with_subsystem(const char * path, int oflag)
73{
74 /* Don't support file creation. */
75 if (oflag & O_CREAT){
76 errno = EINVAL;
77 return -1;
78 }
79
80 int result;
81
82 result = open(path, oflag);
83
84 if ((result < 0) && (errno == ENOENT) && (subsystem_root_path)) {
85 /*
86 * If the file doesn't exist relative to root, search
87 * for it relative to the subsystem root.
88 */
89 char subsystem_path[PATH_MAX];
90
91 if (construct_subsystem_path(subsystem_path, sizeof(subsystem_path), subsystem_root_path, path)) {
92 result = open(subsystem_path, oflag);
93 } else {
94 errno = ENAMETOOLONG;
95 }
96 }
97
98 return result;
99}
100
101int
102stat_with_subsystem(const char *restrict path, struct stat *restrict buf)
103{
104 int result;
105
106 result = stat(path, buf);
107
108 if ((result < 0) && (errno == ENOENT) && (subsystem_root_path)) {
109 /*
110 * If the file doesn't exist relative to root, search
111 * for it relative to the subsystem root.
112 */
113 char subsystem_path[PATH_MAX];
114
115 if (construct_subsystem_path(subsystem_path, sizeof(subsystem_path), subsystem_root_path, path)) {
116 result = stat(subsystem_path, buf);
117 } else {
118 errno = ENAMETOOLONG;
119 }
120 }
121
122 return result;
123}
124