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