• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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