]>
git.saurik.com Git - apple/libc.git/blob - libdarwin/bsd.c
2 * Copyright (c) 2018 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@
25 #pragma mark Utilities
28 * Factored out from _get_parse_boot_arg_value for unit testing purposes
31 _parse_boot_arg_value(char *argsbuff
, const char *which
, char *where
, size_t max
)
36 char *argsstr
= argsbuff
;
37 static const char seps
[] = { ' ', '\t', };
38 while ((token
= strsep(&argsstr
, seps
)) != NULL
) {
39 bool is_boolean
= false;
42 char *equals
= strchr(token
, '=');
43 if (token
[0] == '-') {
45 * Arguments whose names begins with "-" are booleans, so don't get
46 * key=value splitting. Though I'd still discourage you from
47 * naming your option "-edge=case".
57 if (strcmp(which
, token
) == 0) {
59 * Found it! Copy out the value as required.
64 // Caller just wants to know whether the boot-arg exists.
65 } else if (is_boolean
|| value
== NULL
) {
66 strlcpy(where
, "", max
);
68 strlcpy(where
, value
, max
);
79 * This is (very) loosely based on the implementation of
80 * PE_parse_boot_argn() (or at least the parts where I was able to easily
81 * decipher the policy).
84 _get_boot_arg_value(const char *which
, char *where
, size_t max
)
87 __os_free
char *argsbuff
= NULL
;
88 size_t argsbuff_len
= 0;
89 errno_t error
= sysctlbyname_get_data_np("kern.bootargs",
90 (void **)&argsbuff
, &argsbuff_len
);
93 found
= _parse_boot_arg_value(argsbuff
, which
, where
, max
);
101 sysctl_get_data_np(int mib
[4], size_t mib_cnt
, void **buff
, size_t *buff_len
)
108 // We need to get the length of the parameter so we can allocate a buffer
109 // that's large enough.
110 ret
= sysctl(mib
, (unsigned int)mib_cnt
, NULL
, &needed
, NULL
, 0);
116 mybuff
= malloc(needed
);
122 ret
= sysctl(mib
, (unsigned int)mib_cnt
, mybuff
, &needed
, NULL
, 0);
124 // It's conceivable that some other process came along within this
125 // window and modified the variable to be even larger than we'd
126 // previously been told, but if that's the case, just give up.
142 sysctlbyname_get_data_np(const char *mibdesc
, void **buff
, size_t *buff_len
)
147 size_t mib_cnt
= countof(mib
);
149 ret
= sysctlnametomib(mibdesc
, mib
, &mib_cnt
);
155 error
= sysctl_get_data_np(mib
, mib_cnt
, buff
, buff_len
);
162 os_parse_boot_arg_int(const char *which
, int64_t *where
)
169 found
= _get_boot_arg_value(which
, buff
, sizeof(buff
));
170 if (!found
|| !where
) {
174 // A base of zero handles bases 8, 10, and 16.
175 val
= strtoll(buff
, &endptr
, 0);
179 // The boot-arg value was invalid, so say we didn't find it.
188 os_parse_boot_arg_string(const char *which
, char *where
, size_t maxlen
)
190 return _get_boot_arg_value(which
, where
, maxlen
);