static void fill_job_info(launch_data_t data, const char *key, LaunchJobStatus * info) { switch (launch_data_get_type(data)) { case LAUNCH_DATA_STRING: if (strcmp(key, LAUNCH_JOBKEY_LABEL) == 0) { info->m_label = std::string(launch_data_get_string(data)); } else if (strcmp(key, LAUNCH_JOBKEY_PROGRAM) == 0) { info->m_program = std::string(launch_data_get_string(data)); } return; case LAUNCH_DATA_INTEGER: if (strcmp(key, LAUNCH_JOBKEY_PID) == 0) { info->m_pid = (pid_t)launch_data_get_integer(data); } return; case LAUNCH_DATA_DICTIONARY: launch_data_dict_iterate(data, (dict_iterate_callback)fill_job_info, info); return; default: return; /* do nothing */ } }
static void GTMConvertCFDictEntryToLaunchDataDictEntry(const void *key, const void *value, void *context) { GTMCFToLDictContext *local_context = (GTMCFToLDictContext *)context; if (*(local_context->error)) return; launch_data_t launch_value = GTMLaunchDataCreateFromCFType(value, local_context->error); if (launch_value) { launch_data_t launch_key = GTMLaunchDataCreateFromCFType(key, local_context->error); if (launch_key) { bool goodInsert = launch_data_dict_insert(local_context->dict, launch_value, launch_data_get_string(launch_key)); if (!goodInsert) { *(local_context->error) = GTMCFLaunchCreateUnlocalizedError(EINVAL, CFSTR("launch_data_dict_insert " "failed key: %@ value: %@"), key, value); launch_data_free(launch_value); } launch_data_free(launch_key); } } }
static PyObject* launch2python(launch_data_t data) { launch_data_type_t tp; tp = launch_data_get_type(data); switch (tp) { case LAUNCH_DATA_DICTIONARY: return launchdict2python(data); case LAUNCH_DATA_ARRAY: return launcharray2python(data); case LAUNCH_DATA_FD: return PyObject_CallFunction(file_descriptor_type, "i", launch_data_get_fd(data)); return NULL; case LAUNCH_DATA_INTEGER: return PyLong_FromLongLong(launch_data_get_integer(data)); case LAUNCH_DATA_REAL: return PyFloat_FromDouble(launch_data_get_real(data)); case LAUNCH_DATA_BOOL: return PyBool_FromLong(launch_data_get_bool(data)); case LAUNCH_DATA_STRING: return PyString_FromString(launch_data_get_string(data)); case LAUNCH_DATA_OPAQUE: return PyBuffer_FromMemory( launch_data_get_opaque(data), launch_data_get_opaque_size(data)); case LAUNCH_DATA_ERRNO: return PyObject_CallFunction(errno_type, "i", launch_data_get_errno(data)); default: PyErr_Format(PyExc_ValueError, "Unhandled launch data type (tag: %d)", (int)tp); return NULL; } }
mig_deallocate(outdata, outdata_cnt); } return kr; } vproc_err_t _vproc_post_fork_ping(void) { return vproc_mig_post_fork_ping(bootstrap_port, mach_task_self()) == 0 ? NULL : _vproc_post_fork_ping; } static void setup_env_hack(const launch_data_t obj, const char *key, void *context __attribute__((unused))) { setenv(key, launch_data_get_string(obj), 1); } vproc_err_t _vprocmgr_init(const char *session_type) { if (vproc_mig_move_subset(bootstrap_port, MACH_PORT_NULL, (char *)session_type) == 0) { return NULL; } return (vproc_err_t)_vprocmgr_init; } vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type) {
void my_callback(const launch_data_t obj, const char *key, void *context) { fprintf(context, "%s == %s\n", key, launch_data_get_string(obj)); }
DBusServer * _dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error) { #ifdef DBUS_ENABLE_LAUNCHD DBusServer *server; DBusString address; int launchd_fd; launch_data_t sockets_dict, checkin_response; launch_data_t checkin_request; launch_data_t listening_fd_array, listening_fd; launch_data_t environment_dict, environment_param; const char *launchd_socket_path, *display; launchd_socket_path = _dbus_getenv (launchd_env_var); display = _dbus_getenv ("DISPLAY"); _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (launchd_socket_path == NULL || *launchd_socket_path == '\0') { dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "launchd's environment variable %s is empty, but should contain a socket path.\n", launchd_env_var); return NULL; } if (!_dbus_string_init (&address)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } if (!_dbus_string_append (&address, "unix:path=")) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto l_failed_0; } if (!_dbus_string_append (&address, launchd_socket_path)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto l_failed_0; } if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, "launch_data_new_string(\"%s\") Unable to create string.\n", LAUNCH_KEY_CHECKIN); goto l_failed_0; } if ((checkin_response = launch_msg (checkin_request)) == NULL) { dbus_set_error (error, DBUS_ERROR_IO_ERROR, "launch_msg(\"%s\") IPC failure: %s\n", LAUNCH_KEY_CHECKIN, strerror (errno)); goto l_failed_0; } if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response)) { dbus_set_error (error, DBUS_ERROR_FAILED, "Check-in failed: %s\n", strerror (launch_data_get_errno (checkin_response))); goto l_failed_0; } sockets_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS); if (NULL == sockets_dict) { dbus_set_error (error, DBUS_ERROR_IO_ERROR, "No sockets found to answer requests on!\n"); goto l_failed_0; } listening_fd_array = launch_data_dict_lookup (sockets_dict, "unix_domain_listener"); if (NULL == listening_fd_array) { dbus_set_error (error, DBUS_ERROR_IO_ERROR, "No known sockets found to answer requests on!\n"); goto l_failed_0; } if (launch_data_array_get_count (listening_fd_array) != 1) { dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, "Expected 1 socket from launchd, got %d.\n", launch_data_array_get_count (listening_fd_array)); goto l_failed_0; } listening_fd = launch_data_array_get_index (listening_fd_array, 0); launchd_fd = launch_data_get_fd (listening_fd); _dbus_fd_set_close_on_exec (launchd_fd); if (launchd_fd < 0) { _DBUS_ASSERT_ERROR_IS_SET (error); goto l_failed_0; if (display == NULL || *display == '\0') { environment_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES); if (NULL == environment_dict) { _dbus_warn ("Unable to retrieve user environment from launchd."); } else { environment_param = launch_data_dict_lookup (environment_dict, "DISPLAY"); if (NULL == environment_param) { _dbus_warn ("Unable to retrieve DISPLAY from launchd."); } else { display = launch_data_get_string(environment_param); dbus_setenv ("DISPLAY", display); } } } } server = _dbus_server_new_for_socket (&launchd_fd, 1, &address, 0); if (server == NULL) { dbus_set_error (error, DBUS_ERROR_NO_SERVER, "Unable to listen on launchd fd %d.", launchd_fd); goto l_failed_0; } _dbus_string_free (&address); return server; l_failed_0: _dbus_string_free (&address); return NULL; #else /* DBUS_ENABLE_LAUNCHD */ dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "address type 'launchd' requested, but launchd support not compiled in"); return NULL; #endif }
CFTypeRef GTMCFTypeCreateFromLaunchData(launch_data_t ldata, bool convert_non_standard_objects, CFErrorRef *error) { CFTypeRef cf_type_ref = NULL; CFErrorRef local_error = NULL; if (ldata == NULL) { local_error = GTMCFLaunchCreateUnlocalizedError(EINVAL, CFSTR("NULL ldata")); goto exit; } launch_data_type_t ldata_type = launch_data_get_type(ldata); switch (ldata_type) { case LAUNCH_DATA_STRING: cf_type_ref = CFStringCreateWithCString(kCFAllocatorDefault, launch_data_get_string(ldata), kCFStringEncodingUTF8); break; case LAUNCH_DATA_INTEGER: { long long value = launch_data_get_integer(ldata); cf_type_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &value); break; } case LAUNCH_DATA_REAL: { double value = launch_data_get_real(ldata); cf_type_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value); break; } case LAUNCH_DATA_BOOL: { bool value = launch_data_get_bool(ldata); cf_type_ref = value ? kCFBooleanTrue : kCFBooleanFalse; CFRetain(cf_type_ref); break; } case LAUNCH_DATA_OPAQUE: { size_t size = launch_data_get_opaque_size(ldata); void *data = launch_data_get_opaque(ldata); cf_type_ref = CFDataCreate(kCFAllocatorDefault, data, size); break; } case LAUNCH_DATA_ARRAY: { size_t count = launch_data_array_get_count(ldata); cf_type_ref = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks); if (cf_type_ref) { for (size_t i = 0; !local_error && i < count; i++) { launch_data_t l_sub_data = launch_data_array_get_index(ldata, i); CFTypeRef cf_sub_type = GTMCFTypeCreateFromLaunchData(l_sub_data, convert_non_standard_objects, &local_error); if (cf_sub_type) { CFArrayAppendValue((CFMutableArrayRef)cf_type_ref, cf_sub_type); CFRelease(cf_sub_type); } } } break; } case LAUNCH_DATA_DICTIONARY: cf_type_ref = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (cf_type_ref) { GTMLToCFDictContext context = { (CFMutableDictionaryRef)cf_type_ref, convert_non_standard_objects, &local_error }; launch_data_dict_iterate(ldata, GTMConvertLaunchDataDictEntryToCFDictEntry, &context); } break; case LAUNCH_DATA_FD: if (convert_non_standard_objects) { int file_descriptor = launch_data_get_fd(ldata); cf_type_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &file_descriptor); } break; case LAUNCH_DATA_MACHPORT: if (convert_non_standard_objects) { mach_port_t port = launch_data_get_machport(ldata); cf_type_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &port); } break; default: local_error = GTMCFLaunchCreateUnlocalizedError(EINVAL, CFSTR("Unknown launchd type %d"), ldata_type); break; } exit: if (error) { *error = local_error; } else if (local_error) { #ifdef DEBUG CFShow(local_error); #endif // DEBUG CFRelease(local_error); } return cf_type_ref; }