Merge lp:~jamesodhunt/upstart/bugs-1235649+1203595 into lp:upstart
- bugs-1235649+1203595
- Merge into trunk
Status: | Rejected | ||||||||
---|---|---|---|---|---|---|---|---|---|
Rejected by: | Steve Langasek | ||||||||
Proposed branch: | lp:~jamesodhunt/upstart/bugs-1235649+1203595 | ||||||||
Merge into: | lp:upstart | ||||||||
Diff against target: |
1044 lines (+730/-34) 13 files modified
ChangeLog (+48/-1) init/control.c (+45/-12) init/control.h (+5/-1) init/environ.c (+4/-0) init/job_class.c (+56/-6) init/job_process.c (+1/-1) init/main.c (+12/-5) init/tests/test_control.c (+2/-2) init/tests/test_environ.c (+457/-0) test/test_util_common.c (+11/-1) util/initctl.c (+2/-3) util/man/initctl.8 (+2/-2) util/tests/test_initctl.c (+85/-0) |
||||||||
To merge this branch: | bzr merge lp:~jamesodhunt/upstart/bugs-1235649+1203595 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Steve Langasek | Disapprove | ||
Review via email: mp+191852@code.launchpad.net |
Commit message
Description of the change
Make a Session Init connect to the D-Bus session bus as well as the private socket.
James Hunt (jamesodhunt) wrote : | # |
James Hunt (jamesodhunt) wrote : | # |
Discussion with slangasek has resulted in a better plan to solve this issue.
Steve Langasek (vorlon) wrote : | # |
I was assuming you would replace this with a fresh branch, based on our discussion, since it will have almost nothing in common with the current code. :) So rejecting this mp.
As we discussed, a better approach is to make this explicit rather than implicit by having a new initctl interface that takes the dbus address as an argument. When a session init receives this call, it should connect to the dbus session bus at the specified address if it isn't already connected to the session bus. (Requests to connect to a session bus if there's already a session bus should be ignored.) This way, we don't have to fiddle with the environment at all.
Unmerged revisions
- 1545. By James Hunt
-
* init/control.c: control_bus_open(): Don't call nih_dbus_bus() if
DBUS_SESSION_ BUS_ADDRESS is not set to avoid D-bus auto-launching a
dbus-daemon.
* init/environ.c: Comments.
* init/job_class.c:
- job_class_environment_ init(): Superior check on whether job_environ
is not empty.
- job_class_environment_ reset() : Only reset job_environ if not NULL
already.
- job_class_environment_ set(): Set variable in Upstarts environment
too (required to allow Upstart to be aware of the D-Bus session bus
address when the dbus-daemon is available).
- job_class_environment_ unset() : Unset variable from Upstarts
environment, but only if it is not a default variable.
* init/job_process.c: Formatting.
* init/test_control. c: Updated strings used by tests which check error
messages to include 'D-Bus'.
* init/test_environ. c:
- test_add(): New test:
- "using bare word with no corresponding variable set in environment"
- test_remove(): New function ("the missing test") containing 8 new tests:
- "remove name=value pair with empty table"
- "remove bare name with empty table"
- "remove name=value from table of size 1"
- "remove bare name from table of size 1"
- "remove first name=value entry from table of size 2"
- "remove first bare name entry from table of size 2"
- "remove last name=value entry from table of size 2"
- "remove last bare name entry from table of size 2"
* test/test_util_common. c:
- Formatting.
- get_initctl(): Added environment checks.
* util/initctl.c:
- Formatting.
- Removed testing comment from option text for '--session'.
* util/man/initctl.8: Removed testing comment for '--session'.
* util/tests/test_initctl. c:
- test_session_init(): New test that checks the Session Init now
connects to the D-Bus session bus. - 1544. By James Hunt
-
* Connect to the D-Bus session bus as well as using a private socket
when running as a Session Init (LP: #1203595, #1235649).
Preview Diff
1 | === modified file 'ChangeLog' | |||
2 | --- ChangeLog 2013-10-04 21:34:25 +0000 | |||
3 | +++ ChangeLog 2013-10-22 10:15:27 +0000 | |||
4 | @@ -1,4 +1,51 @@ | |||
6 | 1 | 2013-01-04 Steve Langasek <steve.langasek@ubuntu.com | 1 | 2013-10-22 James Hunt <james.hunt@ubuntu.com> |
7 | 2 | |||
8 | 3 | * init/control.c: control_bus_open(): Don't call nih_dbus_bus() if | ||
9 | 4 | DBUS_SESSION_BUS_ADDRESS is not set to avoid D-bus auto-launching a | ||
10 | 5 | dbus-daemon. | ||
11 | 6 | * init/environ.c: Comments. | ||
12 | 7 | * init/job_class.c: | ||
13 | 8 | - job_class_environment_init(): Superior check on whether job_environ | ||
14 | 9 | is not empty. | ||
15 | 10 | - job_class_environment_reset(): Only reset job_environ if not NULL | ||
16 | 11 | already. | ||
17 | 12 | - job_class_environment_set(): Set variable in Upstarts environment | ||
18 | 13 | too (required to allow Upstart to be aware of the D-Bus session bus | ||
19 | 14 | address when the dbus-daemon is available). | ||
20 | 15 | - job_class_environment_unset(): Unset variable from Upstarts | ||
21 | 16 | environment, but only if it is not a default variable. | ||
22 | 17 | * init/job_process.c: Formatting. | ||
23 | 18 | * init/test_control.c: Updated strings used by tests which check error | ||
24 | 19 | messages to include 'D-Bus'. | ||
25 | 20 | * init/test_environ.c: | ||
26 | 21 | - test_add(): New test: | ||
27 | 22 | - "using bare word with no corresponding variable set in environment" | ||
28 | 23 | - test_remove(): New function ("the missing test") containing 8 new tests: | ||
29 | 24 | - "remove name=value pair with empty table" | ||
30 | 25 | - "remove bare name with empty table" | ||
31 | 26 | - "remove name=value from table of size 1" | ||
32 | 27 | - "remove bare name from table of size 1" | ||
33 | 28 | - "remove first name=value entry from table of size 2" | ||
34 | 29 | - "remove first bare name entry from table of size 2" | ||
35 | 30 | - "remove last name=value entry from table of size 2" | ||
36 | 31 | - "remove last bare name entry from table of size 2" | ||
37 | 32 | * test/test_util_common.c: | ||
38 | 33 | - Formatting. | ||
39 | 34 | - get_initctl(): Added environment checks. | ||
40 | 35 | * util/initctl.c: | ||
41 | 36 | - Formatting. | ||
42 | 37 | - Removed testing comment from option text for '--session'. | ||
43 | 38 | * util/man/initctl.8: Removed testing comment for '--session'. | ||
44 | 39 | * util/tests/test_initctl.c: | ||
45 | 40 | - test_session_init(): New test that checks the Session Init now | ||
46 | 41 | connects to the D-Bus session bus. | ||
47 | 42 | |||
48 | 43 | 2013-10-18 James Hunt <james.hunt@ubuntu.com> | ||
49 | 44 | |||
50 | 45 | * Connect to the D-Bus session bus as well as using a private socket | ||
51 | 46 | when running as a Session Init (LP: #1203595, #1235649). | ||
52 | 47 | |||
53 | 48 | 2013-10-04 Steve Langasek <steve.langasek@ubuntu.com | ||
54 | 2 | 49 | ||
55 | 3 | * extra/upstart-local-bridge.c: use SOCKET_PATH in our event | 50 | * extra/upstart-local-bridge.c: use SOCKET_PATH in our event |
56 | 4 | environment, instead of clobbering PATH. (LP: #1235480) | 51 | environment, instead of clobbering PATH. (LP: #1235480) |
57 | 5 | 52 | ||
58 | === modified file 'init/control.c' | |||
59 | --- init/control.c 2013-04-22 10:30:09 +0000 | |||
60 | +++ init/control.c 2013-10-22 10:15:27 +0000 | |||
61 | @@ -81,11 +81,19 @@ | |||
62 | 81 | * | 81 | * |
63 | 82 | * If TRUE, connect to the D-Bus session bus rather than the system bus. | 82 | * If TRUE, connect to the D-Bus session bus rather than the system bus. |
64 | 83 | * | 83 | * |
66 | 84 | * Used for testing. | 84 | * Used for testing to simulate (as far as possible) a system-like init |
67 | 85 | * when running as a non-priv user. | ||
68 | 85 | **/ | 86 | **/ |
69 | 86 | int use_session_bus = FALSE; | 87 | int use_session_bus = FALSE; |
70 | 87 | 88 | ||
71 | 88 | /** | 89 | /** |
72 | 90 | * dbus_bus_type: | ||
73 | 91 | * | ||
74 | 92 | * Type of D-Bus bus to connect to. | ||
75 | 93 | **/ | ||
76 | 94 | DBusBusType dbus_bus_type; | ||
77 | 95 | |||
78 | 96 | /** | ||
79 | 89 | * control_server_address: | 97 | * control_server_address: |
80 | 90 | * | 98 | * |
81 | 91 | * Address on which the control server may be reached. | 99 | * Address on which the control server may be reached. |
82 | @@ -258,16 +266,35 @@ | |||
83 | 258 | 266 | ||
84 | 259 | control_init (); | 267 | control_init (); |
85 | 260 | 268 | ||
89 | 261 | control_handle_bus_type (); | 269 | dbus_bus_type = control_get_bus_type (); |
90 | 262 | 270 | ||
91 | 263 | /* Connect to the D-Bus System Bus and hook everything up into | 271 | /* Avoid D-Bus attempting to autolaunch a dbus-daemon since: |
92 | 272 | * | ||
93 | 273 | * - the behaviour is undesirable: launching a dbus-daemon | ||
94 | 274 | * should be handled by a job. | ||
95 | 275 | * | ||
96 | 276 | * - if autolaunch fails (for example if DISPLAY is not set, or | ||
97 | 277 | * dbus-uuidgen has not been run (or the generated file is | ||
98 | 278 | * unreadable)), libdbus may call abort(), depending on how | ||
99 | 279 | * libdbus has been built. | ||
100 | 280 | */ | ||
101 | 281 | if (dbus_bus_type == DBUS_BUS_SESSION && ! getenv ("DBUS_SESSION_BUS_ADDRESS")) { | ||
102 | 282 | nih_dbus_error_raise ("dbus session bus error", | ||
103 | 283 | "DBUS_SESSION_BUS_ADDRESS not set"); | ||
104 | 284 | return -1; | ||
105 | 285 | } | ||
106 | 286 | |||
107 | 287 | /* Connect to the appropriate D-Bus bus and hook everything up into | ||
108 | 264 | * our own main loop automatically. | 288 | * our own main loop automatically. |
109 | 265 | */ | 289 | */ |
112 | 266 | conn = nih_dbus_bus (use_session_bus ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, | 290 | conn = nih_dbus_bus (dbus_bus_type, control_disconnected); |
111 | 267 | control_disconnected); | ||
113 | 268 | if (! conn) | 291 | if (! conn) |
114 | 269 | return -1; | 292 | return -1; |
115 | 270 | 293 | ||
116 | 294 | nih_debug ("Connected to D-Bus %s bus", | ||
117 | 295 | dbus_bus_type == DBUS_BUS_SESSION | ||
118 | 296 | ? "session" : "system"); | ||
119 | 297 | |||
120 | 271 | /* Register objects on the bus. */ | 298 | /* Register objects on the bus. */ |
121 | 272 | control_register_all (conn); | 299 | control_register_all (conn); |
122 | 273 | 300 | ||
123 | @@ -345,7 +372,9 @@ | |||
124 | 345 | 372 | ||
125 | 346 | dbus_error_init (&error); | 373 | dbus_error_init (&error); |
126 | 347 | 374 | ||
128 | 348 | nih_warn (_("Disconnected from system bus")); | 375 | nih_warn (_("Disconnected from D-Bus %s bus"), |
129 | 376 | dbus_bus_type == DBUS_BUS_SESSION | ||
130 | 377 | ? "session" : "system"); | ||
131 | 349 | 378 | ||
132 | 350 | control_bus = NULL; | 379 | control_bus = NULL; |
133 | 351 | } | 380 | } |
134 | @@ -817,19 +846,23 @@ | |||
135 | 817 | } | 846 | } |
136 | 818 | 847 | ||
137 | 819 | /** | 848 | /** |
139 | 820 | * control_handle_bus_type: | 849 | * control_get_bus_type: |
140 | 821 | * | 850 | * |
141 | 822 | * Determine D-Bus bus type to connect to. | 851 | * Determine D-Bus bus type to connect to. |
142 | 852 | * | ||
143 | 853 | * Returns: Type of D-Bus bus to connect to. | ||
144 | 823 | **/ | 854 | **/ |
147 | 824 | void | 855 | DBusBusType |
148 | 825 | control_handle_bus_type (void) | 856 | control_get_bus_type (void) |
149 | 826 | { | 857 | { |
150 | 827 | if (getenv (USE_SESSION_BUS_ENV)) | 858 | if (getenv (USE_SESSION_BUS_ENV)) |
151 | 828 | use_session_bus = TRUE; | 859 | use_session_bus = TRUE; |
152 | 829 | 860 | ||
155 | 830 | if (use_session_bus) | 861 | return (use_session_bus || user_mode) |
156 | 831 | nih_debug ("Using session bus"); | 862 | ? DBUS_BUS_SESSION |
157 | 863 | : DBUS_BUS_SYSTEM; | ||
158 | 832 | } | 864 | } |
159 | 865 | |||
160 | 833 | /** | 866 | /** |
161 | 834 | * control_notify_disk_writeable: | 867 | * control_notify_disk_writeable: |
162 | 835 | * @data: not used, | 868 | * @data: not used, |
163 | 836 | 869 | ||
164 | === modified file 'init/control.h' | |||
165 | --- init/control.h 2013-05-08 16:21:08 +0000 | |||
166 | +++ init/control.h 2013-10-22 10:15:27 +0000 | |||
167 | @@ -134,7 +134,11 @@ | |||
168 | 134 | const char *log_priority) | 134 | const char *log_priority) |
169 | 135 | __attribute__ ((warn_unused_result)); | 135 | __attribute__ ((warn_unused_result)); |
170 | 136 | 136 | ||
172 | 137 | void control_handle_bus_type (void); | 137 | DBusBusType control_get_bus_type (void) |
173 | 138 | __attribute__ ((warn_unused_result)); | ||
174 | 139 | |||
175 | 140 | const char *control_get_bus_name (void) | ||
176 | 141 | __attribute__ ((warn_unused_result)); | ||
177 | 138 | 142 | ||
178 | 139 | void control_prepare_reexec (void); | 143 | void control_prepare_reexec (void); |
179 | 140 | 144 | ||
180 | 141 | 145 | ||
181 | === modified file 'init/environ.c' | |||
182 | --- init/environ.c 2013-01-08 15:57:31 +0000 | |||
183 | +++ init/environ.c 2013-10-22 10:15:27 +0000 | |||
184 | @@ -202,6 +202,10 @@ | |||
185 | 202 | for (e = *env; e && *e; e++) { | 202 | for (e = *env; e && *e; e++) { |
186 | 203 | keylen = strcspn (*e, "="); | 203 | keylen = strcspn (*e, "="); |
187 | 204 | 204 | ||
188 | 205 | /* Found @str in the existing environment (either as a | ||
189 | 206 | * name=value pair, or a bare name), so don't copy it to | ||
190 | 207 | * the new environment. | ||
191 | 208 | */ | ||
192 | 205 | if (! strncmp (str, *e, keylen)) | 209 | if (! strncmp (str, *e, keylen)) |
193 | 206 | continue; | 210 | continue; |
194 | 207 | 211 | ||
195 | 208 | 212 | ||
196 | === modified file 'init/job_class.c' | |||
197 | --- init/job_class.c 2013-07-22 00:15:43 +0000 | |||
198 | +++ init/job_class.c 2013-10-22 10:15:27 +0000 | |||
199 | @@ -89,6 +89,14 @@ | |||
200 | 89 | NihHash *job_classes = NULL; | 89 | NihHash *job_classes = NULL; |
201 | 90 | 90 | ||
202 | 91 | /** | 91 | /** |
203 | 92 | * default_environ: | ||
204 | 93 | * | ||
205 | 94 | * Minimal set of environment variables all jobs are provided with by | ||
206 | 95 | * default. | ||
207 | 96 | */ | ||
208 | 97 | static char * const default_environ[] = { JOB_DEFAULT_ENVIRONMENT, NULL }; | ||
209 | 98 | |||
210 | 99 | /** | ||
211 | 92 | * job_environ: | 100 | * job_environ: |
212 | 93 | * | 101 | * |
213 | 94 | * Array of environment variables that will be set in the jobs | 102 | * Array of environment variables that will be set in the jobs |
214 | @@ -116,8 +124,6 @@ | |||
215 | 116 | void | 124 | void |
216 | 117 | job_class_environment_init (void) | 125 | job_class_environment_init (void) |
217 | 118 | { | 126 | { |
218 | 119 | char * const default_environ[] = { JOB_DEFAULT_ENVIRONMENT, NULL }; | ||
219 | 120 | |||
220 | 121 | if (job_environ) | 127 | if (job_environ) |
221 | 122 | return; | 128 | return; |
222 | 123 | 129 | ||
223 | @@ -125,7 +131,7 @@ | |||
224 | 125 | NIH_MUST (environ_append (&job_environ, NULL, 0, TRUE, default_environ)); | 131 | NIH_MUST (environ_append (&job_environ, NULL, 0, TRUE, default_environ)); |
225 | 126 | 132 | ||
226 | 127 | if (user_mode && ! no_inherit_env) | 133 | if (user_mode && ! no_inherit_env) |
228 | 128 | NIH_MUST(environ_append (&job_environ, NULL, 0, TRUE, environ)); | 134 | NIH_MUST (environ_append (&job_environ, NULL, 0, TRUE, environ)); |
229 | 129 | } | 135 | } |
230 | 130 | 136 | ||
231 | 131 | /** | 137 | /** |
232 | @@ -138,10 +144,10 @@ | |||
233 | 138 | void | 144 | void |
234 | 139 | job_class_environment_reset (void) | 145 | job_class_environment_reset (void) |
235 | 140 | { | 146 | { |
237 | 141 | if (job_environ) | 147 | if (job_environ) { |
238 | 142 | nih_free (job_environ); | 148 | nih_free (job_environ); |
241 | 143 | 149 | job_environ = NULL; | |
242 | 144 | job_environ = NULL; | 150 | } |
243 | 145 | 151 | ||
244 | 146 | job_class_environment_init (); | 152 | job_class_environment_init (); |
245 | 147 | } | 153 | } |
246 | @@ -160,9 +166,31 @@ | |||
247 | 160 | int | 166 | int |
248 | 161 | job_class_environment_set (const char *var, int replace) | 167 | job_class_environment_set (const char *var, int replace) |
249 | 162 | { | 168 | { |
250 | 169 | nih_local char *name = NULL; | ||
251 | 170 | char *value; | ||
252 | 171 | |||
253 | 163 | nih_assert (var); | 172 | nih_assert (var); |
254 | 164 | nih_assert (job_environ); | 173 | nih_assert (job_environ); |
255 | 165 | 174 | ||
256 | 175 | name = nih_strdup (NULL, var); | ||
257 | 176 | if (! name) | ||
258 | 177 | return -1; | ||
259 | 178 | |||
260 | 179 | value = strchr (name, '='); | ||
261 | 180 | nih_assert (value); | ||
262 | 181 | *value = '\0'; | ||
263 | 182 | |||
264 | 183 | /* Jump over delimiter */ | ||
265 | 184 | value++; | ||
266 | 185 | |||
267 | 186 | /* Set variable in Upstarts environment. | ||
268 | 187 | * | ||
269 | 188 | * This isn't necessary for jobs (due to job_environ), but is | ||
270 | 189 | * required to allow the Session Init to connect to the D-Bus | ||
271 | 190 | * session bus. | ||
272 | 191 | */ | ||
273 | 192 | setenv (name, value, replace); | ||
274 | 193 | |||
275 | 166 | if (! environ_add (&job_environ, NULL, NULL, replace, var)) | 194 | if (! environ_add (&job_environ, NULL, NULL, replace, var)) |
276 | 167 | return -1; | 195 | return -1; |
277 | 168 | 196 | ||
278 | @@ -193,9 +221,20 @@ | |||
279 | 193 | int | 221 | int |
280 | 194 | job_class_environment_unset (const char *name) | 222 | job_class_environment_unset (const char *name) |
281 | 195 | { | 223 | { |
282 | 224 | char * const *e; | ||
283 | 225 | int keep = FALSE; | ||
284 | 226 | |||
285 | 196 | nih_assert (name); | 227 | nih_assert (name); |
286 | 197 | nih_assert (job_environ); | 228 | nih_assert (job_environ); |
287 | 198 | 229 | ||
288 | 230 | /* Determine if @name is a default variable */ | ||
289 | 231 | for (e = default_environ; e && *e; e++) { | ||
290 | 232 | if (! strcmp (*e, name)) { | ||
291 | 233 | keep = TRUE; | ||
292 | 234 | break; | ||
293 | 235 | } | ||
294 | 236 | } | ||
295 | 237 | |||
296 | 199 | if (! environ_remove (&job_environ, NULL, NULL, name)) | 238 | if (! environ_remove (&job_environ, NULL, NULL, name)) |
297 | 200 | return -1; | 239 | return -1; |
298 | 201 | 240 | ||
299 | @@ -211,6 +250,17 @@ | |||
300 | 211 | } | 250 | } |
301 | 212 | } | 251 | } |
302 | 213 | 252 | ||
303 | 253 | if (! keep) { | ||
304 | 254 | /* Remove variable from Upstarts environment, but only if it is | ||
305 | 255 | * not part of the default environment; if we did this, | ||
306 | 256 | * it would not be possible to reset the job environment | ||
307 | 257 | * since adding a variable by name would *not* be added | ||
308 | 258 | * to the job environment table since the environment | ||
309 | 259 | * lookup would fail. | ||
310 | 260 | */ | ||
311 | 261 | unsetenv (name); | ||
312 | 262 | } | ||
313 | 263 | |||
314 | 214 | return 0; | 264 | return 0; |
315 | 215 | } | 265 | } |
316 | 216 | 266 | ||
317 | 217 | 267 | ||
318 | === modified file 'init/job_process.c' | |||
319 | --- init/job_process.c 2013-10-03 14:43:24 +0000 | |||
320 | +++ init/job_process.c 2013-10-22 10:15:27 +0000 | |||
321 | @@ -278,7 +278,7 @@ | |||
322 | 278 | env = NIH_MUST (nih_str_array_new (NULL)); | 278 | env = NIH_MUST (nih_str_array_new (NULL)); |
323 | 279 | 279 | ||
324 | 280 | if (job->env) | 280 | if (job->env) |
326 | 281 | NIH_MUST(environ_append (&env, NULL, &envc, TRUE, job->env)); | 281 | NIH_MUST (environ_append (&env, NULL, &envc, TRUE, job->env)); |
327 | 282 | 282 | ||
328 | 283 | if (job->stop_env | 283 | if (job->stop_env |
329 | 284 | && ((process == PROCESS_PRE_STOP) | 284 | && ((process == PROCESS_PRE_STOP) |
330 | 285 | 285 | ||
331 | === modified file 'init/main.c' | |||
332 | --- init/main.c 2013-07-31 09:28:48 +0000 | |||
333 | +++ init/main.c 2013-10-22 10:15:27 +0000 | |||
334 | @@ -128,7 +128,7 @@ | |||
335 | 128 | extern int default_console; | 128 | extern int default_console; |
336 | 129 | extern int write_state_file; | 129 | extern int write_state_file; |
337 | 130 | extern char *log_dir; | 130 | extern char *log_dir; |
339 | 131 | 131 | extern DBusBusType dbus_bus_type; | |
340 | 132 | 132 | ||
341 | 133 | /** | 133 | /** |
342 | 134 | * options: | 134 | * options: |
343 | @@ -213,7 +213,8 @@ | |||
344 | 213 | if (disable_job_logging) | 213 | if (disable_job_logging) |
345 | 214 | nih_debug ("Job logging disabled"); | 214 | nih_debug ("Job logging disabled"); |
346 | 215 | 215 | ||
348 | 216 | control_handle_bus_type (); | 216 | if (getenv (USE_SESSION_BUS_ENV)) |
349 | 217 | use_session_bus = TRUE; | ||
350 | 217 | 218 | ||
351 | 218 | if (! user_mode) | 219 | if (! user_mode) |
352 | 219 | no_inherit_env = TRUE; | 220 | no_inherit_env = TRUE; |
353 | @@ -933,14 +934,20 @@ | |||
354 | 933 | NihSignal *signal) | 934 | NihSignal *signal) |
355 | 934 | { | 935 | { |
356 | 935 | if (! control_bus) { | 936 | if (! control_bus) { |
358 | 936 | nih_info (_("Reconnecting to system bus")); | 937 | char *dbus_bus_name; |
359 | 938 | |||
360 | 939 | dbus_bus_name = dbus_bus_type == DBUS_BUS_SESSION | ||
361 | 940 | ? "session" : "system"; | ||
362 | 941 | |||
363 | 942 | nih_info (_("Reconnecting to D-Bus %s bus"), | ||
364 | 943 | dbus_bus_name); | ||
365 | 937 | 944 | ||
366 | 938 | if (control_bus_open () < 0) { | 945 | if (control_bus_open () < 0) { |
367 | 939 | NihError *err; | 946 | NihError *err; |
368 | 940 | 947 | ||
369 | 941 | err = nih_error_get (); | 948 | err = nih_error_get (); |
372 | 942 | nih_warn ("%s: %s", _("Unable to connect to the system bus"), | 949 | nih_warn (_("Unable to connect to the D-Bus %s bus: %s"), |
373 | 943 | err->message); | 950 | dbus_bus_name, err->message); |
374 | 944 | nih_free (err); | 951 | nih_free (err); |
375 | 945 | } | 952 | } |
376 | 946 | } | 953 | } |
377 | 947 | 954 | ||
378 | === modified file 'init/tests/test_control.c' | |||
379 | --- init/tests/test_control.c 2012-09-09 21:27:24 +0000 | |||
380 | +++ init/tests/test_control.c 2013-10-22 10:15:27 +0000 | |||
381 | @@ -821,7 +821,7 @@ | |||
382 | 821 | 821 | ||
383 | 822 | TEST_LIST_EMPTY (control_conns); | 822 | TEST_LIST_EMPTY (control_conns); |
384 | 823 | 823 | ||
386 | 824 | TEST_FILE_EQ (output, "test: Disconnected from system bus\n"); | 824 | TEST_FILE_EQ (output, "test: Disconnected from D-Bus system bus\n"); |
387 | 825 | TEST_FILE_END (output); | 825 | TEST_FILE_END (output); |
388 | 826 | TEST_FILE_RESET (output); | 826 | TEST_FILE_RESET (output); |
389 | 827 | 827 | ||
390 | @@ -879,7 +879,7 @@ | |||
391 | 879 | 879 | ||
392 | 880 | TEST_LIST_EMPTY (control_conns); | 880 | TEST_LIST_EMPTY (control_conns); |
393 | 881 | 881 | ||
395 | 882 | TEST_FILE_EQ (output, "test: Disconnected from system bus\n"); | 882 | TEST_FILE_EQ (output, "test: Disconnected from D-Bus system bus\n"); |
396 | 883 | TEST_FILE_END (output); | 883 | TEST_FILE_END (output); |
397 | 884 | TEST_FILE_RESET (output); | 884 | TEST_FILE_RESET (output); |
398 | 885 | 885 | ||
399 | 886 | 886 | ||
400 | === modified file 'init/tests/test_environ.c' | |||
401 | --- init/tests/test_environ.c 2011-06-06 17:05:11 +0000 | |||
402 | +++ init/tests/test_environ.c 2013-10-22 10:15:27 +0000 | |||
403 | @@ -572,6 +572,462 @@ | |||
404 | 572 | } | 572 | } |
405 | 573 | 573 | ||
406 | 574 | unsetenv ("BAR"); | 574 | unsetenv ("BAR"); |
407 | 575 | |||
408 | 576 | /* Check that attempting to add a variable by name fails if | ||
409 | 577 | * there is no corresponding environment variable set. | ||
410 | 578 | */ | ||
411 | 579 | TEST_FEATURE ("using bare word with no corresponding variable set in environment"); | ||
412 | 580 | |||
413 | 581 | /* Ensure variable not set initially */ | ||
414 | 582 | TEST_EQ_P (getenv ("UPSTART_TEST_VARIABLE"), NULL); | ||
415 | 583 | |||
416 | 584 | TEST_ALLOC_FAIL { | ||
417 | 585 | TEST_ALLOC_SAFE { | ||
418 | 586 | len = 0; | ||
419 | 587 | env = nih_str_array_new (NULL); | ||
420 | 588 | assert (nih_str_array_add (&env, NULL, &len, | ||
421 | 589 | "FOO=BAR")); | ||
422 | 590 | } | ||
423 | 591 | |||
424 | 592 | ret = environ_add (&env, NULL, &len, FALSE, "UPSTART_TEST_VARIABLE"); | ||
425 | 593 | |||
426 | 594 | if (test_alloc_failed) { | ||
427 | 595 | TEST_EQ_P (ret, NULL); | ||
428 | 596 | |||
429 | 597 | TEST_EQ (len, 1); | ||
430 | 598 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
431 | 599 | TEST_EQ_P (env[1], NULL); | ||
432 | 600 | |||
433 | 601 | nih_free (env); | ||
434 | 602 | continue; | ||
435 | 603 | } | ||
436 | 604 | |||
437 | 605 | /* XXX: Attempting to add an unset variable results in | ||
438 | 606 | * no change to the table (it is not an error!) | ||
439 | 607 | */ | ||
440 | 608 | TEST_EQ_P (ret, env); | ||
441 | 609 | |||
442 | 610 | TEST_EQ (len, 1); | ||
443 | 611 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
444 | 612 | TEST_EQ_P (env[1], NULL); | ||
445 | 613 | |||
446 | 614 | nih_free (env); | ||
447 | 615 | } | ||
448 | 616 | } | ||
449 | 617 | |||
450 | 618 | void | ||
451 | 619 | test_remove (void) | ||
452 | 620 | { | ||
453 | 621 | char **env = NULL, **ret; | ||
454 | 622 | size_t len = 0; | ||
455 | 623 | |||
456 | 624 | TEST_FUNCTION ("environ_remove"); | ||
457 | 625 | |||
458 | 626 | TEST_FEATURE ("remove name=value pair with empty table"); | ||
459 | 627 | TEST_ALLOC_FAIL { | ||
460 | 628 | TEST_ALLOC_SAFE { | ||
461 | 629 | len = 0; | ||
462 | 630 | env = nih_str_array_new (NULL); | ||
463 | 631 | } | ||
464 | 632 | |||
465 | 633 | ret = environ_remove (&env, NULL, &len, "FOO=BAR"); | ||
466 | 634 | |||
467 | 635 | if (test_alloc_failed) { | ||
468 | 636 | TEST_EQ_P (ret, NULL); | ||
469 | 637 | |||
470 | 638 | TEST_EQ (len, 0); | ||
471 | 639 | TEST_EQ_P (env[0], NULL); | ||
472 | 640 | |||
473 | 641 | nih_free (env); | ||
474 | 642 | continue; | ||
475 | 643 | } | ||
476 | 644 | |||
477 | 645 | TEST_EQ_P (ret, NULL); | ||
478 | 646 | TEST_EQ (len, 0); | ||
479 | 647 | TEST_EQ_P (env[0], NULL); | ||
480 | 648 | |||
481 | 649 | nih_free (env); | ||
482 | 650 | } | ||
483 | 651 | |||
484 | 652 | TEST_FEATURE ("remove bare name with empty table"); | ||
485 | 653 | TEST_ALLOC_FAIL { | ||
486 | 654 | TEST_ALLOC_SAFE { | ||
487 | 655 | len = 0; | ||
488 | 656 | env = nih_str_array_new (NULL); | ||
489 | 657 | } | ||
490 | 658 | |||
491 | 659 | ret = environ_remove (&env, NULL, &len, "FOO"); | ||
492 | 660 | |||
493 | 661 | if (test_alloc_failed) { | ||
494 | 662 | TEST_EQ_P (ret, NULL); | ||
495 | 663 | |||
496 | 664 | TEST_EQ (len, 0); | ||
497 | 665 | TEST_EQ_P (env[0], NULL); | ||
498 | 666 | |||
499 | 667 | nih_free (env); | ||
500 | 668 | continue; | ||
501 | 669 | } | ||
502 | 670 | |||
503 | 671 | TEST_EQ_P (ret, NULL); | ||
504 | 672 | TEST_EQ (len, 0); | ||
505 | 673 | TEST_EQ_P (env[0], NULL); | ||
506 | 674 | |||
507 | 675 | nih_free (env); | ||
508 | 676 | } | ||
509 | 677 | |||
510 | 678 | TEST_FEATURE ("remove name=value from table of size 1"); | ||
511 | 679 | TEST_ALLOC_FAIL { | ||
512 | 680 | TEST_ALLOC_SAFE { | ||
513 | 681 | len = 0; | ||
514 | 682 | env = nih_str_array_new (NULL); | ||
515 | 683 | |||
516 | 684 | ret = environ_add (&env, NULL, &len, TRUE, "FOO=BAR"); | ||
517 | 685 | TEST_NE_P (ret, NULL); | ||
518 | 686 | |||
519 | 687 | TEST_EQ (len, 1); | ||
520 | 688 | TEST_ALLOC_PARENT (env[0], env); | ||
521 | 689 | TEST_ALLOC_SIZE (env[0], 8); | ||
522 | 690 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
523 | 691 | TEST_EQ_P (env[1], NULL); | ||
524 | 692 | } | ||
525 | 693 | |||
526 | 694 | ret = environ_remove (&env, NULL, &len, "FOO=BAR"); | ||
527 | 695 | |||
528 | 696 | if (test_alloc_failed) { | ||
529 | 697 | TEST_EQ_P (ret, NULL); | ||
530 | 698 | |||
531 | 699 | TEST_EQ (len, 1); | ||
532 | 700 | |||
533 | 701 | TEST_ALLOC_PARENT (env[0], env); | ||
534 | 702 | TEST_ALLOC_SIZE (env[0], 8); | ||
535 | 703 | |||
536 | 704 | TEST_NE_P (env[0], NULL); | ||
537 | 705 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
538 | 706 | |||
539 | 707 | TEST_EQ_P (env[1], NULL); | ||
540 | 708 | |||
541 | 709 | nih_free (env); | ||
542 | 710 | continue; | ||
543 | 711 | } | ||
544 | 712 | |||
545 | 713 | TEST_NE_P (ret, NULL); | ||
546 | 714 | TEST_EQ (len, 0); | ||
547 | 715 | TEST_EQ_P (env[0], NULL); | ||
548 | 716 | |||
549 | 717 | nih_free (env); | ||
550 | 718 | } | ||
551 | 719 | |||
552 | 720 | TEST_FEATURE ("remove bare name from table of size 1"); | ||
553 | 721 | TEST_ALLOC_FAIL { | ||
554 | 722 | TEST_ALLOC_SAFE { | ||
555 | 723 | len = 0; | ||
556 | 724 | env = nih_str_array_new (NULL); | ||
557 | 725 | |||
558 | 726 | ret = environ_add (&env, NULL, &len, TRUE, "FOO=BAR"); | ||
559 | 727 | TEST_NE_P (ret, NULL); | ||
560 | 728 | |||
561 | 729 | TEST_EQ (len, 1); | ||
562 | 730 | TEST_ALLOC_PARENT (env[0], env); | ||
563 | 731 | TEST_ALLOC_SIZE (env[0], 8); | ||
564 | 732 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
565 | 733 | TEST_EQ_P (env[1], NULL); | ||
566 | 734 | } | ||
567 | 735 | |||
568 | 736 | ret = environ_remove (&env, NULL, &len, "FOO"); | ||
569 | 737 | |||
570 | 738 | if (test_alloc_failed) { | ||
571 | 739 | TEST_EQ_P (ret, NULL); | ||
572 | 740 | |||
573 | 741 | TEST_EQ (len, 1); | ||
574 | 742 | |||
575 | 743 | TEST_ALLOC_PARENT (env[0], env); | ||
576 | 744 | TEST_ALLOC_SIZE (env[0], 8); | ||
577 | 745 | |||
578 | 746 | TEST_NE_P (env[0], NULL); | ||
579 | 747 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
580 | 748 | |||
581 | 749 | TEST_EQ_P (env[1], NULL); | ||
582 | 750 | |||
583 | 751 | nih_free (env); | ||
584 | 752 | continue; | ||
585 | 753 | } | ||
586 | 754 | |||
587 | 755 | TEST_NE_P (ret, NULL); | ||
588 | 756 | TEST_EQ (len, 0); | ||
589 | 757 | TEST_EQ_P (env[0], NULL); | ||
590 | 758 | |||
591 | 759 | nih_free (env); | ||
592 | 760 | } | ||
593 | 761 | |||
594 | 762 | TEST_FEATURE ("remove first name=value entry from table of size 2"); | ||
595 | 763 | TEST_ALLOC_FAIL { | ||
596 | 764 | TEST_ALLOC_SAFE { | ||
597 | 765 | len = 0; | ||
598 | 766 | env = nih_str_array_new (NULL); | ||
599 | 767 | |||
600 | 768 | ret = environ_add (&env, NULL, &len, TRUE, "FOO=BAR"); | ||
601 | 769 | TEST_NE_P (ret, NULL); | ||
602 | 770 | |||
603 | 771 | TEST_EQ (len, 1); | ||
604 | 772 | TEST_ALLOC_PARENT (env[0], env); | ||
605 | 773 | TEST_ALLOC_SIZE (env[0], 8); | ||
606 | 774 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
607 | 775 | TEST_EQ_P (env[1], NULL); | ||
608 | 776 | |||
609 | 777 | ret = environ_add (&env, NULL, &len, TRUE, "BAZ=QUX"); | ||
610 | 778 | TEST_NE_P (ret, NULL); | ||
611 | 779 | |||
612 | 780 | TEST_EQ (len, 2); | ||
613 | 781 | TEST_ALLOC_PARENT (env[0], env); | ||
614 | 782 | TEST_ALLOC_SIZE (env[0], 8); | ||
615 | 783 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
616 | 784 | |||
617 | 785 | TEST_ALLOC_PARENT (env[1], env); | ||
618 | 786 | TEST_ALLOC_SIZE (env[1], 8); | ||
619 | 787 | TEST_EQ_STR (env[1], "BAZ=QUX"); | ||
620 | 788 | |||
621 | 789 | TEST_EQ_P (env[2], NULL); | ||
622 | 790 | } | ||
623 | 791 | |||
624 | 792 | /* Remove first entry added */ | ||
625 | 793 | ret = environ_remove (&env, NULL, &len, "FOO=BAR"); | ||
626 | 794 | |||
627 | 795 | if (test_alloc_failed) { | ||
628 | 796 | TEST_EQ_P (ret, NULL); | ||
629 | 797 | |||
630 | 798 | TEST_EQ (len, 2); | ||
631 | 799 | TEST_ALLOC_PARENT (env[0], env); | ||
632 | 800 | TEST_ALLOC_SIZE (env[0], 8); | ||
633 | 801 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
634 | 802 | |||
635 | 803 | TEST_ALLOC_PARENT (env[1], env); | ||
636 | 804 | TEST_ALLOC_SIZE (env[1], 8); | ||
637 | 805 | TEST_EQ_STR (env[1], "BAZ=QUX"); | ||
638 | 806 | |||
639 | 807 | TEST_EQ_P (env[2], NULL); | ||
640 | 808 | |||
641 | 809 | nih_free (env); | ||
642 | 810 | continue; | ||
643 | 811 | } | ||
644 | 812 | |||
645 | 813 | TEST_NE_P (ret, NULL); | ||
646 | 814 | TEST_EQ (len, 1); | ||
647 | 815 | |||
648 | 816 | TEST_ALLOC_PARENT (env[0], env); | ||
649 | 817 | TEST_ALLOC_SIZE (env[0], 8); | ||
650 | 818 | TEST_EQ_STR (env[0], "BAZ=QUX"); | ||
651 | 819 | |||
652 | 820 | TEST_EQ_P (env[1], NULL); | ||
653 | 821 | |||
654 | 822 | nih_free (env); | ||
655 | 823 | } | ||
656 | 824 | |||
657 | 825 | TEST_FEATURE ("remove first bare name entry from table of size 2"); | ||
658 | 826 | |||
659 | 827 | /* Set a variable to allow the bare name to be expanded */ | ||
660 | 828 | assert0 (setenv ("UPSTART_TEST_VARIABLE", "foo", 1)); | ||
661 | 829 | |||
662 | 830 | TEST_ALLOC_FAIL { | ||
663 | 831 | TEST_ALLOC_SAFE { | ||
664 | 832 | len = 0; | ||
665 | 833 | env = nih_str_array_new (NULL); | ||
666 | 834 | |||
667 | 835 | ret = environ_add (&env, NULL, &len, TRUE, "UPSTART_TEST_VARIABLE"); | ||
668 | 836 | TEST_NE_P (ret, NULL); | ||
669 | 837 | |||
670 | 838 | TEST_EQ (len, 1); | ||
671 | 839 | TEST_ALLOC_PARENT (env[0], env); | ||
672 | 840 | TEST_ALLOC_SIZE (env[0], 8); | ||
673 | 841 | |||
674 | 842 | /* Should have been expanded */ | ||
675 | 843 | TEST_EQ_STR (env[0], "UPSTART_TEST_VARIABLE=foo"); | ||
676 | 844 | |||
677 | 845 | TEST_EQ_P (env[1], NULL); | ||
678 | 846 | |||
679 | 847 | ret = environ_add (&env, NULL, &len, TRUE, "BAZ=QUX"); | ||
680 | 848 | TEST_NE_P (ret, NULL); | ||
681 | 849 | |||
682 | 850 | TEST_EQ (len, 2); | ||
683 | 851 | |||
684 | 852 | TEST_ALLOC_PARENT (env[0], env); | ||
685 | 853 | TEST_ALLOC_SIZE (env[0], 8); | ||
686 | 854 | TEST_EQ_STR (env[0], "UPSTART_TEST_VARIABLE=foo"); | ||
687 | 855 | |||
688 | 856 | TEST_ALLOC_PARENT (env[1], env); | ||
689 | 857 | TEST_ALLOC_SIZE (env[1], 8); | ||
690 | 858 | TEST_EQ_STR (env[1], "BAZ=QUX"); | ||
691 | 859 | |||
692 | 860 | TEST_EQ_P (env[2], NULL); | ||
693 | 861 | } | ||
694 | 862 | |||
695 | 863 | /* Remove first entry added */ | ||
696 | 864 | ret = environ_remove (&env, NULL, &len, "UPSTART_TEST_VARIABLE"); | ||
697 | 865 | |||
698 | 866 | if (test_alloc_failed) { | ||
699 | 867 | TEST_EQ_P (ret, NULL); | ||
700 | 868 | |||
701 | 869 | TEST_EQ (len, 2); | ||
702 | 870 | TEST_ALLOC_PARENT (env[0], env); | ||
703 | 871 | TEST_ALLOC_SIZE (env[0], 8); | ||
704 | 872 | TEST_EQ_STR (env[0], "UPSTART_TEST_VARIABLE=foo"); | ||
705 | 873 | |||
706 | 874 | TEST_ALLOC_PARENT (env[1], env); | ||
707 | 875 | TEST_ALLOC_SIZE (env[1], 8); | ||
708 | 876 | TEST_EQ_STR (env[1], "BAZ=QUX"); | ||
709 | 877 | |||
710 | 878 | TEST_EQ_P (env[2], NULL); | ||
711 | 879 | |||
712 | 880 | nih_free (env); | ||
713 | 881 | continue; | ||
714 | 882 | } | ||
715 | 883 | |||
716 | 884 | TEST_NE_P (ret, NULL); | ||
717 | 885 | TEST_EQ (len, 1); | ||
718 | 886 | |||
719 | 887 | TEST_ALLOC_PARENT (env[0], env); | ||
720 | 888 | TEST_ALLOC_SIZE (env[0], 8); | ||
721 | 889 | TEST_EQ_STR (env[0], "BAZ=QUX"); | ||
722 | 890 | |||
723 | 891 | TEST_EQ_P (env[1], NULL); | ||
724 | 892 | |||
725 | 893 | nih_free (env); | ||
726 | 894 | } | ||
727 | 895 | |||
728 | 896 | assert0 (unsetenv ("UPSTART_TEST_VARIABLE")); | ||
729 | 897 | |||
730 | 898 | TEST_FEATURE ("remove last name=value entry from table of size 2"); | ||
731 | 899 | TEST_ALLOC_FAIL { | ||
732 | 900 | TEST_ALLOC_SAFE { | ||
733 | 901 | len = 0; | ||
734 | 902 | env = nih_str_array_new (NULL); | ||
735 | 903 | |||
736 | 904 | ret = environ_add (&env, NULL, &len, TRUE, "FOO=BAR"); | ||
737 | 905 | TEST_NE_P (ret, NULL); | ||
738 | 906 | |||
739 | 907 | TEST_EQ (len, 1); | ||
740 | 908 | TEST_ALLOC_PARENT (env[0], env); | ||
741 | 909 | TEST_ALLOC_SIZE (env[0], 8); | ||
742 | 910 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
743 | 911 | TEST_EQ_P (env[1], NULL); | ||
744 | 912 | |||
745 | 913 | ret = environ_add (&env, NULL, &len, TRUE, "BAZ=QUX"); | ||
746 | 914 | TEST_NE_P (ret, NULL); | ||
747 | 915 | |||
748 | 916 | TEST_EQ (len, 2); | ||
749 | 917 | TEST_ALLOC_PARENT (env[0], env); | ||
750 | 918 | TEST_ALLOC_SIZE (env[0], 8); | ||
751 | 919 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
752 | 920 | |||
753 | 921 | TEST_ALLOC_PARENT (env[1], env); | ||
754 | 922 | TEST_ALLOC_SIZE (env[1], 8); | ||
755 | 923 | TEST_EQ_STR (env[1], "BAZ=QUX"); | ||
756 | 924 | |||
757 | 925 | TEST_EQ_P (env[2], NULL); | ||
758 | 926 | } | ||
759 | 927 | |||
760 | 928 | /* Remove last entry added */ | ||
761 | 929 | ret = environ_remove (&env, NULL, &len, "BAZ=QUX"); | ||
762 | 930 | |||
763 | 931 | if (test_alloc_failed) { | ||
764 | 932 | TEST_EQ_P (ret, NULL); | ||
765 | 933 | |||
766 | 934 | TEST_EQ (len, 2); | ||
767 | 935 | TEST_ALLOC_PARENT (env[0], env); | ||
768 | 936 | TEST_ALLOC_SIZE (env[0], 8); | ||
769 | 937 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
770 | 938 | |||
771 | 939 | TEST_ALLOC_PARENT (env[1], env); | ||
772 | 940 | TEST_ALLOC_SIZE (env[1], 8); | ||
773 | 941 | TEST_EQ_STR (env[1], "BAZ=QUX"); | ||
774 | 942 | |||
775 | 943 | TEST_EQ_P (env[2], NULL); | ||
776 | 944 | |||
777 | 945 | nih_free (env); | ||
778 | 946 | continue; | ||
779 | 947 | } | ||
780 | 948 | |||
781 | 949 | TEST_NE_P (ret, NULL); | ||
782 | 950 | TEST_EQ (len, 1); | ||
783 | 951 | |||
784 | 952 | TEST_ALLOC_PARENT (env[0], env); | ||
785 | 953 | TEST_ALLOC_SIZE (env[0], 8); | ||
786 | 954 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
787 | 955 | |||
788 | 956 | TEST_EQ_P (env[1], NULL); | ||
789 | 957 | |||
790 | 958 | nih_free (env); | ||
791 | 959 | } | ||
792 | 960 | |||
793 | 961 | TEST_FEATURE ("remove last bare name entry from table of size 2"); | ||
794 | 962 | |||
795 | 963 | /* Set a variable to allow the bare name to be expanded */ | ||
796 | 964 | assert0 (setenv ("UPSTART_TEST_VARIABLE", "foo", 1)); | ||
797 | 965 | |||
798 | 966 | TEST_ALLOC_FAIL { | ||
799 | 967 | TEST_ALLOC_SAFE { | ||
800 | 968 | len = 0; | ||
801 | 969 | env = nih_str_array_new (NULL); | ||
802 | 970 | |||
803 | 971 | ret = environ_add (&env, NULL, &len, TRUE, "FOO=BAR"); | ||
804 | 972 | TEST_NE_P (ret, NULL); | ||
805 | 973 | |||
806 | 974 | TEST_EQ (len, 1); | ||
807 | 975 | TEST_ALLOC_PARENT (env[0], env); | ||
808 | 976 | TEST_ALLOC_SIZE (env[0], 8); | ||
809 | 977 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
810 | 978 | TEST_EQ_P (env[1], NULL); | ||
811 | 979 | |||
812 | 980 | ret = environ_add (&env, NULL, &len, TRUE, "UPSTART_TEST_VARIABLE"); | ||
813 | 981 | TEST_NE_P (ret, NULL); | ||
814 | 982 | |||
815 | 983 | TEST_EQ (len, 2); | ||
816 | 984 | TEST_ALLOC_PARENT (env[0], env); | ||
817 | 985 | TEST_ALLOC_SIZE (env[0], 8); | ||
818 | 986 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
819 | 987 | |||
820 | 988 | TEST_ALLOC_PARENT (env[1], env); | ||
821 | 989 | TEST_ALLOC_SIZE (env[1], 8); | ||
822 | 990 | |||
823 | 991 | /* Should have been expanded */ | ||
824 | 992 | TEST_EQ_STR (env[1], "UPSTART_TEST_VARIABLE=foo"); | ||
825 | 993 | |||
826 | 994 | TEST_EQ_P (env[2], NULL); | ||
827 | 995 | } | ||
828 | 996 | |||
829 | 997 | /* Remove last entry added */ | ||
830 | 998 | ret = environ_remove (&env, NULL, &len, "UPSTART_TEST_VARIABLE"); | ||
831 | 999 | |||
832 | 1000 | if (test_alloc_failed) { | ||
833 | 1001 | TEST_EQ_P (ret, NULL); | ||
834 | 1002 | |||
835 | 1003 | TEST_EQ (len, 2); | ||
836 | 1004 | TEST_ALLOC_PARENT (env[0], env); | ||
837 | 1005 | TEST_ALLOC_SIZE (env[0], 8); | ||
838 | 1006 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
839 | 1007 | |||
840 | 1008 | TEST_ALLOC_PARENT (env[1], env); | ||
841 | 1009 | TEST_ALLOC_SIZE (env[1], 8); | ||
842 | 1010 | TEST_EQ_STR (env[1], "UPSTART_TEST_VARIABLE=foo"); | ||
843 | 1011 | |||
844 | 1012 | TEST_EQ_P (env[2], NULL); | ||
845 | 1013 | |||
846 | 1014 | nih_free (env); | ||
847 | 1015 | continue; | ||
848 | 1016 | } | ||
849 | 1017 | |||
850 | 1018 | TEST_NE_P (ret, NULL); | ||
851 | 1019 | TEST_EQ (len, 1); | ||
852 | 1020 | |||
853 | 1021 | TEST_ALLOC_PARENT (env[0], env); | ||
854 | 1022 | TEST_ALLOC_SIZE (env[0], 8); | ||
855 | 1023 | TEST_EQ_STR (env[0], "FOO=BAR"); | ||
856 | 1024 | |||
857 | 1025 | TEST_EQ_P (env[1], NULL); | ||
858 | 1026 | |||
859 | 1027 | nih_free (env); | ||
860 | 1028 | } | ||
861 | 1029 | |||
862 | 1030 | assert0 (unsetenv ("UPSTART_TEST_VARIABLE")); | ||
863 | 575 | } | 1031 | } |
864 | 576 | 1032 | ||
865 | 577 | void | 1033 | void |
866 | @@ -1590,6 +2046,7 @@ | |||
867 | 1590 | setenv ("UPSTART_NO_SESSIONS", "1", 1); | 2046 | setenv ("UPSTART_NO_SESSIONS", "1", 1); |
868 | 1591 | 2047 | ||
869 | 1592 | test_add (); | 2048 | test_add (); |
870 | 2049 | test_remove (); | ||
871 | 1593 | test_append (); | 2050 | test_append (); |
872 | 1594 | test_set (); | 2051 | test_set (); |
873 | 1595 | test_lookup (); | 2052 | test_lookup (); |
874 | 1596 | 2053 | ||
875 | === modified file 'test/test_util_common.c' | |||
876 | --- test/test_util_common.c 2013-10-02 08:59:20 +0000 | |||
877 | +++ test/test_util_common.c 2013-10-22 10:15:27 +0000 | |||
878 | @@ -120,7 +120,7 @@ | |||
879 | 120 | } | 120 | } |
880 | 121 | 121 | ||
881 | 122 | /* TRUE to denote that Upstart is running in user session mode | 122 | /* TRUE to denote that Upstart is running in user session mode |
883 | 123 | * (FALSE to denote it's using the users D-Bus session bus). | 123 | * (FALSE to denote it's using a D-Bus session bus only). |
884 | 124 | */ | 124 | */ |
885 | 125 | int test_user_mode = FALSE; | 125 | int test_user_mode = FALSE; |
886 | 126 | 126 | ||
887 | @@ -349,6 +349,16 @@ | |||
888 | 349 | { | 349 | { |
889 | 350 | static char path[PATH_MAX + 1024] = { 0 }; | 350 | static char path[PATH_MAX + 1024] = { 0 }; |
890 | 351 | int ret; | 351 | int ret; |
891 | 352 | int env_valid; | ||
892 | 353 | |||
893 | 354 | /* Sanity check calling environment */ | ||
894 | 355 | if (test_user_mode) { | ||
895 | 356 | env_valid = getenv ("UPSTART_SESSION") ? TRUE : FALSE; | ||
896 | 357 | } else { | ||
897 | 358 | env_valid = getenv ("DBUS_SESSION_BUS_ADDRESS") ? TRUE : FALSE; | ||
898 | 359 | } | ||
899 | 360 | |||
900 | 361 | nih_assert (env_valid); | ||
901 | 352 | 362 | ||
902 | 353 | ret = sprintf (path, "%s %s", | 363 | ret = sprintf (path, "%s %s", |
903 | 354 | get_initctl_binary (), | 364 | get_initctl_binary (), |
904 | 355 | 365 | ||
905 | === modified file 'util/initctl.c' | |||
906 | --- util/initctl.c 2013-07-21 23:54:16 +0000 | |||
907 | +++ util/initctl.c 2013-10-22 10:15:27 +0000 | |||
908 | @@ -342,8 +342,7 @@ | |||
909 | 342 | use_dbus = getuid () ? TRUE : FALSE; | 342 | use_dbus = getuid () ? TRUE : FALSE; |
910 | 343 | if (use_dbus >= 0 && dbus_bus_type < 0) | 343 | if (use_dbus >= 0 && dbus_bus_type < 0) |
911 | 344 | dbus_bus_type = DBUS_BUS_SYSTEM; | 344 | dbus_bus_type = DBUS_BUS_SYSTEM; |
914 | 345 | } | 345 | } else { |
913 | 346 | else { | ||
915 | 347 | if (! user_addr) { | 346 | if (! user_addr) { |
916 | 348 | nih_error ("UPSTART_SESSION isn't set in the environment. " | 347 | nih_error ("UPSTART_SESSION isn't set in the environment. " |
917 | 349 | "Unable to locate the Upstart instance."); | 348 | "Unable to locate the Upstart instance."); |
918 | @@ -2827,7 +2826,7 @@ | |||
919 | 2827 | * Command-line options accepted for all arguments. | 2826 | * Command-line options accepted for all arguments. |
920 | 2828 | **/ | 2827 | **/ |
921 | 2829 | static NihOption options[] = { | 2828 | static NihOption options[] = { |
923 | 2830 | { 0, "session", N_("use D-Bus session bus to connect to init daemon (for testing)"), | 2829 | { 0, "session", N_("use D-Bus session bus to connect to init daemon"), |
924 | 2831 | NULL, NULL, NULL, dbus_bus_type_setter }, | 2830 | NULL, NULL, NULL, dbus_bus_type_setter }, |
925 | 2832 | { 0, "system", N_("use D-Bus system bus to connect to init daemon"), | 2831 | { 0, "system", N_("use D-Bus system bus to connect to init daemon"), |
926 | 2833 | NULL, NULL, NULL, dbus_bus_type_setter }, | 2832 | NULL, NULL, NULL, dbus_bus_type_setter }, |
927 | 2834 | 2833 | ||
928 | === modified file 'util/man/initctl.8' | |||
929 | --- util/man/initctl.8 2013-05-31 15:41:20 +0000 | |||
930 | +++ util/man/initctl.8 2013-10-22 10:15:27 +0000 | |||
931 | @@ -47,9 +47,9 @@ | |||
932 | 47 | .\" | 47 | .\" |
933 | 48 | .TP | 48 | .TP |
934 | 49 | .B \-\-session | 49 | .B \-\-session |
936 | 50 | Connect to | 50 | Connect to the |
937 | 51 | .BR init (8) | 51 | .BR init (8) |
939 | 52 | daemon using the D\-Bus session bus (for testing purposes only). | 52 | daemon using the D\-Bus session bus. |
940 | 53 | .\" | 53 | .\" |
941 | 54 | .TP | 54 | .TP |
942 | 55 | .B \-\-system | 55 | .B \-\-system |
943 | 56 | 56 | ||
944 | === modified file 'util/tests/test_initctl.c' | |||
945 | --- util/tests/test_initctl.c 2013-09-26 16:33:07 +0000 | |||
946 | +++ util/tests/test_initctl.c 2013-10-22 10:15:27 +0000 | |||
947 | @@ -16698,6 +16698,89 @@ | |||
948 | 16698 | TEST_EQ (rmdir (logdir), 0); | 16698 | TEST_EQ (rmdir (logdir), 0); |
949 | 16699 | } | 16699 | } |
950 | 16700 | 16700 | ||
951 | 16701 | void | ||
952 | 16702 | test_session_init (void) | ||
953 | 16703 | { | ||
954 | 16704 | size_t lines; | ||
955 | 16705 | pid_t dbus_pid = 0; | ||
956 | 16706 | pid_t upstart_pid = 0; | ||
957 | 16707 | nih_local char *cmd = NULL; | ||
958 | 16708 | char **output; | ||
959 | 16709 | nih_local char *dbus_session_address = NULL; | ||
960 | 16710 | nih_local char *upstart_session = NULL; | ||
961 | 16711 | char *address; | ||
962 | 16712 | |||
963 | 16713 | TEST_GROUP ("User Mode"); | ||
964 | 16714 | |||
965 | 16715 | TEST_FEATURE ("ensure session init connects to D-Bus session bus"); | ||
966 | 16716 | |||
967 | 16717 | /* Start a dbus-daemon */ | ||
968 | 16718 | TEST_DBUS (dbus_pid); | ||
969 | 16719 | |||
970 | 16720 | /* Not required */ | ||
971 | 16721 | assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS")); | ||
972 | 16722 | |||
973 | 16723 | address = getenv ("DBUS_SESSION_BUS_ADDRESS"); | ||
974 | 16724 | TEST_NE_P (address, NULL); | ||
975 | 16725 | |||
976 | 16726 | dbus_session_address = nih_strdup (NULL, address); | ||
977 | 16727 | TEST_NE_P (dbus_session_address, NULL); | ||
978 | 16728 | |||
979 | 16729 | /* Stop Upstart connectng to the D-Bus session bus at | ||
980 | 16730 | * startup (it will attempt to do so, but fail and try again on | ||
981 | 16731 | * SIGUSR1. | ||
982 | 16732 | */ | ||
983 | 16733 | assert0 (unsetenv ("DBUS_SESSION_BUS_ADDRESS")); | ||
984 | 16734 | |||
985 | 16735 | START_UPSTART (upstart_pid, TRUE); | ||
986 | 16736 | |||
987 | 16737 | /* Save the Upstart session socket details and unset to stop | ||
988 | 16738 | * initctl finding upstart via this route. | ||
989 | 16739 | */ | ||
990 | 16740 | address = getenv ("UPSTART_SESSION"); | ||
991 | 16741 | TEST_NE_P (address, NULL); | ||
992 | 16742 | upstart_session = nih_strdup (NULL, address); | ||
993 | 16743 | TEST_NE_P (upstart_session, NULL); | ||
994 | 16744 | assert0 (unsetenv ("UPSTART_SESSION")); | ||
995 | 16745 | |||
996 | 16746 | /* Ensure it is not possible to query the running version via | ||
997 | 16747 | * the D-Bus session bus. | ||
998 | 16748 | */ | ||
999 | 16749 | cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ()); | ||
1000 | 16750 | TEST_NE_P (cmd, NULL); | ||
1001 | 16751 | RUN_COMMAND (NULL, cmd, &output, &lines); | ||
1002 | 16752 | TEST_EQ (lines, 1); | ||
1003 | 16753 | TEST_STR_MATCH (output[0], "initctl: Name \"com.ubuntu.Upstart\" does not exist*"); | ||
1004 | 16754 | |||
1005 | 16755 | /* Re-apply in the test environment */ | ||
1006 | 16756 | assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address, 1)); | ||
1007 | 16757 | assert0 (setenv ("UPSTART_SESSION", upstart_session, 1)); | ||
1008 | 16758 | |||
1009 | 16759 | /* Set the variable in Upstarts environment too */ | ||
1010 | 16760 | cmd = nih_sprintf (NULL, "%s --user set-env -g %s=%s", | ||
1011 | 16761 | get_initctl_binary (), | ||
1012 | 16762 | "DBUS_SESSION_BUS_ADDRESS", | ||
1013 | 16763 | dbus_session_address); | ||
1014 | 16764 | TEST_NE_P (cmd, NULL); | ||
1015 | 16765 | RUN_COMMAND (NULL, cmd, &output, &lines); | ||
1016 | 16766 | TEST_EQ (lines, 0); | ||
1017 | 16767 | |||
1018 | 16768 | /* Send signal to upstart requesting it reconnect to D-Bus */ | ||
1019 | 16769 | assert0 (kill (upstart_pid, SIGUSR1)); | ||
1020 | 16770 | |||
1021 | 16771 | /* It should now be possible to query the running version via | ||
1022 | 16772 | * the D-Bus session bus. | ||
1023 | 16773 | */ | ||
1024 | 16774 | cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ()); | ||
1025 | 16775 | TEST_NE_P (cmd, NULL); | ||
1026 | 16776 | RUN_COMMAND (NULL, cmd, &output, &lines); | ||
1027 | 16777 | TEST_EQ (lines, 1); | ||
1028 | 16778 | TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*"); | ||
1029 | 16779 | |||
1030 | 16780 | STOP_UPSTART (upstart_pid); | ||
1031 | 16781 | TEST_DBUS_END (dbus_pid); | ||
1032 | 16782 | } | ||
1033 | 16783 | |||
1034 | 16701 | int | 16784 | int |
1035 | 16702 | main (int argc, | 16785 | main (int argc, |
1036 | 16703 | char *argv[]) | 16786 | char *argv[]) |
1037 | @@ -16741,5 +16824,7 @@ | |||
1038 | 16741 | test_notify_disk_writeable (); | 16824 | test_notify_disk_writeable (); |
1039 | 16742 | } | 16825 | } |
1040 | 16743 | 16826 | ||
1041 | 16827 | test_session_init (); | ||
1042 | 16828 | |||
1043 | 16744 | return 0; | 16829 | return 0; |
1044 | 16745 | } | 16830 | } |
This branch makes the Session Init attempt to connect to the D-Bus session bus on startup and retry when sent SIGUSR1. This behaviour is consistent with Upstart running as PID 1 and connecting to the D-Bus system bus.
The branch achieves the required behaviour by setting all global job environment variables in the Session Inits own environment too. This is specifically so that the Session Init will have knowledge of DBUS_SESSION_ BUS_ADDRESS but avoids hard-coding a whitelist of variables to set. Note that since the Session Inits environment will change with each 'initctl (un)set-env -g ...', a subsequent call to 'initctl reset-env -g' will set the environment back to contain:
1) The default variables (PATH, TERM).
2) The Session Inits initial environment.
3) Any variables set via 'set-env -g'.
This is a subtle behavioural change which although not ideal can be rectified by manually running 'unsetenv $var' for all job global variables that should be removed from job environments.
Note that Upstart running as PID 1 will not have its environment modified.
Tested to ensure that bug 1235649 is resolved when a client connects to Upstart via the D-Bus session bus without a main loop and the spam.sh (attached to the bug) is run.