|
D-Bus
1.8.20
|
00001 /* dbus-server-launchd.c Server methods for interacting with launchd. 00002 * Copyright (C) 2007, Tanner Lovelace <lovelace@wayfarer.org> 00003 * Copyright (C) 2008, Colin Walters <walters@verbum.org> 00004 * Copyright (C) 2008-2009, Benjamin Reed <rangerrick@befunk.com> 00005 * Copyright (C) 2009, Jonas Bähr <jonas.baehr@web.de> 00006 * 00007 * Permission is hereby granted, free of charge, to any person 00008 * obtaining a copy of this software and associated documentation 00009 * files (the "Software"), to deal in the Software without 00010 * restriction, including without limitation the rights to use, copy, 00011 * modify, merge, publish, distribute, sublicense, and/or sell copies 00012 * of the Software, and to permit persons to whom the Software is 00013 * furnished to do so, subject to the following conditions: 00014 * 00015 * The above copyright notice and this permission notice shall be 00016 * included in all copies or substantial portions of the Software. 00017 * 00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00019 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00020 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00021 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 00022 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 00023 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00025 * DEALINGS IN THE SOFTWARE. 00026 */ 00027 00028 #include <config.h> 00029 #include "dbus-server-launchd.h" 00030 00039 #ifdef DBUS_ENABLE_LAUNCHD 00040 #include <launch.h> 00041 #include <errno.h> 00042 00043 #include "dbus-misc.h" 00044 #include "dbus-server-socket.h" 00045 00046 /* put other private launchd functions here */ 00047 00048 #endif /* DBUS_ENABLE_LAUNCHD */ 00049 00064 DBusServer * 00065 _dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error) 00066 { 00067 #ifdef DBUS_ENABLE_LAUNCHD 00068 DBusServer *server; 00069 DBusString address; 00070 int launchd_fd; 00071 launch_data_t sockets_dict, checkin_response; 00072 launch_data_t checkin_request; 00073 launch_data_t listening_fd_array, listening_fd; 00074 launch_data_t environment_dict, environment_param; 00075 const char *launchd_socket_path, *display; 00076 00077 launchd_socket_path = _dbus_getenv (launchd_env_var); 00078 display = _dbus_getenv ("DISPLAY"); 00079 00080 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00081 00082 if (launchd_socket_path == NULL || *launchd_socket_path == '\0') 00083 { 00084 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00085 "launchd's environment variable %s is empty, but should contain a socket path.\n", launchd_env_var); 00086 return NULL; 00087 } 00088 00089 if (!_dbus_string_init (&address)) 00090 { 00091 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00092 return NULL; 00093 } 00094 if (!_dbus_string_append (&address, "unix:path=")) 00095 { 00096 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00097 goto l_failed_0; 00098 } 00099 if (!_dbus_string_append (&address, launchd_socket_path)) 00100 { 00101 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00102 goto l_failed_0; 00103 } 00104 00105 if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL) 00106 { 00107 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, 00108 "launch_data_new_string(\"%s\") Unable to create string.\n", 00109 LAUNCH_KEY_CHECKIN); 00110 goto l_failed_0; 00111 } 00112 00113 if ((checkin_response = launch_msg (checkin_request)) == NULL) 00114 { 00115 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 00116 "launch_msg(\"%s\") IPC failure: %s\n", 00117 LAUNCH_KEY_CHECKIN, strerror (errno)); 00118 goto l_failed_0; 00119 } 00120 00121 if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response)) 00122 { 00123 dbus_set_error (error, DBUS_ERROR_FAILED, "Check-in failed: %s\n", 00124 strerror (launch_data_get_errno (checkin_response))); 00125 goto l_failed_0; 00126 } 00127 00128 sockets_dict = 00129 launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS); 00130 if (NULL == sockets_dict) 00131 { 00132 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 00133 "No sockets found to answer requests on!\n"); 00134 goto l_failed_0; 00135 } 00136 00137 listening_fd_array = 00138 launch_data_dict_lookup (sockets_dict, "unix_domain_listener"); 00139 if (NULL == listening_fd_array) 00140 { 00141 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 00142 "No known sockets found to answer requests on!\n"); 00143 goto l_failed_0; 00144 } 00145 00146 if (launch_data_array_get_count (listening_fd_array) != 1) 00147 { 00148 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, 00149 "Expected 1 socket from launchd, got %d.\n", 00150 launch_data_array_get_count (listening_fd_array)); 00151 goto l_failed_0; 00152 } 00153 00154 listening_fd = launch_data_array_get_index (listening_fd_array, 0); 00155 launchd_fd = launch_data_get_fd (listening_fd); 00156 00157 _dbus_fd_set_close_on_exec (launchd_fd); 00158 00159 if (launchd_fd < 0) 00160 { 00161 _DBUS_ASSERT_ERROR_IS_SET (error); 00162 goto l_failed_0; 00163 if (display == NULL || *display == '\0') 00164 { 00165 environment_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES); 00166 if (NULL == environment_dict) 00167 { 00168 _dbus_warn ("Unable to retrieve user environment from launchd."); 00169 } 00170 else 00171 { 00172 environment_param = launch_data_dict_lookup (environment_dict, "DISPLAY"); 00173 if (NULL == environment_param) 00174 { 00175 _dbus_warn ("Unable to retrieve DISPLAY from launchd."); 00176 } 00177 else 00178 { 00179 display = launch_data_get_string(environment_param); 00180 dbus_setenv ("DISPLAY", display); 00181 } 00182 } 00183 } 00184 00185 } 00186 00187 server = _dbus_server_new_for_socket (&launchd_fd, 1, &address, 0); 00188 if (server == NULL) 00189 { 00190 dbus_set_error (error, DBUS_ERROR_NO_SERVER, 00191 "Unable to listen on launchd fd %d.", launchd_fd); 00192 goto l_failed_0; 00193 } 00194 00195 _dbus_string_free (&address); 00196 00197 return server; 00198 00199 l_failed_0: 00200 _dbus_string_free (&address); 00201 00202 return NULL; 00203 #else /* DBUS_ENABLE_LAUNCHD */ 00204 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00205 "address type 'launchd' requested, but launchd support not compiled in"); 00206 return NULL; 00207 #endif 00208 } 00209
1.7.6.1