#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ZN_ASSERT(expr) \ do { \ zn_status_t status = expr; \ if (status != ZN_OK) { \ zn_printf("initd: " #expr " failed: %s\n", zn_status_to_string(status)); \ return EXIT_FAILURE; \ } \ } while (0) [[__format(printf, 1, 2)]] static void zn_printf(const char* msg, ...) { char buf[1024]; va_list args; va_start(args, msg); int32_t len = vsnprintf(buf, sizeof(buf), msg, args); va_end(args); zn_log(buf, len); } int main(int argc, char* argv[], char* envp[]) { zn_printf("initd: starting...\n"); zn_handle_t channel = getauxval(AT_INIT_HANDLE); while (true) { static thread_local zn_handle_t handles[32]; static thread_local char buf[1024]; ZN_ASSERT(zn_channel_read(channel, handles, buf, ARRAY_SIZE(handles), ARRAY_SIZE(buf), nullptr, nullptr)); enum ipc_msg_id* msg = (enum ipc_msg_id*)buf; switch (*msg) { case IPC_MSG_FOO: { struct ipc_init_register_rq* foo = (struct ipc_init_register_rq*)msg; char buf[32] = {0}; IPC_GET_STRING(foo->data, &foo->name, buf); zn_printf("initd: ipc_init_register_rq, peer = \"%s\"\n", buf); } break; case IPC_MSG_BAR: { struct ipc_kernel_msg* foo = (struct ipc_kernel_msg*)msg; char buf[32] = {0}; IPC_GET_STRING(foo->data, &foo->name, buf); zn_printf("initd: ipc_kernel_msg, msg = \"%s\"\n", buf); } break; case IPC_MSG_BAZ: break; } } }