mirror of
https://github.com/darlinghq/darling-iokitd.git
synced 2024-11-26 22:10:38 +00:00
Initial iokitd daemon with stubs
This commit is contained in:
parent
9a89b4e25e
commit
0d64152ab8
@ -2,13 +2,28 @@ project(iokitd)
|
||||
|
||||
add_compile_options(
|
||||
-nostdinc
|
||||
-nostdinc++
|
||||
-Wno-gcc-compat
|
||||
)
|
||||
|
||||
add_definitions(-DIOKIT=1 -DIOKIT_ALL_IPC=1)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/launchd
|
||||
${CMAKE_SOURCE_DIR}/src/lkm/osfmk
|
||||
)
|
||||
include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src/external/libcxx/include ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
mig(iokitmig.defs)
|
||||
|
||||
set(iokitd_sources
|
||||
src/main.cpp
|
||||
src/stubs.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/iokitmigServer.c
|
||||
)
|
||||
|
||||
add_darling_executable(iokitd ${iokitd_sources})
|
||||
target_link_libraries(iokitd cxx)
|
||||
|
||||
install(TARGETS iokitd DESTINATION libexec/darling/usr/sbin)
|
||||
install(FILES org.darlinghq.iokitd.plist DESTINATION libexec/darling/System/Library/LaunchDaemons)
|
||||
|
1
iokitmig.defs
Normal file
1
iokitmig.defs
Normal file
@ -0,0 +1 @@
|
||||
#include <device/device.defs>
|
@ -13,7 +13,9 @@
|
||||
<key>org.darlinghq.iokitd</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>EnableTransactions</key>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -2,8 +2,6 @@
|
||||
#define _IOKITD_H
|
||||
#include <mach/mach.h>
|
||||
|
||||
extern mach_port_t g_machServerPort;
|
||||
|
||||
#define asldebug(...) os_log_debug(OS_LOG_DEFAULT, __VA_ARGS__)
|
||||
|
||||
#endif
|
||||
|
119
src/main.cpp
119
src/main.cpp
@ -1,54 +1,111 @@
|
||||
#include <unistd.h>
|
||||
#include <os/log.h>
|
||||
#include <liblaunch/launch.h>
|
||||
#include <liblaunch/bootstrap.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <cstdlib>
|
||||
#include "iokitd.h"
|
||||
#include "iokitmig.h"
|
||||
|
||||
extern "C" {
|
||||
#include "iokitmigServer.h"
|
||||
}
|
||||
|
||||
static const char* SERVICE_NAME = "org.darlinghq.iokitd";
|
||||
mach_port_t g_machServerPort;
|
||||
|
||||
static void launch_config();
|
||||
static void service_mach_message(mach_port_t serverPort);
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
launch_config();
|
||||
mach_port_t bs, mp;
|
||||
kern_return_t ret;
|
||||
|
||||
task_get_bootstrap_port(mach_task_self(), &bs);
|
||||
ret = bootstrap_check_in(bs, SERVICE_NAME, &mp);
|
||||
|
||||
mach_port_destroy(mach_task_self(), bs);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
{
|
||||
os_log_error(OS_LOG_DEFAULT, "%d bootstrap_check_in() failed with error %d", getpid(), ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
dispatch_source_t portSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, mp, 0, queue);
|
||||
|
||||
if (!portSource)
|
||||
{
|
||||
os_log_error(OS_LOG_DEFAULT, "%d dispatch_source_create() failed", getpid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
dispatch_source_set_event_handler(portSource, ^{
|
||||
service_mach_message(mp);
|
||||
});
|
||||
dispatch_resume(portSource);
|
||||
|
||||
dispatch_main();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void launch_config()
|
||||
typedef union
|
||||
{
|
||||
launch_data_t tmp, pdict;
|
||||
kern_return_t status;
|
||||
launch_data_t launch_dict;
|
||||
mach_msg_header_t head;
|
||||
union __RequestUnion__iokit_subsystem request;
|
||||
} iokit_request_msg;
|
||||
|
||||
tmp = launch_data_new_string(LAUNCH_KEY_CHECKIN);
|
||||
launch_dict = launch_msg(tmp);
|
||||
launch_data_free(tmp);
|
||||
typedef union
|
||||
{
|
||||
mach_msg_header_t head;
|
||||
union __ReplyUnion__iokit_subsystem reply;
|
||||
} iokit_reply_msg;
|
||||
|
||||
if (!launch_dict)
|
||||
static void service_mach_message(mach_port_t serverPort)
|
||||
{
|
||||
__block kern_return_t status;
|
||||
uint32_t rbits, sbits;
|
||||
iokit_request_msg *request;
|
||||
iokit_reply_msg *reply;
|
||||
char rbuf[sizeof(iokit_request_msg) + MAX_TRAILER_SIZE];
|
||||
char sbuf[sizeof(iokit_reply_msg) + MAX_TRAILER_SIZE];
|
||||
|
||||
while (true)
|
||||
{
|
||||
os_log_error(OS_LOG_DEFAULT, "%d launchd checkin failed\n", global.pid);
|
||||
exit(1);
|
||||
}
|
||||
memset(rbuf, 0, sizeof(rbuf));
|
||||
memset(sbuf, 0, sizeof(sbuf));
|
||||
|
||||
tmp = launch_data_dict_lookup(launch_dict, LAUNCH_JOBKEY_MACHSERVICES);
|
||||
if (!tmp)
|
||||
{
|
||||
os_log_error(OS_LOG_DEFAULT, "%d launchd lookup of LAUNCH_JOBKEY_MACHSERVICES failed\n", getpid());
|
||||
exit(1);
|
||||
}
|
||||
request = (iokit_request_msg *)rbuf;
|
||||
reply = (iokit_reply_msg *)sbuf;
|
||||
|
||||
pdict = launch_data_dict_lookup(tmp, SERVICE_NAME);
|
||||
if (!pdict)
|
||||
{
|
||||
os_log_error(OS_LOG_DEFAULT, "%d launchd lookup of SERVICE_NAME failed\n", getpid());
|
||||
exit(1);
|
||||
}
|
||||
request->head.msgh_local_port = serverPort;
|
||||
request->head.msgh_size = sizeof(iokit_request_msg) + MAX_TRAILER_SIZE;
|
||||
|
||||
g_machServerPort = launch_data_get_machport(pdict);
|
||||
rbits = MACH_RCV_MSG | MACH_RCV_TIMEOUT | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) | MACH_RCV_VOUCHER;
|
||||
sbits = MACH_SEND_MSG;
|
||||
|
||||
status = mach_msg(&(request->head), rbits, 0, request->head.msgh_size, serverPort, 0, MACH_PORT_NULL);
|
||||
if (status != KERN_SUCCESS) return;
|
||||
|
||||
voucher_mach_msg_state_t voucher = voucher_mach_msg_adopt(&(request->head));
|
||||
|
||||
status = iokit_server(&(request->head), &(reply->head));
|
||||
|
||||
if (!status && (request->head.msgh_bits & MACH_MSGH_BITS_COMPLEX))
|
||||
{
|
||||
/* destroy the request - but not the reply port */
|
||||
request->head.msgh_remote_port = MACH_PORT_NULL;
|
||||
mach_msg_destroy(&(request->head));
|
||||
}
|
||||
|
||||
if (reply->head.msgh_remote_port)
|
||||
{
|
||||
status = mach_msg(&(reply->head), sbits, reply->head.msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
|
||||
if (status == MACH_SEND_INVALID_DEST || status == MACH_SEND_TIMED_OUT)
|
||||
{
|
||||
/* deallocate reply port rights not consumed by failed mach_msg() send */
|
||||
mach_msg_destroy(&(reply->head));
|
||||
}
|
||||
}
|
||||
|
||||
voucher_mach_msg_revert(voucher);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
1067
src/stubs.c
Normal file
1067
src/stubs.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user