1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <unistd.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <signal.h>
31 #include <stddef.h>
32 #include <ltdl.h>
33 #include <limits.h>
34 #include <locale.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37
38 #ifdef HAVE_SYS_MMAN_H
39 #include <sys/mman.h>
40 #endif
41
42 #ifdef HAVE_PWD_H
43 #include <pwd.h>
44 #endif
45 #ifdef HAVE_GRP_H
46 #include <grp.h>
47 #endif
48
49 #ifdef HAVE_LIBWRAP
50 #include <syslog.h>
51 #include <tcpd.h>
52 #endif
53
54 #ifdef HAVE_DBUS
55 #include <dbus/dbus.h>
56 #endif
57
58 #ifdef HAVE_SYSTEMD_DAEMON
59 #include <systemd/sd-daemon.h>
60 #endif
61
62 #ifdef HAVE_WINDOWS_H
63 #include <windows.h>
64 #include <aclapi.h>
65 #include <sddl.h>
66 #endif
67
68 #include <pulse/client-conf.h>
69 #include <pulse/mainloop.h>
70 #include <pulse/mainloop-signal.h>
71 #include <pulse/timeval.h>
72 #include <pulse/xmalloc.h>
73
74 #include <pulsecore/i18n.h>
75 #include <pulsecore/lock-autospawn.h>
76 #include <pulsecore/socket.h>
77 #include <pulsecore/core-error.h>
78 #include <pulsecore/core-rtclock.h>
79 #include <pulsecore/core-scache.h>
80 #include <pulsecore/core.h>
81 #include <pulsecore/module.h>
82 #include <pulsecore/cli-command.h>
83 #include <pulsecore/log.h>
84 #include <pulsecore/core-util.h>
85 #include <pulsecore/sioman.h>
86 #include <pulsecore/cli-text.h>
87 #include <pulsecore/pid.h>
88 #include <pulsecore/random.h>
89 #include <pulsecore/macro.h>
90 #include <pulsecore/shm.h>
91 #include <pulsecore/memtrap.h>
92 #include <pulsecore/strlist.h>
93 #ifdef HAVE_DBUS
94 #include <pulsecore/dbus-shared.h>
95 #endif
96 #include <pulsecore/cpu.h>
97
98 #include "cmdline.h"
99 #include "cpulimit.h"
100 #include "daemon-conf.h"
101 #include "dumpmodules.h"
102 #include "caps.h"
103 #include "ltdl-bind-now.h"
104 #include "server-lookup.h"
105
106 #ifdef __cplusplus
107 #if __cplusplus
108 extern "C" {
109 #endif
110 #endif /* End of #ifdef __cplusplus */
111 #ifdef DISABLE_LIBTOOL_PRELOAD
112 /* FIXME: work around a libtool bug by making sure we have 2 elements. Bug has
113 * been reported: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=29576 */
114 LT_DLSYM_CONST lt_dlsymlist lt_preloaded_symbols[] = {
115 { "@PROGRAM@", NULL },
116 { NULL, NULL }
117 };
118 #endif
119
120 #ifdef HAVE_LIBWRAP
121 /* Only one instance of these variables */
122 int allow_severity = LOG_INFO;
123 int deny_severity = LOG_WARNING;
124 #endif
125
126 #ifdef HAVE_OSS_WRAPPER
127 /* padsp looks for this symbol in the running process and disables
128 * itself if it finds it and it is set to 7 (which is actually a bit
129 * mask). For details see padsp. */
130 int __padsp_disabled__ = 7;
131 #endif
132
signal_callback(pa_mainloop_api * m,pa_signal_event * e,int sig,void * userdata)133 static void signal_callback(pa_mainloop_api* m, pa_signal_event *e, int sig, void *userdata) {
134 pa_module *module = NULL;
135
136 pa_log_info("Got signal %s.", pa_sig2str(sig));
137
138 switch (sig) {
139 #ifdef SIGUSR1
140 case SIGUSR1:
141 pa_module_load(&module, userdata, "module-cli", NULL);
142 break;
143 #endif
144
145 #ifdef SIGUSR2
146 case SIGUSR2:
147 pa_module_load(&module, userdata, "module-cli-protocol-unix", NULL);
148 break;
149 #endif
150
151 #ifdef SIGHUP
152 case SIGHUP: {
153 char *c = pa_full_status_string(userdata);
154 pa_log_notice("%s", c);
155 pa_xfree(c);
156 return;
157 }
158 #endif
159
160 case SIGINT:
161 case SIGTERM:
162 default:
163 pa_log_info("Do nothing.");
164 break;
165 }
166 }
167
168 #if defined(OS_IS_WIN32)
169
change_user(void)170 static int change_user(void) {
171 pa_log_info("Overriding system runtime/config base dir to '%s'.", pa_win32_get_system_appdata());
172
173 /* On other platforms, these paths are compiled into PulseAudio. This isn't
174 * suitable on Windows. Firstly, Windows doesn't follow the FHS or use Unix
175 * paths and the build system can't handle Windows-style paths properly.
176 * Secondly, the idiomatic location for a service's state and shared data is
177 * ProgramData, and the location of special folders is dynamic on Windows.
178 * Also, this method of handling paths is consistent with how they are
179 * handled on Windows in other parts of PA. Note that this is only needed
180 * in system-wide mode since paths in user instances are already handled
181 * properly.
182 */
183
184 char *run_path = pa_sprintf_malloc("%s" PA_PATH_SEP "run", pa_win32_get_system_appdata());
185 char *lib_path = pa_sprintf_malloc("%s" PA_PATH_SEP "lib", pa_win32_get_system_appdata());
186
187 /* https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings */
188 /* https://docs.microsoft.com/en-us/windows/win32/secauthz/modifying-the-acls-of-an-object-in-c-- */
189 /* https://docs.microsoft.com/en-us/windows/win32/api/sddl/nf-sddl-convertstringsecuritydescriptortosecuritydescriptora */
190 {
191 mkdir(run_path);
192 PSECURITY_DESCRIPTOR sd;
193 if (ConvertStringSecurityDescriptorToSecurityDescriptorA(
194 "D:PAI" /* DACL, disable inheritance from parent, enable propagation to children */
195 "(A;OICI;FA;;;SY)" /* give system full access */
196 "(A;OICI;FA;;;CO)" /* give owner full access */
197 "(A;OICI;FA;;;BA)" /* give administrators full access */
198 "(A;OICI;0x1200a9;;;WD)", /* give everyone read/write/execute access */
199 SDDL_REVISION_1, &sd, NULL
200 )) {
201 PACL acl;
202 BOOL acl_present, acl_default;
203 if (GetSecurityDescriptorDacl(sd, &acl_present, &acl, &acl_default)) {
204 if (SetNamedSecurityInfo(run_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, acl, NULL) != ERROR_SUCCESS) {
205 pa_log_warn("Failed to set DACL for runtime dir: failed to apply DACL: error %lu.", GetLastError());
206 }
207 LocalFree(acl);
208 } else {
209 pa_log_warn("Failed to set DACL for runtime dir: failed to get security descriptor DACL: error %lu.", GetLastError());
210 }
211 } else {
212 pa_log_warn("Failed to set DACL for runtime dir: failed to parse security descriptor: error %lu.", GetLastError());
213 }
214 }
215 {
216 mkdir(lib_path);
217 PSECURITY_DESCRIPTOR sd;
218 if (ConvertStringSecurityDescriptorToSecurityDescriptorA(
219 "D:PAI" /* DACL, disable inheritance from parent, enable propagation to children */
220 "(A;OICI;FA;;;SY)" /* give system full access */
221 "(A;OICI;FA;;;CO)" /* give owner full access */
222 "(A;OICI;FA;;;BA)", /* give administrators full access */
223 SDDL_REVISION_1, &sd, NULL
224 )) {
225 PACL acl;
226 BOOL acl_present, acl_default;
227 if (GetSecurityDescriptorDacl(sd, &acl_present, &acl, &acl_default)) {
228 if (SetNamedSecurityInfo(lib_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, acl, NULL) != ERROR_SUCCESS) {
229 pa_log_warn("Failed to set DACL for lib dir: failed to apply DACL: error %lu.", GetLastError());
230 }
231 LocalFree(acl);
232 } else {
233 pa_log_warn("Failed to set DACL for lib dir: failed to get security descriptor DACL: error %lu.", GetLastError());
234 }
235 } else {
236 pa_log_warn("Failed to set DACL for lib dir: failed to parse security descriptor: error %lu.", GetLastError());
237 }
238 }
239
240 pa_set_env("HOME", run_path);
241 if (!getenv("PULSE_RUNTIME_PATH"))
242 pa_set_env("PULSE_RUNTIME_PATH", run_path);
243 if (!getenv("PULSE_CONFIG_PATH"))
244 pa_set_env("PULSE_CONFIG_PATH", lib_path);
245 if (!getenv("PULSE_STATE_PATH"))
246 pa_set_env("PULSE_STATE_PATH", lib_path);
247
248 pa_xfree(run_path);
249 pa_xfree(lib_path);
250
251 pa_log_info("Not changing user for system instance on Windows.");
252 return 0;
253 }
254
255 #elif defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
256
change_user(void)257 static int change_user(void) {
258 struct passwd *pw;
259 struct group * gr;
260 int r;
261
262 /* This function is called only in system-wide mode. It creates a
263 * runtime dir in /var/run/ with proper UID/GID and drops privs
264 * afterwards. */
265
266 if (!(pw = getpwnam(PA_SYSTEM_USER))) {
267 pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER);
268 return -1;
269 }
270
271 if (!(gr = getgrnam(PA_SYSTEM_GROUP))) {
272 pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP);
273 return -1;
274 }
275
276 pa_log_info("Found user '%s' (UID %lu) and group '%s' (GID %lu).",
277 PA_SYSTEM_USER, (unsigned long) pw->pw_uid,
278 PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid);
279
280 if (pw->pw_gid != gr->gr_gid) {
281 pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP);
282 return -1;
283 }
284
285 if (!pa_streq(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH))
286 pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
287
288 if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid, true) < 0) {
289 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
290 return -1;
291 }
292
293 if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid, true) < 0) {
294 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
295 return -1;
296 }
297
298 /* We don't create the config dir here, because we don't need to write to it */
299
300 if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) {
301 pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno));
302 return -1;
303 }
304
305 #if defined(HAVE_SETRESGID)
306 r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid);
307 #elif defined(HAVE_SETEGID)
308 if ((r = setgid(gr->gr_gid)) >= 0)
309 r = setegid(gr->gr_gid);
310 #elif defined(HAVE_SETREGID)
311 r = setregid(gr->gr_gid, gr->gr_gid);
312 #else
313 #error "No API to drop privileges"
314 #endif
315
316 if (r < 0) {
317 pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno));
318 return -1;
319 }
320
321 #if defined(HAVE_SETRESUID)
322 r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
323 #elif defined(HAVE_SETEUID)
324 if ((r = setuid(pw->pw_uid)) >= 0)
325 r = seteuid(pw->pw_uid);
326 #elif defined(HAVE_SETREUID)
327 r = setreuid(pw->pw_uid, pw->pw_uid);
328 #else
329 #error "No API to drop privileges"
330 #endif
331
332 if (r < 0) {
333 pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno));
334 return -1;
335 }
336
337 pa_drop_caps();
338
339 pa_set_env("USER", PA_SYSTEM_USER);
340 pa_set_env("USERNAME", PA_SYSTEM_USER);
341 pa_set_env("LOGNAME", PA_SYSTEM_USER);
342 pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH);
343
344 /* Relevant for pa_runtime_path() */
345 if (!getenv("PULSE_RUNTIME_PATH"))
346 pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH);
347
348 if (!getenv("PULSE_CONFIG_PATH"))
349 pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH);
350
351 if (!getenv("PULSE_STATE_PATH"))
352 pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
353
354 pa_log_info("Successfully changed user to \"" PA_SYSTEM_USER "\".");
355
356 return 0;
357 }
358
359 #else /* HAVE_PWD_H && HAVE_GRP_H */
360
change_user(void)361 static int change_user(void) {
362 pa_log(_("System wide mode unsupported on this platform."));
363 return -1;
364 }
365
366 #endif /* HAVE_PWD_H && HAVE_GRP_H */
367
368 #ifdef HAVE_SYS_RESOURCE_H
369
set_one_rlimit(const pa_rlimit * r,int resource,const char * name)370 static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
371 struct rlimit rl;
372 pa_assert(r);
373
374 if (!r->is_set)
375 return 0;
376
377 rl.rlim_cur = rl.rlim_max = r->value;
378
379 if (setrlimit(resource, &rl) < 0) {
380 pa_log_info("setrlimit(%s, (%u, %u)) failed: %s", name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
381 return -1;
382 }
383
384 return 0;
385 }
386
set_all_rlimits(const pa_daemon_conf * conf)387 static void set_all_rlimits(const pa_daemon_conf *conf) {
388 set_one_rlimit(&conf->rlimit_fsize, RLIMIT_FSIZE, "RLIMIT_FSIZE");
389 set_one_rlimit(&conf->rlimit_data, RLIMIT_DATA, "RLIMIT_DATA");
390 set_one_rlimit(&conf->rlimit_stack, RLIMIT_STACK, "RLIMIT_STACK");
391 set_one_rlimit(&conf->rlimit_core, RLIMIT_CORE, "RLIMIT_CORE");
392 #ifdef RLIMIT_RSS
393 set_one_rlimit(&conf->rlimit_rss, RLIMIT_RSS, "RLIMIT_RSS");
394 #endif
395 #ifdef RLIMIT_NPROC
396 set_one_rlimit(&conf->rlimit_nproc, RLIMIT_NPROC, "RLIMIT_NPROC");
397 #endif
398 #ifdef RLIMIT_NOFILE
399 set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
400 #endif
401 #ifdef RLIMIT_MEMLOCK
402 set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
403 #endif
404 #ifdef RLIMIT_AS
405 set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
406 #endif
407 #ifdef RLIMIT_LOCKS
408 set_one_rlimit(&conf->rlimit_locks, RLIMIT_LOCKS, "RLIMIT_LOCKS");
409 #endif
410 #ifdef RLIMIT_SIGPENDING
411 set_one_rlimit(&conf->rlimit_sigpending, RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING");
412 #endif
413 #ifdef RLIMIT_MSGQUEUE
414 set_one_rlimit(&conf->rlimit_msgqueue, RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE");
415 #endif
416 #ifdef RLIMIT_NICE
417 set_one_rlimit(&conf->rlimit_nice, RLIMIT_NICE, "RLIMIT_NICE");
418 #endif
419 #ifdef RLIMIT_RTPRIO
420 set_one_rlimit(&conf->rlimit_rtprio, RLIMIT_RTPRIO, "RLIMIT_RTPRIO");
421 #endif
422 #ifdef RLIMIT_RTTIME
423 set_one_rlimit(&conf->rlimit_rttime, RLIMIT_RTTIME, "RLIMIT_RTTIME");
424 #endif
425 }
426 #endif
427
check_configured_address(void)428 static char *check_configured_address(void) {
429 char *default_server = NULL;
430 pa_client_conf *c = pa_client_conf_new();
431
432 pa_client_conf_load(c, true, true);
433
434 if (c->default_server && *c->default_server)
435 default_server = pa_xstrdup(c->default_server);
436
437 pa_client_conf_free(c);
438
439 return default_server;
440 }
441
442 #ifdef HAVE_DBUS
register_dbus_name(pa_core * c,DBusBusType bus,const char * name)443 static pa_dbus_connection *register_dbus_name(pa_core *c, DBusBusType bus, const char* name) {
444 DBusError error;
445 pa_dbus_connection *conn;
446
447 dbus_error_init(&error);
448
449 if (!(conn = pa_dbus_bus_get(c, bus, &error)) || dbus_error_is_set(&error)) {
450 pa_log_warn("Unable to contact D-Bus: %s: %s", error.name, error.message);
451 goto fail;
452 }
453
454 if (dbus_bus_request_name(pa_dbus_connection_get(conn), name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
455 pa_log_debug("Got %s!", name);
456 return conn;
457 }
458
459 if (dbus_error_is_set(&error))
460 pa_log_error("Failed to acquire %s: %s: %s", name, error.name, error.message);
461 else
462 pa_log_error("D-Bus name %s already taken.", name);
463
464 /* PA cannot be started twice by the same user and hence we can
465 * ignore mostly the case that a name is already taken. */
466
467 fail:
468 if (conn)
469 pa_dbus_connection_unref(conn);
470
471 dbus_error_free(&error);
472 return NULL;
473 }
474 #endif
475
change_permission(const char * path,mode_t mode)476 void change_permission(const char *path, mode_t mode) {
477 if (!path) {
478 pa_log_error("chmod empty path");
479 return;
480 }
481
482 if (chmod(path, mode)) {
483 pa_log_error("chmod failed for directory: %s", path);
484 }
485 }
486
487 #ifdef OS_IS_WIN32
488 #define SVC_NAME "PulseAudio"
489 static bool is_svc = true;
490 static int argc;
491 static char **argv;
492 static int real_main(int s_argc, char *s_argv[]);
493 static SERVICE_STATUS_HANDLE svc_status;
494
svc_callback(DWORD ctl,DWORD evt,LPVOID data,LPVOID userdata)495 DWORD svc_callback(DWORD ctl, DWORD evt, LPVOID data, LPVOID userdata) {
496 pa_mainloop **m = userdata;
497 switch (ctl) {
498 case SERVICE_CONTROL_STOP:
499 case SERVICE_CONTROL_SHUTDOWN:
500 if (m) {
501 pa_log_info("Exiting.");
502 pa_mainloop_get_api(*m)->quit(pa_mainloop_get_api(*m), 0);
503 }
504 return NO_ERROR;
505 case SERVICE_CONTROL_INTERROGATE:
506 return NO_ERROR;
507 }
508 return ERROR_CALL_NOT_IMPLEMENTED;
509 }
510
ohos_pa_main(int argc,char * argv[])511 int ohos_pa_main(int argc, char *argv[]) {
512 argc = p_argc;
513 argv = p_argv;
514 if (StartServiceCtrlDispatcherA((SERVICE_TABLE_ENTRYA[]){
515 {SVC_NAME, (LPSERVICE_MAIN_FUNCTIONA) real_main},
516 {0},
517 })) return 0;
518 is_svc = false;
519 return real_main(0, NULL);
520 }
521
real_main(int s_argc,char * s_argv[])522 static int real_main(int s_argc, char *s_argv[]) {
523 #else
524 int ohos_pa_main(int argc, char *argv[]) {
525 #endif
526 pa_core *c = NULL;
527 pa_strbuf *buf = NULL;
528 pa_daemon_conf *conf = NULL;
529 pa_mainloop *mainloop = NULL;
530 char *s;
531 char *configured_address;
532 int r = 0, retval = 1, d = 0;
533 bool valid_pid_file = false;
534 #ifdef HAVE_NO_OHOS
535 bool ltdl_init = false;
536 #endif
537 int n_fds = 0, *passed_fds = NULL;
538 const char *e;
539 #ifdef HAVE_FORK
540 int daemon_pipe[2] = { -1, -1 };
541 int daemon_pipe2[2] = { -1, -1 };
542 #endif
543 int autospawn_fd = -1;
544 bool autospawn_locked = false;
545 #ifdef HAVE_DBUS
546 pa_dbusobj_server_lookup *server_lookup = NULL; /* /org/pulseaudio/server_lookup */
547 pa_dbus_connection *lookup_service_bus = NULL; /* Always the user bus. */
548 pa_dbus_connection *server_bus = NULL; /* The bus where we reserve org.pulseaudio.Server, either the user or the system bus. */
549 bool start_server;
550 #endif
551
552 #ifdef OS_IS_WIN32
553 if (is_svc && !(svc_status = RegisterServiceCtrlHandlerExA(SVC_NAME, (LPHANDLER_FUNCTION_EX) svc_callback, &mainloop))) {
554 pa_log("Failed to register service control handler.");
555 goto finish;
556 }
557
558 if (is_svc) {
559 SetServiceStatus(svc_status, &(SERVICE_STATUS){
560 .dwServiceType = SERVICE_WIN32,
561 .dwCurrentState = SERVICE_START_PENDING,
562 .dwControlsAccepted = 0,
563 .dwWin32ExitCode = NO_ERROR,
564 .dwWaitHint = 3000,
565 });
566 }
567 #endif
568
569 pa_log_set_ident("pulseaudio");
570 pa_log_set_level(PA_LOG_NOTICE);
571 pa_log_set_flags(PA_LOG_COLORS|PA_LOG_PRINT_FILE|PA_LOG_PRINT_LEVEL, PA_LOG_RESET);
572
573 #if !defined(HAVE_BIND_NOW) && defined(__linux__) && defined(__OPTIMIZE__)
574 /*
575 Disable lazy relocations to make usage of external libraries
576 more deterministic for our RT threads. We abuse __OPTIMIZE__ as
577 a check whether we are a debug build or not. This all is
578 admittedly a bit snake-oilish.
579 */
580
581 if (!getenv("LD_BIND_NOW")) {
582 char *rp;
583 char *canonical_rp;
584
585 /* We have to execute ourselves, because the libc caches the
586 * value of $LD_BIND_NOW on initialization. */
587
588 pa_set_env("LD_BIND_NOW", "1");
589
590 if ((canonical_rp = pa_realpath(PA_BINARY))) {
591
592 if ((rp = pa_readlink("/proc/self/exe"))) {
593
594 if (pa_streq(rp, canonical_rp))
595 pa_assert_se(execv(rp, argv) == 0);
596 else
597 pa_log_warn("/proc/self/exe does not point to %s, cannot self execute. Are you playing games?", canonical_rp);
598
599 pa_xfree(rp);
600
601 } else
602 pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
603
604 pa_xfree(canonical_rp);
605
606 } else
607 pa_log_warn("Couldn't canonicalize binary path, cannot self execute.");
608 }
609 #endif
610
611 #ifdef HAVE_SYSTEMD_DAEMON
612 n_fds = sd_listen_fds(0);
613 if (n_fds > 0) {
614 int i = n_fds;
615
616 passed_fds = pa_xnew(int, n_fds+2);
617 passed_fds[n_fds] = passed_fds[n_fds+1] = -1;
618 while (i--)
619 passed_fds[i] = SD_LISTEN_FDS_START + i;
620 }
621 #endif
622
623 if (!passed_fds) {
624 n_fds = 0;
625 passed_fds = pa_xnew(int, 2);
626 passed_fds[0] = passed_fds[1] = -1;
627 }
628
629 if ((e = getenv("PULSE_PASSED_FD"))) {
630 int passed_fd = atoi(e);
631 if (passed_fd > 2)
632 passed_fds[n_fds] = passed_fd;
633 }
634
635 /* We might be autospawned, in which case have no idea in which
636 * context we have been started. Let's cleanup our execution
637 * context as good as possible */
638
639 pa_reset_personality();
640 pa_drop_root();
641 #ifdef HAVE_NO_OHOS
642 pa_close_allv(passed_fds);
643 pa_xfree(passed_fds);
644 #endif
645
646 /* Load locale from the environment. */
647 setlocale(LC_ALL, "");
648
649 /* Set LC_NUMERIC to C so that floating point strings are consistently
650 * formatted and parsed across locales. */
651 setlocale(LC_NUMERIC, "C");
652
653 pa_init_i18n();
654
655 conf = pa_daemon_conf_new();
656 if (!conf) {
657 pa_log(_("Failed to create daemon conf."));
658 goto finish;
659 }
660
661 if (pa_daemon_conf_load(conf, NULL) < 0)
662 goto finish;
663
664 if (pa_daemon_conf_env(conf) < 0)
665 goto finish;
666
667 if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
668 pa_log(_("Failed to parse command line."));
669 goto finish;
670 }
671
672 if (conf->log_target)
673 pa_log_set_target(conf->log_target);
674 else {
675 pa_log_target target = { .type = PA_LOG_STDERR, .file = NULL };
676 pa_log_set_target(&target);
677 }
678
679 pa_log_set_level(conf->log_level);
680 if (conf->log_meta)
681 pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
682 if (conf->log_time)
683 pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
684 pa_log_set_show_backtrace(conf->log_backtrace);
685
686 #ifdef HAVE_DBUS
687 /* conf->system_instance and conf->local_server_type control almost the
688 * same thing; make them agree about what is requested. */
689 switch (conf->local_server_type) {
690 case PA_SERVER_TYPE_UNSET:
691 conf->local_server_type = conf->system_instance ? PA_SERVER_TYPE_SYSTEM : PA_SERVER_TYPE_USER;
692 break;
693 case PA_SERVER_TYPE_USER:
694 case PA_SERVER_TYPE_NONE:
695 conf->system_instance = false;
696 break;
697 case PA_SERVER_TYPE_SYSTEM:
698 conf->system_instance = true;
699 break;
700 default:
701 pa_assert_not_reached();
702 }
703
704 start_server = conf->local_server_type == PA_SERVER_TYPE_USER || (getuid() == 0 && conf->local_server_type == PA_SERVER_TYPE_SYSTEM);
705
706 if (!start_server && conf->local_server_type == PA_SERVER_TYPE_SYSTEM) {
707 pa_log_notice(_("System mode refused for non-root user. Only starting the D-Bus server lookup service."));
708 conf->system_instance = false;
709 }
710 #endif
711
712 #ifdef HAVE_NO_OHOS
713 LTDL_SET_PRELOADED_SYMBOLS();
714 pa_ltdl_init();
715 ltdl_init = true;
716
717 if (conf->dl_search_path)
718 lt_dlsetsearchpath(conf->dl_search_path);
719 #endif
720
721 #ifdef OS_IS_WIN32
722 {
723 WSADATA data;
724 WSAStartup(MAKEWORD(2, 0), &data);
725 }
726 #endif
727
728 pa_random_seed();
729
730 switch (conf->cmd) {
731 case PA_CMD_DUMP_MODULES:
732 #ifdef HAVE_NO_OHOS
733 pa_dump_modules(conf, argc-d, argv+d);
734 #endif
735 retval = 0;
736 goto finish;
737
738 case PA_CMD_DUMP_CONF: {
739
740 if (d < argc) {
741 pa_log("Too many arguments.");
742 goto finish;
743 }
744
745 s = pa_daemon_conf_dump(conf);
746 fputs(s, stdout);
747 pa_xfree(s);
748 retval = 0;
749 goto finish;
750 }
751
752 case PA_CMD_DUMP_RESAMPLE_METHODS: {
753 int i;
754
755 if (d < argc) {
756 pa_log("Too many arguments.");
757 goto finish;
758 }
759
760 for (i = 0; i < PA_RESAMPLER_MAX; i++)
761 if (pa_resample_method_supported(i))
762 printf("%s\n", pa_resample_method_to_string(i));
763
764 retval = 0;
765 goto finish;
766 }
767
768 case PA_CMD_HELP :
769 pa_cmdline_help(argv[0]);
770 retval = 0;
771 goto finish;
772
773 case PA_CMD_VERSION :
774
775 if (d < argc) {
776 pa_log("Too many arguments.");
777 goto finish;
778 }
779
780 printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
781 retval = 0;
782 goto finish;
783
784 case PA_CMD_CHECK: {
785 pid_t pid;
786
787 if (d < argc) {
788 pa_log("Too many arguments.");
789 goto finish;
790 }
791
792 if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
793 pa_log_info("Daemon not running");
794 else {
795 pa_log_info("Daemon running as PID %u", pid);
796 retval = 0;
797 }
798
799 goto finish;
800
801 }
802 case PA_CMD_KILL:
803
804 if (d < argc) {
805 pa_log("Too many arguments.");
806 goto finish;
807 }
808
809 if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
810 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
811 else
812 retval = 0;
813
814 goto finish;
815
816 case PA_CMD_CLEANUP_SHM:
817
818 if (d < argc) {
819 pa_log("Too many arguments.");
820 goto finish;
821 }
822
823 if (pa_shm_cleanup() >= 0)
824 retval = 0;
825
826 goto finish;
827
828 default:
829 pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
830 }
831
832 if (d < argc) {
833 pa_log("Too many arguments.");
834 goto finish;
835 }
836
837 #ifdef HAVE_GETUID
838 if (getuid() == 0 && !conf->system_instance)
839 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
840 #ifndef HAVE_DBUS /* A similar, only a notice worthy check was done earlier, if D-Bus is enabled. */
841 else if (getuid() != 0 && conf->system_instance) {
842 pa_log(_("Root privileges required."));
843 goto finish;
844 }
845 #endif
846 #endif /* HAVE_GETUID */
847
848 if (conf->cmd == PA_CMD_START && conf->system_instance) {
849 pa_log(_("--start not supported for system instances."));
850 goto finish;
851 }
852
853 if (conf->cmd == PA_CMD_START && (configured_address = check_configured_address())) {
854 /* There is an server address in our config, but where did it come from?
855 * By default a standard X11 login will load module-x11-publish which will
856 * inject PULSE_SERVER X11 property. If the PA daemon crashes, we will end
857 * up hitting this code path. So we have to check to see if our configured_address
858 * is the same as the value that would go into this property so that we can
859 * recover (i.e. autospawn) from a crash.
860 */
861 char *ufn;
862 bool start_anyway = false;
863
864 if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
865 char *id;
866
867 if ((id = pa_machine_id())) {
868 pa_strlist *server_list;
869 char formatted_ufn[256];
870
871 pa_snprintf(formatted_ufn, sizeof(formatted_ufn), "{%s}unix:%s", id, ufn);
872 pa_xfree(id);
873
874 if ((server_list = pa_strlist_parse(configured_address))) {
875 char *u = NULL;
876
877 /* We only need to check the first server */
878 server_list = pa_strlist_pop(server_list, &u);
879 pa_strlist_free(server_list);
880
881 start_anyway = (u && pa_streq(formatted_ufn, u));
882 pa_xfree(u);
883 }
884 }
885 pa_xfree(ufn);
886 }
887
888 if (!start_anyway) {
889 pa_log_notice(_("User-configured server at %s, refusing to start/autospawn."), configured_address);
890 pa_xfree(configured_address);
891 retval = 0;
892 goto finish;
893 }
894
895 pa_log_notice(_("User-configured server at %s, which appears to be local. Probing deeper."), configured_address);
896 pa_xfree(configured_address);
897 }
898
899 if (conf->system_instance && !conf->disallow_exit)
900 pa_log_warn(_("Running in system mode, but --disallow-exit not set."));
901
902 if (conf->system_instance && !conf->disallow_module_loading)
903 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set."));
904
905 if (conf->system_instance && !conf->disable_shm) {
906 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode."));
907 conf->disable_shm = true;
908 }
909
910 if (conf->system_instance && conf->exit_idle_time >= 0) {
911 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time."));
912 conf->exit_idle_time = -1;
913 }
914
915 if (conf->cmd == PA_CMD_START) {
916 /* If we shall start PA only when it is not running yet, we
917 * first take the autospawn lock to make things
918 * synchronous. */
919
920 /* This locking and thread synchronisation code doesn't work reliably
921 * on kFreeBSD (Debian bug #705435), or in upstream FreeBSD ports
922 * (bug reference: ports/128947, patched in SVN r231972). */
923 #if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
924 if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
925 pa_log("Failed to initialize autospawn lock");
926 goto finish;
927 }
928
929 if ((pa_autospawn_lock_acquire(true) < 0)) {
930 pa_log("Failed to acquire autospawn lock");
931 goto finish;
932 }
933
934 autospawn_locked = true;
935 #endif
936 }
937
938 if (conf->daemonize) {
939 #ifdef HAVE_FORK
940 pid_t child;
941 #endif
942
943 if (pa_stdio_acquire() < 0) {
944 pa_log(_("Failed to acquire stdio."));
945 goto finish;
946 }
947
948 #ifdef HAVE_FORK
949 if (pipe(daemon_pipe) < 0) {
950 pa_log(_("pipe() failed: %s"), pa_cstrerror(errno));
951 goto finish;
952 }
953
954 if ((child = fork()) < 0) {
955 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
956 pa_close_pipe(daemon_pipe);
957 goto finish;
958 }
959
960 if (child != 0) {
961 ssize_t n;
962 /* Father */
963
964 pa_assert_se(pa_close(daemon_pipe[1]) == 0);
965 daemon_pipe[1] = -1;
966
967 if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
968
969 if (n < 0)
970 pa_log(_("read() failed: %s"), pa_cstrerror(errno));
971
972 retval = 1;
973 }
974
975 if (retval)
976 pa_log(_("Daemon startup failed."));
977 else
978 pa_log_info("Daemon startup successful.");
979
980 goto finish;
981 }
982
983 if (autospawn_fd >= 0) {
984 /* The lock file is unlocked from the parent, so we need
985 * to close it in the child */
986
987 pa_autospawn_lock_release();
988 pa_autospawn_lock_done(true);
989
990 autospawn_locked = false;
991 autospawn_fd = -1;
992 }
993
994 pa_assert_se(pa_close(daemon_pipe[0]) == 0);
995 daemon_pipe[0] = -1;
996 #endif
997
998 if (!conf->log_target) {
999 #ifdef HAVE_SYSTEMD_JOURNAL
1000 pa_log_target target = { .type = PA_LOG_JOURNAL, .file = NULL };
1001 #else
1002 pa_log_target target = { .type = PA_LOG_SYSLOG, .file = NULL };
1003 #endif
1004 pa_log_set_target(&target);
1005 }
1006
1007 #ifdef HAVE_SETSID
1008 if (setsid() < 0) {
1009 pa_log(_("setsid() failed: %s"), pa_cstrerror(errno));
1010 goto finish;
1011 }
1012 #endif
1013
1014 #ifdef HAVE_FORK
1015 /* We now are a session and process group leader. Let's fork
1016 * again and let the father die, so that we'll become a
1017 * process that can never acquire a TTY again, in a session and
1018 * process group without leader */
1019
1020 if (pipe(daemon_pipe2) < 0) {
1021 pa_log(_("pipe() failed: %s"), pa_cstrerror(errno));
1022 goto finish;
1023 }
1024
1025 if ((child = fork()) < 0) {
1026 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
1027 pa_close_pipe(daemon_pipe2);
1028 goto finish;
1029 }
1030
1031 if (child != 0) {
1032 ssize_t n;
1033 /* Father */
1034
1035 pa_assert_se(pa_close(daemon_pipe2[1]) == 0);
1036 daemon_pipe2[1] = -1;
1037
1038 if ((n = pa_loop_read(daemon_pipe2[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
1039
1040 if (n < 0)
1041 pa_log(_("read() failed: %s"), pa_cstrerror(errno));
1042
1043 retval = 1;
1044 }
1045
1046 /* We now have to take care of signalling the first fork with
1047 * the return value we've received from this fork... */
1048 pa_assert(daemon_pipe[1] >= 0);
1049
1050 pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
1051 pa_close(daemon_pipe[1]);
1052 daemon_pipe[1] = -1;
1053
1054 goto finish;
1055 }
1056
1057 pa_assert_se(pa_close(daemon_pipe2[0]) == 0);
1058 daemon_pipe2[0] = -1;
1059
1060 /* We no longer need the (first) daemon_pipe as it's handled in our child above */
1061 pa_close_pipe(daemon_pipe);
1062 #endif
1063
1064 #ifdef SIGTTOU
1065 signal(SIGTTOU, SIG_IGN);
1066 #endif
1067 #ifdef SIGTTIN
1068 signal(SIGTTIN, SIG_IGN);
1069 #endif
1070 #ifdef SIGTSTP
1071 signal(SIGTSTP, SIG_IGN);
1072 #endif
1073
1074 pa_nullify_stdfds();
1075 }
1076
1077 pa_set_env_and_record("PULSE_INTERNAL", "1");
1078 pa_assert_se(chdir("/") == 0);
1079 #ifdef HAVE_NO_OHOS
1080 umask(0077);
1081 #endif
1082 #ifdef HAVE_SYS_RESOURCE_H
1083 set_all_rlimits(conf);
1084 #endif
1085 pa_rtclock_hrtimer_enable();
1086
1087 #ifdef HAVE_NO_OHOS
1088 if (conf->high_priority)
1089 pa_raise_priority(conf->nice_level);
1090 #endif
1091 if (conf->system_instance)
1092 if (change_user() < 0)
1093 goto finish;
1094
1095 pa_set_env_and_record("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
1096
1097 pa_log_info("This is PulseAudio %s", PACKAGE_VERSION);
1098 pa_log_debug("Compilation CFLAGS: %s", PA_CFLAGS);
1099
1100 #ifdef HAVE_LIBSAMPLERATE
1101 pa_log_warn("Compiled with DEPRECATED libsamplerate support!");
1102 #endif
1103
1104 s = pa_uname_string();
1105 pa_log_debug("Running on host: %s", s);
1106 pa_xfree(s);
1107
1108 pa_log_debug("Found %u CPUs.", pa_ncpus());
1109
1110 pa_log_info("Page size is %zu bytes", pa_page_size());
1111
1112 #ifdef HAVE_VALGRIND_MEMCHECK_H
1113 pa_log_debug("Compiled with Valgrind support: yes");
1114 #else
1115 pa_log_debug("Compiled with Valgrind support: no");
1116 #endif
1117
1118 pa_log_debug("Running in valgrind mode: %s", pa_yes_no(pa_in_valgrind()));
1119
1120 pa_log_debug("Running in VM: %s", pa_yes_no(pa_running_in_vm()));
1121
1122 #ifdef HAVE_RUNNING_FROM_BUILD_TREE
1123 pa_log_debug("Running from build tree: %s", pa_yes_no(pa_run_from_build_tree()));
1124 #else
1125 pa_log_debug("Running from build tree: no");
1126 #endif
1127
1128 #ifdef __OPTIMIZE__
1129 pa_log_debug("Optimized build: yes");
1130 #else
1131 pa_log_debug("Optimized build: no");
1132 #endif
1133
1134 #ifdef NDEBUG
1135 pa_log_debug("NDEBUG defined, all asserts disabled.");
1136 #elif defined(FASTPATH)
1137 pa_log_debug("FASTPATH defined, only fast path asserts disabled.");
1138 #else
1139 pa_log_debug("All asserts enabled.");
1140 #endif
1141
1142 if (!(s = pa_machine_id())) {
1143 pa_log(_("Failed to get machine ID"));
1144 goto finish;
1145 }
1146 pa_log_info("Machine ID is %s.", s);
1147 pa_xfree(s);
1148
1149 if ((s = pa_session_id())) {
1150 pa_log_info("Session ID is %s.", s);
1151 pa_xfree(s);
1152 }
1153
1154 if (!(s = pa_get_runtime_dir()))
1155 goto finish;
1156 pa_log_info("Using runtime directory %s.", s);
1157 pa_xfree(s);
1158
1159 if (!(s = pa_get_state_dir()))
1160 goto finish;
1161 pa_log_info("Using state directory %s.", s);
1162 pa_xfree(s);
1163
1164 pa_log_info("Using modules directory %s.", conf->dl_search_path);
1165
1166 pa_log_info("Running in system mode: %s", pa_yes_no(pa_in_system_mode()));
1167
1168 #ifdef HAVE_NO_OHOS
1169 if (pa_in_system_mode())
1170 pa_log_warn(_("OK, so you are running PA in system mode. Please make sure that you actually do want to do that.\n"
1171 "Please read http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/WhatIsWrongWithSystemWide/ for an explanation why system mode is usually a bad idea."));
1172 #endif
1173 if (conf->use_pid_file) {
1174 int z;
1175 pa_pid_file_remove();
1176 if ((z = pa_pid_file_create("pulseaudio")) != 0) {
1177
1178 if (conf->cmd == PA_CMD_START && z > 0) {
1179 /* If we are already running and with are run in
1180 * --start mode, then let's return this as success. */
1181
1182 retval = 0;
1183 goto finish;
1184 }
1185
1186 pa_log(_("pa_pid_file_create() failed."));
1187 goto finish;
1188 }
1189
1190 valid_pid_file = true;
1191 }
1192
1193 pa_disable_sigpipe();
1194
1195 if (pa_rtclock_hrtimer())
1196 pa_log_info("System supports high resolution timers");
1197 else
1198 pa_log_info("System appears to not support high resolution timers");
1199
1200 if (conf->lock_memory) {
1201 #if defined(HAVE_SYS_MMAN_H) && !defined(__ANDROID__)
1202 if (mlockall(MCL_FUTURE) < 0)
1203 pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
1204 else
1205 pa_log_info("Successfully locked process into memory.");
1206 #else
1207 pa_log_warn("Memory locking requested but not supported on platform.");
1208 #endif
1209 }
1210
1211 pa_memtrap_install();
1212
1213 pa_assert_se(mainloop = pa_mainloop_new());
1214
1215 if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm,
1216 !conf->disable_shm && !conf->disable_memfd && pa_memfd_is_locally_supported(),
1217 conf->shm_size))) {
1218 pa_log(_("pa_core_new() failed."));
1219 goto finish;
1220 }
1221
1222 c->default_sample_spec = conf->default_sample_spec;
1223 c->alternate_sample_rate = conf->alternate_sample_rate;
1224 c->default_channel_map = conf->default_channel_map;
1225 c->default_n_fragments = conf->default_n_fragments;
1226 c->default_fragment_size_msec = conf->default_fragment_size_msec;
1227 c->deferred_volume_safety_margin_usec = conf->deferred_volume_safety_margin_usec;
1228 c->deferred_volume_extra_delay_usec = conf->deferred_volume_extra_delay_usec;
1229 c->lfe_crossover_freq = conf->lfe_crossover_freq;
1230 c->exit_idle_time = conf->exit_idle_time;
1231 c->scache_idle_time = conf->scache_idle_time;
1232 c->resample_method = conf->resample_method;
1233 c->realtime_priority = conf->realtime_priority;
1234 c->realtime_scheduling = conf->realtime_scheduling;
1235 c->avoid_resampling = conf->avoid_resampling;
1236 c->disable_remixing = conf->disable_remixing;
1237 c->remixing_use_all_sink_channels = conf->remixing_use_all_sink_channels;
1238 c->remixing_produce_lfe = conf->remixing_produce_lfe;
1239 c->remixing_consume_lfe = conf->remixing_consume_lfe;
1240 c->deferred_volume = conf->deferred_volume;
1241 c->running_as_daemon = conf->daemonize;
1242 c->disallow_exit = conf->disallow_exit;
1243 c->flat_volumes = conf->flat_volumes;
1244 c->rescue_streams = conf->rescue_streams;
1245 #ifdef HAVE_DBUS
1246 c->server_type = conf->local_server_type;
1247 #endif
1248
1249 pa_core_check_idle(c);
1250
1251 c->state = PA_CORE_RUNNING;
1252 #ifdef HAVE_CPU_INFO
1253 pa_cpu_init(&c->cpu_info);
1254 #endif
1255 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
1256 pa_signal_new(SIGINT, signal_callback, c);
1257 pa_signal_new(SIGTERM, signal_callback, c);
1258 #ifdef SIGUSR1
1259 pa_signal_new(SIGUSR1, signal_callback, c);
1260 #endif
1261 #ifdef SIGUSR2
1262 pa_signal_new(SIGUSR2, signal_callback, c);
1263 #endif
1264 #ifdef SIGHUP
1265 pa_signal_new(SIGHUP, signal_callback, c);
1266 #endif
1267
1268 if (!conf->no_cpu_limit)
1269 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
1270
1271 buf = pa_strbuf_new();
1272
1273 #ifdef HAVE_DBUS
1274 pa_assert_se(dbus_threads_init_default());
1275
1276 if (start_server)
1277 #endif
1278 {
1279 const char *command_source = NULL;
1280
1281 if (conf->load_default_script_file) {
1282 FILE *f;
1283
1284 if ((f = pa_daemon_conf_open_default_script_file(conf))) {
1285 r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
1286 fclose(f);
1287 command_source = pa_daemon_conf_get_default_script_file(conf);
1288 }
1289 }
1290
1291 if (r >= 0) {
1292 r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
1293 command_source = _("command line arguments");
1294 }
1295
1296 pa_log_error("%s", s = pa_strbuf_to_string_free(buf));
1297 pa_xfree(s);
1298
1299 if (r < 0 && conf->fail) {
1300 pa_log(_("Failed to initialize daemon due to errors while executing startup commands. Source of commands: %s"), command_source);
1301 goto finish;
1302 }
1303
1304 if (!c->modules || pa_idxset_size(c->modules) == 0) {
1305 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
1306 goto finish;
1307 }
1308 #ifdef HAVE_DBUS
1309 } else {
1310 /* When we just provide the D-Bus server lookup service, we don't want
1311 * any modules to be loaded. We haven't loaded any so far, so one might
1312 * think there's no way to contact the server, but receiving certain
1313 * signals could still cause modules to load. */
1314 conf->disallow_module_loading = true;
1315 #endif
1316 }
1317
1318 /* We completed the initial module loading, so let's disable it
1319 * from now on, if requested */
1320 c->disallow_module_loading = conf->disallow_module_loading;
1321
1322 #ifdef HAVE_DBUS
1323 if (!conf->system_instance) {
1324 if ((server_lookup = pa_dbusobj_server_lookup_new(c))) {
1325 if (!(lookup_service_bus = register_dbus_name(c, DBUS_BUS_SESSION, "org.PulseAudio1")))
1326 goto finish;
1327 }
1328 }
1329
1330 if (start_server)
1331 server_bus = register_dbus_name(c, conf->system_instance ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, "org.pulseaudio.Server");
1332 #endif
1333
1334 #ifdef HAVE_FORK
1335 if (daemon_pipe2[1] >= 0) {
1336 int ok = 0;
1337 pa_loop_write(daemon_pipe2[1], &ok, sizeof(ok), NULL);
1338 pa_close(daemon_pipe2[1]);
1339 daemon_pipe2[1] = -1;
1340 }
1341 #endif
1342 change_permission("/data/data/.pulse_dir", 0755);
1343 change_permission("/data/data/.pulse_dir/runtime", 0755);
1344 change_permission("/data/data/.pulse_dir/state", 0755);
1345 change_permission("/data/data/.pulse_dir/state/cookie", 0664);
1346 change_permission("/data/data/.pulse_dir/runtime/cli", 0660);
1347 change_permission("/data/data/.pulse_dir/runtime/native", 0666);
1348
1349 pa_log_info("Daemon startup complete.");
1350
1351 #ifdef HAVE_SYSTEMD_DAEMON
1352 sd_notify(0, "READY=1");
1353 #endif
1354
1355 #ifdef OS_IS_WIN32
1356 if (is_svc) {
1357 SetServiceStatus(svc_status, &(SERVICE_STATUS){
1358 .dwServiceType = SERVICE_WIN32,
1359 .dwCurrentState = SERVICE_RUNNING,
1360 .dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN,
1361 .dwWin32ExitCode = NO_ERROR,
1362 .dwWaitHint = 0,
1363 });
1364 }
1365 #endif
1366
1367 retval = 0;
1368 if (pa_mainloop_run(mainloop, &retval) < 0)
1369 goto finish;
1370
1371 pa_log_info("Daemon shutdown initiated.");
1372
1373 #ifdef HAVE_SYSTEMD_DAEMON
1374 sd_notify(0, "STOPPING=1");
1375 #endif
1376
1377 #ifdef OS_IS_WIN32
1378 if (is_svc) {
1379 SetServiceStatus(svc_status, &(SERVICE_STATUS){
1380 .dwServiceType = SERVICE_WIN32,
1381 .dwCurrentState = SERVICE_STOP_PENDING,
1382 .dwControlsAccepted = 0,
1383 .dwWin32ExitCode = NO_ERROR,
1384 .dwWaitHint = 2000,
1385 });
1386 }
1387 #endif
1388
1389 finish:
1390 #ifdef HAVE_DBUS
1391 if (server_bus)
1392 pa_dbus_connection_unref(server_bus);
1393 if (lookup_service_bus)
1394 pa_dbus_connection_unref(lookup_service_bus);
1395 if (server_lookup)
1396 pa_dbusobj_server_lookup_free(server_lookup);
1397 #endif
1398
1399 if (autospawn_fd >= 0) {
1400 if (autospawn_locked)
1401 pa_autospawn_lock_release();
1402
1403 pa_autospawn_lock_done(false);
1404 }
1405
1406 if (c) {
1407 /* Ensure all the modules/samples are unloaded when the core is still ref'ed,
1408 * as unlink callback hooks in modules may need the core to be ref'ed */
1409 pa_module_unload_all(c);
1410 pa_scache_free_all(c);
1411
1412 pa_core_unref(c);
1413 pa_log_info("Daemon terminated.");
1414 }
1415
1416 if (!conf->no_cpu_limit)
1417 pa_cpu_limit_done();
1418
1419 pa_signal_done();
1420
1421 #ifdef HAVE_FORK
1422 /* If we have daemon_pipe[1] still open, this means we've failed after
1423 * the first fork, but before the second. Therefore just write to it. */
1424 if (daemon_pipe[1] >= 0)
1425 pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
1426 else if (daemon_pipe2[1] >= 0)
1427 pa_loop_write(daemon_pipe2[1], &retval, sizeof(retval), NULL);
1428
1429 pa_close_pipe(daemon_pipe2);
1430 pa_close_pipe(daemon_pipe);
1431 #endif
1432
1433 if (mainloop)
1434 pa_mainloop_free(mainloop);
1435
1436 if (conf)
1437 pa_daemon_conf_free(conf);
1438
1439 if (valid_pid_file)
1440 pa_pid_file_remove();
1441
1442 /* This has no real purpose except making things valgrind-clean */
1443 pa_unset_env_recorded();
1444
1445 #ifdef OS_IS_WIN32
1446 WSACleanup();
1447 #endif
1448
1449 #ifdef HAVE_NO_OHOS
1450 if (ltdl_init)
1451 pa_ltdl_done();
1452 #endif
1453
1454 #ifdef HAVE_DBUS
1455 dbus_shutdown();
1456 #endif
1457
1458 #ifdef OS_IS_WIN32
1459 if (is_svc) {
1460 SetServiceStatus(svc_status, &(SERVICE_STATUS){
1461 .dwServiceType = SERVICE_WIN32,
1462 .dwCurrentState = SERVICE_STOPPED,
1463 .dwControlsAccepted = 0,
1464 .dwWin32ExitCode = retval ? ERROR_PROCESS_ABORTED : NO_ERROR,
1465 .dwWaitHint = 0,
1466 });
1467 }
1468 #endif
1469
1470 return retval;
1471 }
1472
1473 #ifdef __cplusplus
1474 #if __cplusplus
1475 }
1476 #endif
1477 #endif /* End of #ifdef __cplusplus */
1478