D-Bus: dbus-server-launchd.c Source File

D-Bus 1.8.16

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List

dbus-server-launchd.c
1 /* dbus-server-launchd.c Server methods for interacting with launchd.
2 * Copyright (C) 2007, Tanner Lovelace <lovelace@wayfarer.org>
3 * Copyright (C) 2008, Colin Walters <walters@verbum.org>
4 * Copyright (C) 2008-2009, Benjamin Reed <rangerrick@befunk.com>
5 * Copyright (C) 2009, Jonas Bähr <jonas.baehr@web.de>
6 *
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without
10 * restriction, including without limitation the rights to use, copy,
11 * modify, merge, publish, distribute, sublicense, and/or sell copies
12 * of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28 #include <config.h>
29 #include "dbus-server-launchd.h"
30
39 #ifdef DBUS_ENABLE_LAUNCHD
40 #include <launch.h>
41 #include <errno.h>
42
43 #include "dbus-misc.h"
44 #include "dbus-server-socket.h"
45
46 /* put other private launchd functions here */
47
48 #endif /* DBUS_ENABLE_LAUNCHD */
49
64 DBusServer *
65 _dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error)
66 {
67 #ifdef DBUS_ENABLE_LAUNCHD
68 DBusServer *server;
69 DBusString address;
70 int launchd_fd;
71 launch_data_t sockets_dict, checkin_response;
72 launch_data_t checkin_request;
73 launch_data_t listening_fd_array, listening_fd;
74 launch_data_t environment_dict, environment_param;
75 const char *launchd_socket_path, *display;
76
77 launchd_socket_path = _dbus_getenv (launchd_env_var);
78 display = _dbus_getenv ("DISPLAY");
79
80 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
81
82 if (launchd_socket_path == NULL || *launchd_socket_path == '\0')
83 {
84 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
85 "launchd's environment variable %s is empty, but should contain a socket path.\n", launchd_env_var);
86 return NULL;
87 }
88
89 if (!_dbus_string_init (&address))
90 {
91 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
92 return NULL;
93 }
94 if (!_dbus_string_append (&address, "unix:path="))
95 {
96 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
97 goto l_failed_0;
98 }
99 if (!_dbus_string_append (&address, launchd_socket_path))
100 {
101 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
102 goto l_failed_0;
103 }
104
105 if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL)
106 {
107 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
108 "launch_data_new_string(\"%s\") Unable to create string.\n",
109 LAUNCH_KEY_CHECKIN);
110 goto l_failed_0;
111 }
112
113 if ((checkin_response = launch_msg (checkin_request)) == NULL)
114 {
115 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
116 "launch_msg(\"%s\") IPC failure: %s\n",
117 LAUNCH_KEY_CHECKIN, strerror (errno));
118 goto l_failed_0;
119 }
120
121 if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response))
122 {
123 dbus_set_error (error, DBUS_ERROR_FAILED, "Check-in failed: %s\n",
124 strerror (launch_data_get_errno (checkin_response)));
125 goto l_failed_0;
126 }
127
128 sockets_dict =
129 launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS);
130 if (NULL == sockets_dict)
131 {
132 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
133 "No sockets found to answer requests on!\n");
134 goto l_failed_0;
135 }
136
137 listening_fd_array =
138 launch_data_dict_lookup (sockets_dict, "unix_domain_listener");
139 if (NULL == listening_fd_array)
140 {
141 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
142 "No known sockets found to answer requests on!\n");
143 goto l_failed_0;
144 }
145
146 if (launch_data_array_get_count (listening_fd_array) != 1)
147 {
148 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
149 "Expected 1 socket from launchd, got %d.\n",
150 launch_data_array_get_count (listening_fd_array));
151 goto l_failed_0;
152 }
153
154 listening_fd = launch_data_array_get_index (listening_fd_array, 0);
155 launchd_fd = launch_data_get_fd (listening_fd);
156
157 _dbus_fd_set_close_on_exec (launchd_fd);
158
159 if (launchd_fd < 0)
160 {
161 _DBUS_ASSERT_ERROR_IS_SET (error);
162 goto l_failed_0;
163 if (display == NULL || *display == '\0')
164 {
165 environment_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES);
166 if (NULL == environment_dict)
167 {
168 _dbus_warn ("Unable to retrieve user environment from launchd.");
169 }
170 else
171 {
172 environment_param = launch_data_dict_lookup (environment_dict, "DISPLAY");
173 if (NULL == environment_param)
174 {
175 _dbus_warn ("Unable to retrieve DISPLAY from launchd.");
176 }
177 else
178 {
179 display = launch_data_get_string(environment_param);
180 dbus_setenv ("DISPLAY", display);
181 }
182 }
183 }
184
185 }
186
187 server = _dbus_server_new_for_socket (&launchd_fd, 1, &address, 0);
188 if (server == NULL)
189 {
190 dbus_set_error (error, DBUS_ERROR_NO_SERVER,
191 "Unable to listen on launchd fd %d.", launchd_fd);
192 goto l_failed_0;
193 }
194
195 _dbus_string_free (&address);
196
197 return server;
198
199 l_failed_0:
200 _dbus_string_free (&address);
201
202 return NULL;
203 #else /* DBUS_ENABLE_LAUNCHD */
204 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
205 "address type 'launchd' requested, but launchd support not compiled in");
206 return NULL;
207 #endif
208 }
209
_dbus_string_append
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:918
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
_dbus_server_new_for_launchd
DBusServer * _dbus_server_new_for_launchd(const char *launchd_env_var, DBusError *error)
Creates a new server from launchd.
Definition: dbus-server-launchd.c:65
DBusServer
Internals of DBusServer object.
Definition: dbus-server-protected.h:56
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
DBUS_ERROR_IO_ERROR
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
Definition: dbus-protocol.h:360
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
DBUS_ERROR_NO_SERVER
#define DBUS_ERROR_NO_SERVER
Unable to connect to server (probably caused by ECONNREFUSED on a socket).
Definition: dbus-protocol.h:372
_dbus_fd_set_close_on_exec
void _dbus_fd_set_close_on_exec(intptr_t fd)
Sets the file descriptor to be close on exec.
Definition: dbus-sysdeps-unix.c:2936
DBusString
Definition: dbus-string.h:42
dbus_setenv
DBUS_EXPORT dbus_bool_t dbus_setenv(const char *variable, const char *value)
Wrapper for setenv().
Definition: dbus-sysdeps.c:114
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:230
_dbus_server_new_for_socket
DBusServer * _dbus_server_new_for_socket(int *fds, int n_fds, const DBusString *address, DBusNonceFile *noncefile)
Creates a new server listening on the given file descriptor.
Definition: dbus-server-socket.c:280
DBusError
Object representing an exception.
Definition: dbus-errors.h:48
DBUS_ERROR_BAD_ADDRESS
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
Definition: dbus-protocol.h:362
dbus_set_error
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
DBUS_ERROR_FAILED
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
Definition: dbus-protocol.h:350
DBUS_ERROR_NO_MEMORY
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
Definition: dbus-protocol.h:352
DBUS_ERROR_LIMITS_EXCEEDED
#define DBUS_ERROR_LIMITS_EXCEEDED
Some limited resource is exhausted.
Definition: dbus-protocol.h:366