Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ DESTDIR ?=
SRC := attach.c blame.c bootstrap.c enable.c env.c error.c examine.c kickstart.c
SRC += kill.c launchctl.c limit.c list.c load.c manager.c plist.c print.c reboot.c
SRC += remove.c runstats.c start_stop.c userswitch.c version.c xpc_helper.c
SRC += dumpjpcategory.c procinfo.c resolveport.c
SRC += dumpjpcategory.c procinfo.c resolveport.c rem.c

ifeq ($(DEBUG),1)
CFLAGS += -O0 -g -fsanitize=address,undefined -fno-omit-frame-pointer
Expand Down
6 changes: 3 additions & 3 deletions bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ bootstrap_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **appl
if (argc > 2) {
paths = launchctl_parse_load_unload(0, argc - 2, argv + 2);
xpc_dictionary_set_value(dict, "paths", paths);
if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)) {
if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, bridgeOS 7.0, *)) {
if (xpc_dictionary_get_uint64(dict, "type") == 1 && xpc_user_sessions_enabled() != 0) {
xpc_array_apply(paths, ^bool(size_t index, xpc_object_t val) {
xpc_object_t plist = launchctl_xpc_from_plist(xpc_string_get_string_ptr(val));
Expand Down Expand Up @@ -128,7 +128,7 @@ bootout_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
if (argc > 2 && name == NULL) {
paths = launchctl_parse_load_unload(0, argc - 2, argv + 2);
xpc_dictionary_set_value(dict, "paths", paths);
if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)) {
if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, bridgeOS 7.0, *)) {
if (xpc_dictionary_get_uint64(dict, "type") == 1 && xpc_user_sessions_enabled() != 0) {
xpc_array_apply(paths, ^bool(size_t index, xpc_object_t val) {
xpc_object_t plist = launchctl_xpc_from_plist(xpc_string_get_string_ptr(val));
Expand All @@ -146,7 +146,7 @@ bootout_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
}
}

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
xpc_dictionary_set_bool(dict, "no-einprogress", true);
}

Expand Down
4 changes: 2 additions & 2 deletions dumpjpcategory.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ dumpjpcategory_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char *
launchctl_setup_xpc_dict_for_service_name("system", dict, NULL);
xpc_dictionary_set_fd(dict, "fd", STDOUT_FILENO);

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
addr = launchctl_create_shmem(dict, sz);
} else {
xpc_dictionary_set_fd(dict, "fd", STDOUT_FILENO);
Expand All @@ -59,7 +59,7 @@ dumpjpcategory_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char *
fprintf(stderr, "Dump jetsamproperties category is not supported on this platform.\n");
}

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
if (retval == 0)
launchctl_print_shmem(reply, addr, sz, stdout);
vm_deallocate(mach_task_self(), addr, sz);
Expand Down
3 changes: 3 additions & 0 deletions launchctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ static const struct {
{ "examine", "Runs the specified analysis tool against launchd in a non-reentrant manner.", "[<tool> [arg0, arg1, ... , @PID, ...]]", examine_cmd },
{ "config", "Modifies persistent configuration parameters for launchd domains.", NULL, config_cmd },
{ "dumpstate", "Dumps launchd state to stdout.", NULL, dumpstate_cmd },
{ "dump-xsc", "Dumps launchd XPC string caches to stdout.", "<name>", dump_xsc_cmd },
{ "dumpjpcategory", "Dumps the jetsam properties category for all services.", NULL, dumpjpcategory_cmd },
{ "reboot", "Initiates a system reboot of the specified type.", "[system|halt|obliterate|userspace] [-s]", reboot_cmd },
{ "enter-rem", "Enter into Restricted Execution Mode (REM).", NULL, enter_rem_cmd },
{ "enter-rem-dev", "Enter into Restricted Execution Mode (REM) in development mode.", NULL, enter_rem_dev_cmd },
{ "userswitch", "Initiates a user switch.", "<old-uid> <new-uid>", userswitch_cmd },
{ "load", "Bootstraps a service or directory of services.", "<service-path, service-path2, ...>", load_cmd },
{ "unload", "Unloads a service or directory of services.", "<service-path, service-path2, ...>", load_cmd },
Expand Down
5 changes: 5 additions & 0 deletions launchctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ cmd_main print_cmd;
cmd_main print_cache_cmd;
cmd_main print_disabled_cmd;
cmd_main dumpstate_cmd;
cmd_main dump_xsc_cmd;

// env.c
cmd_main setenv_cmd;
Expand Down Expand Up @@ -123,6 +124,10 @@ cmd_main hostinfo_cmd;
// resolveport.c
cmd_main resolveport_cmd;

// rem.c
cmd_main enter_rem_cmd;
cmd_main enter_rem_dev_cmd;

void launchctl_xpc_object_print(xpc_object_t, const char *name, int level);
int launchctl_send_xpc_to_launchd(uint64_t routine, xpc_object_t msg, xpc_object_t *reply);
void launchctl_setup_xpc_dict(xpc_object_t dict);
Expand Down
4 changes: 2 additions & 2 deletions limit.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ limit_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
printlimits:
xpc_dictionary_set_bool(dict, "print", true);

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
addr = launchctl_create_shmem(dict, sz);
} else {
xpc_dictionary_set_fd(dict, "file", STDOUT_FILENO);
Expand All @@ -97,7 +97,7 @@ limit_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
fprintf(stderr, "Could not print resource limits: %d: %s\n", err, xpc_strerror(err));
}

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
launchctl_print_shmem(reply, addr, sz, stdout);
vm_deallocate(mach_task_self(), addr, sz);
}
Expand Down
2 changes: 1 addition & 1 deletion load.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ load_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
xpc_dictionary_set_bool(dict, "enable", wflag);
} else {
xpc_dictionary_set_bool(dict, "disable", wflag);
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
xpc_dictionary_set_bool(dict, "no-einprogress", true);
}
}
Expand Down
48 changes: 40 additions & 8 deletions print.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ print_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
if ((ret = launchctl_setup_xpc_dict_for_service_name(argv[1], dict, &name)) != 0)
return ret;

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
addr = launchctl_create_shmem(dict, sz);
} else {
xpc_dictionary_set_fd(dict, "fd", STDOUT_FILENO);
Expand All @@ -64,7 +64,7 @@ print_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
ret = launchctl_send_xpc_to_launchd(XPC_ROUTINE_PRINT, dict, &reply);

if (ret == 0) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
launchctl_print_shmem(reply, addr, sz, stdout);
vm_deallocate(mach_task_self(), addr, sz);
}
Expand Down Expand Up @@ -92,7 +92,7 @@ print_cache_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **ap
xpc_dictionary_set_uint64(dict, "type", 1);
xpc_dictionary_set_uint64(dict, "handle", 0);

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
addr = launchctl_create_shmem(dict, sz);
} else {
xpc_dictionary_set_fd(dict, "fd", STDOUT_FILENO);
Expand All @@ -102,7 +102,7 @@ print_cache_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **ap
ret = launchctl_send_xpc_to_launchd(XPC_ROUTINE_PRINT, dict, &reply);

if (ret == 0) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
launchctl_print_shmem(reply, addr, sz, stdout);
vm_deallocate(mach_task_self(), addr, sz);
}
Expand Down Expand Up @@ -130,7 +130,7 @@ print_disabled_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char *
xpc_dictionary_set_uint64(dict, "type", 1);
xpc_dictionary_set_uint64(dict, "handle", 0);

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
addr = launchctl_create_shmem(dict, sz);
} else {
xpc_dictionary_set_fd(dict, "fd", STDOUT_FILENO);
Expand All @@ -140,7 +140,7 @@ print_disabled_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char *
ret = launchctl_send_xpc_to_launchd(XPC_ROUTINE_PRINT, dict, &reply);

if (ret == 0) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
launchctl_print_shmem(reply, addr, sz, stdout);
vm_deallocate(mach_task_self(), addr, sz);
}
Expand Down Expand Up @@ -168,7 +168,7 @@ dumpstate_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **appl
xpc_dictionary_set_uint64(dict, "type", 1);
xpc_dictionary_set_uint64(dict, "handle", 0);

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
addr = launchctl_create_shmem(dict, sz);
} else {
xpc_dictionary_set_fd(dict, "fd", STDOUT_FILENO);
Expand All @@ -177,7 +177,7 @@ dumpstate_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **appl
ret = launchctl_send_xpc_to_launchd(XPC_ROUTINE_DUMPSTATE, dict, &reply);

if (ret == 0) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
launchctl_print_shmem(reply, addr, sz, stdout);
vm_deallocate(mach_task_self(), addr, sz);
}
Expand All @@ -193,3 +193,35 @@ dumpstate_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **appl

return ret;
}

int
dump_xsc_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
{
int ret = ENOTSUP;
xpc_object_t reply;
vm_address_t addr;
vm_size_t sz = 0xa00000;

if (__builtin_available(macOS 16.0, iOS 19.0, tvOS 19.0, watchOS 12.0, bridgeOS 10.0, *)) {
xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
*msg = dict;

if ((ret = launchctl_setup_xpc_dict_for_service_name("system", dict, NULL)) != 0)
return ret;

if (argc > 1)
xpc_dictionary_set_string(dict, "name", argv[1]);

addr = launchctl_create_shmem(dict, sz);
ret = launchctl_send_xpc_to_launchd(XPC_ROUTINE_DUMP_XSC, dict, &reply);

if (ret)
fprintf(stderr, "State-dump failed with error %d\n", ret);
else
launchctl_print_shmem(reply, addr, sz, stdout);

vm_deallocate(mach_task_self(), addr, sz);
}

return ret;
}
5 changes: 2 additions & 3 deletions procinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,6 @@ procinfo_proc_info : {
assert(p < &procargs[argmax]);

// reached argv[0]
char *proc_argv = (char *)p;
printf("argument vector = {\n");
for (int32_t i = 0; i < proc_argc && p < &procargs[argmax]; i++) {
printf("\t[%d] = %s\n", i, p);
Expand Down Expand Up @@ -613,14 +612,14 @@ procinfo_launchd_info : {
dict = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_int64(dict, "pid", pid);

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
addr = launchctl_create_shmem(dict, sz);
} else {
xpc_dictionary_set_fd(dict, "fd", STDOUT_FILENO);
}
retval = launchctl_send_xpc_to_launchd(XPC_ROUTINE_PRINT_SERVICE, dict, &reply);
if (retval == 0) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
launchctl_print_shmem(reply, addr, sz, stdout);
vm_deallocate(mach_task_self(), addr, sz);
}
Expand Down
63 changes: 63 additions & 0 deletions rem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 Procursus Team <team@procurs.us>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <xpc/xpc.h>

#include "launchctl.h"
#include "xpc_private.h"

int
enter_rem_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
{
int ret = ENOTSUP;

if (__builtin_available(macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, bridgeOS 9.0, *))
ret = launch_userspace_reboot_with_purpose(4);

if (ret != 0)
fprintf(stderr, "Failed to enter REM: %d: %s\n", ret, xpc_strerror(ret));

return ret;
}

int
enter_rem_dev_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
{
int ret = ENOTSUP;

if (__builtin_available(macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, bridgeOS 9.0, *))
ret = launch_userspace_reboot_with_purpose(5);

if (ret != 0)
fprintf(stderr, "Failed to enter REM (development): %d: %s\n", ret, xpc_strerror(ret));

return ret;
}
7 changes: 6 additions & 1 deletion userswitch.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,18 @@ userswitch_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **app

int ret = ENOTSUP;

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 16.0, iOS 19.0, tvOS 19.0, watchOS 12.0, bridgeOS 10.0, *)) {
/* The code is like this because __builtin_available cannot be combined with other operators */
} else if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
long olduid = 0, newuid = 0;

olduid = strtol(argv[1], NULL, 0);
newuid = strtol(argv[1], NULL, 0);

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ret = launch_active_user_switch(olduid, newuid);
#pragma clang diagnostic pop
}

if (ret != 0) {
Expand Down
4 changes: 2 additions & 2 deletions version.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ version_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
vm_address_t addr = 0;
vm_size_t sz = 0x100000;

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
addr = launchctl_create_shmem(dict, sz);
} else {
xpc_dictionary_set_fd(dict, "fd", STDOUT_FILENO);
Expand All @@ -62,7 +62,7 @@ version_cmd(xpc_object_t *msg, int argc, char **argv, char **envp, char **apple)
fprintf(stderr, "Could not print variant: %d: %s\n", ret, xpc_strerror(ret));
}

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
launchctl_print_shmem(reply, addr, sz, stdout);

if (addr != 0)
Expand Down
8 changes: 4 additions & 4 deletions xpc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ launchctl_send_xpc_to_launchd(uint64_t routine, xpc_object_t msg, xpc_object_t *
xpc_dictionary_set_uint64(msg, "routine", routine);
int ret = 0;

if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
ret = _xpc_pipe_interface_routine(bootstrap_pipe, 0, msg, reply, 0);
} else {
ret = xpc_pipe_routine(bootstrap_pipe, msg, reply);
Expand Down Expand Up @@ -122,7 +122,7 @@ launchctl_xpc_object_print(xpc_object_t in, const char *name, int level)
void
launchctl_setup_xpc_dict(xpc_object_t dict)
{
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) {
if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, bridgeOS 6.0, *)) {
xpc_dictionary_set_uint64(dict, "type", 7);
} else {
xpc_dictionary_set_uint64(dict, "type", 1);
Expand Down Expand Up @@ -170,7 +170,7 @@ launchctl_setup_xpc_dict_for_service_name(char *servicetarget, xpc_object_t dict
if (name != NULL) {
*name = split[1];
}
if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)) {
if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, bridgeOS 7.0, *)) {
if (xpc_user_sessions_enabled() &&
launchctl_test_xpc_send(1, handle, split[1]) == false) {
uint64_t fguid = xpc_user_sessions_get_foreground_uid(0);
Expand All @@ -189,7 +189,7 @@ launchctl_setup_xpc_dict_for_service_name(char *servicetarget, xpc_object_t dict
} else if (strcmp(split[0], "user") == 0) {
xpc_dictionary_set_uint64(dict, "type", 2);
if (split[1] != NULL && strcmp(split[1], "foreground") == 0) {
if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)) {
if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, bridgeOS 7.0, *)) {
if (xpc_user_sessions_enabled() == 0) {
fprintf(stderr,
"user/foreground/ specifier is not supported on this platform\n");
Expand Down
Loading