l10n: Updates to Russian (ru) translation
[pulseaudio-mirror.git] / src / daemon / main.c
blob9bea2aee50ea51c65a2b51492ff6f8c2e592cf5c
1 /***
2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
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.
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.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include <unistd.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <signal.h>
33 #include <stddef.h>
34 #include <ltdl.h>
35 #include <limits.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <locale.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
42 #ifdef HAVE_SYS_MMAN_H
43 #include <sys/mman.h>
44 #endif
46 #ifdef HAVE_SYS_IOCTL_H
47 #include <sys/ioctl.h>
48 #endif
50 #ifdef HAVE_PWD_H
51 #include <pwd.h>
52 #endif
53 #ifdef HAVE_GRP_H
54 #include <grp.h>
55 #endif
57 #ifdef HAVE_LIBWRAP
58 #include <syslog.h>
59 #include <tcpd.h>
60 #endif
62 #ifdef HAVE_DBUS
63 #include <dbus/dbus.h>
64 #endif
66 #include <pulse/client-conf.h>
67 #ifdef HAVE_X11
68 #include <pulse/client-conf-x11.h>
69 #endif
70 #include <pulse/mainloop.h>
71 #include <pulse/mainloop-signal.h>
72 #include <pulse/timeval.h>
73 #include <pulse/xmalloc.h>
74 #include <pulse/i18n.h>
76 #include <pulsecore/lock-autospawn.h>
77 #include <pulsecore/winsock.h>
78 #include <pulsecore/core-error.h>
79 #include <pulsecore/core-rtclock.h>
80 #include <pulsecore/core.h>
81 #include <pulsecore/memblock.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/namereg.h>
90 #include <pulsecore/random.h>
91 #include <pulsecore/macro.h>
92 #include <pulsecore/mutex.h>
93 #include <pulsecore/thread.h>
94 #include <pulsecore/once.h>
95 #include <pulsecore/shm.h>
96 #include <pulsecore/memtrap.h>
97 #ifdef HAVE_DBUS
98 #include <pulsecore/dbus-shared.h>
99 #endif
100 #include <pulsecore/cpu-arm.h>
101 #include <pulsecore/cpu-x86.h>
103 #include "cmdline.h"
104 #include "cpulimit.h"
105 #include "daemon-conf.h"
106 #include "dumpmodules.h"
107 #include "caps.h"
108 #include "ltdl-bind-now.h"
109 #include "server-lookup.h"
111 #ifdef HAVE_LIBWRAP
112 /* Only one instance of these variables */
113 int allow_severity = LOG_INFO;
114 int deny_severity = LOG_WARNING;
115 #endif
117 #ifdef HAVE_OSS_WRAPPER
118 /* padsp looks for this symbol in the running process and disables
119 * itself if it finds it and it is set to 7 (which is actually a bit
120 * mask). For details see padsp. */
121 int __padsp_disabled__ = 7;
122 #endif
124 #ifdef OS_IS_WIN32
126 static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval *tv, void *userdata) {
127 MSG msg;
128 struct timeval tvnext;
130 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
131 if (msg.message == WM_QUIT)
132 raise(SIGTERM);
133 else {
134 TranslateMessage(&msg);
135 DispatchMessage(&msg);
139 pa_timeval_add(pa_gettimeofday(&tvnext), 100000);
140 a->rtclock_time_restart(e, &tvnext);
143 #endif
145 static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
146 pa_log_info(_("Got signal %s."), pa_sig2str(sig));
148 switch (sig) {
149 #ifdef SIGUSR1
150 case SIGUSR1:
151 pa_module_load(userdata, "module-cli", NULL);
152 break;
153 #endif
155 #ifdef SIGUSR2
156 case SIGUSR2:
157 pa_module_load(userdata, "module-cli-protocol-unix", NULL);
158 break;
159 #endif
161 #ifdef SIGHUP
162 case SIGHUP: {
163 char *c = pa_full_status_string(userdata);
164 pa_log_notice("%s", c);
165 pa_xfree(c);
166 return;
168 #endif
170 case SIGINT:
171 case SIGTERM:
172 default:
173 pa_log_info(_("Exiting."));
174 m->quit(m, 1);
175 break;
179 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
181 static int change_user(void) {
182 struct passwd *pw;
183 struct group * gr;
184 int r;
186 /* This function is called only in system-wide mode. It creates a
187 * runtime dir in /var/run/ with proper UID/GID and drops privs
188 * afterwards. */
190 if (!(pw = getpwnam(PA_SYSTEM_USER))) {
191 pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER);
192 return -1;
195 if (!(gr = getgrnam(PA_SYSTEM_GROUP))) {
196 pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP);
197 return -1;
200 pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."),
201 PA_SYSTEM_USER, (unsigned long) pw->pw_uid,
202 PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid);
204 if (pw->pw_gid != gr->gr_gid) {
205 pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP);
206 return -1;
209 if (strcmp(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH) != 0)
210 pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
212 if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) {
213 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
214 return -1;
217 if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) {
218 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
219 return -1;
222 /* We don't create the config dir here, because we don't need to write to it */
224 if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) {
225 pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno));
226 return -1;
229 #if defined(HAVE_SETRESGID)
230 r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid);
231 #elif defined(HAVE_SETEGID)
232 if ((r = setgid(gr->gr_gid)) >= 0)
233 r = setegid(gr->gr_gid);
234 #elif defined(HAVE_SETREGID)
235 r = setregid(gr->gr_gid, gr->gr_gid);
236 #else
237 #error "No API to drop privileges"
238 #endif
240 if (r < 0) {
241 pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno));
242 return -1;
245 #if defined(HAVE_SETRESUID)
246 r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
247 #elif defined(HAVE_SETEUID)
248 if ((r = setuid(pw->pw_uid)) >= 0)
249 r = seteuid(pw->pw_uid);
250 #elif defined(HAVE_SETREUID)
251 r = setreuid(pw->pw_uid, pw->pw_uid);
252 #else
253 #error "No API to drop privileges"
254 #endif
256 if (r < 0) {
257 pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno));
258 return -1;
261 pa_set_env("USER", PA_SYSTEM_USER);
262 pa_set_env("USERNAME", PA_SYSTEM_USER);
263 pa_set_env("LOGNAME", PA_SYSTEM_USER);
264 pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH);
266 /* Relevant for pa_runtime_path() */
267 if (!getenv("PULSE_RUNTIME_PATH"))
268 pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH);
270 if (!getenv("PULSE_CONFIG_PATH"))
271 pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH);
273 if (!getenv("PULSE_STATE_PATH"))
274 pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
276 pa_log_info(_("Successfully dropped root privileges."));
278 return 0;
281 #else /* HAVE_PWD_H && HAVE_GRP_H */
283 static int change_user(void) {
284 pa_log(_("System wide mode unsupported on this platform."));
285 return -1;
288 #endif /* HAVE_PWD_H && HAVE_GRP_H */
290 #ifdef HAVE_SYS_RESOURCE_H
292 static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
293 struct rlimit rl;
294 pa_assert(r);
296 if (!r->is_set)
297 return 0;
299 rl.rlim_cur = rl.rlim_max = r->value;
301 if (setrlimit(resource, &rl) < 0) {
302 pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
303 return -1;
306 return 0;
309 static void set_all_rlimits(const pa_daemon_conf *conf) {
310 set_one_rlimit(&conf->rlimit_fsize, RLIMIT_FSIZE, "RLIMIT_FSIZE");
311 set_one_rlimit(&conf->rlimit_data, RLIMIT_DATA, "RLIMIT_DATA");
312 set_one_rlimit(&conf->rlimit_stack, RLIMIT_STACK, "RLIMIT_STACK");
313 set_one_rlimit(&conf->rlimit_core, RLIMIT_CORE, "RLIMIT_CORE");
314 #ifdef RLIMIT_RSS
315 set_one_rlimit(&conf->rlimit_rss, RLIMIT_RSS, "RLIMIT_RSS");
316 #endif
317 #ifdef RLIMIT_NPROC
318 set_one_rlimit(&conf->rlimit_nproc, RLIMIT_NPROC, "RLIMIT_NPROC");
319 #endif
320 #ifdef RLIMIT_NOFILE
321 set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
322 #endif
323 #ifdef RLIMIT_MEMLOCK
324 set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
325 #endif
326 #ifdef RLIMIT_AS
327 set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
328 #endif
329 #ifdef RLIMIT_LOCKS
330 set_one_rlimit(&conf->rlimit_locks, RLIMIT_LOCKS, "RLIMIT_LOCKS");
331 #endif
332 #ifdef RLIMIT_SIGPENDING
333 set_one_rlimit(&conf->rlimit_sigpending, RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING");
334 #endif
335 #ifdef RLIMIT_MSGQUEUE
336 set_one_rlimit(&conf->rlimit_msgqueue, RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE");
337 #endif
338 #ifdef RLIMIT_NICE
339 set_one_rlimit(&conf->rlimit_nice, RLIMIT_NICE, "RLIMIT_NICE");
340 #endif
341 #ifdef RLIMIT_RTPRIO
342 set_one_rlimit(&conf->rlimit_rtprio, RLIMIT_RTPRIO, "RLIMIT_RTPRIO");
343 #endif
344 #ifdef RLIMIT_RTTIME
345 set_one_rlimit(&conf->rlimit_rttime, RLIMIT_RTTIME, "RLIMIT_RTTIME");
346 #endif
348 #endif
350 static char *check_configured_address(void) {
351 char *default_server = NULL;
352 pa_client_conf *c = pa_client_conf_new();
354 pa_client_conf_load(c, NULL);
355 #ifdef HAVE_X11
356 pa_client_conf_from_x11(c, NULL);
357 #endif
358 pa_client_conf_env(c);
360 if (c->default_server && *c->default_server)
361 default_server = pa_xstrdup(c->default_server);
363 pa_client_conf_free(c);
365 return default_server;
368 #ifdef HAVE_DBUS
369 static pa_dbus_connection *register_dbus_name(pa_core *c, DBusBusType bus, const char* name) {
370 DBusError error;
371 pa_dbus_connection *conn;
373 dbus_error_init(&error);
375 if (!(conn = pa_dbus_bus_get(c, bus, &error)) || dbus_error_is_set(&error)) {
376 pa_log_warn("Unable to contact D-Bus: %s: %s", error.name, error.message);
377 goto fail;
380 if (dbus_bus_request_name(pa_dbus_connection_get(conn), name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
381 pa_log_debug("Got %s!", name);
382 return conn;
385 if (dbus_error_is_set(&error))
386 pa_log_error("Failed to acquire %s: %s: %s", name, error.name, error.message);
387 else
388 pa_log_error("D-Bus name %s already taken. Weird shit!", name);
390 /* PA cannot be started twice by the same user and hence we can
391 * ignore mostly the case that a name is already taken. */
393 fail:
394 if (conn)
395 pa_dbus_connection_unref(conn);
397 dbus_error_free(&error);
398 return NULL;
400 #endif
402 int main(int argc, char *argv[]) {
403 pa_core *c = NULL;
404 pa_strbuf *buf = NULL;
405 pa_daemon_conf *conf = NULL;
406 pa_mainloop *mainloop = NULL;
407 char *s;
408 char *configured_address;
409 int r = 0, retval = 1, d = 0;
410 pa_bool_t valid_pid_file = FALSE;
411 pa_bool_t ltdl_init = FALSE;
412 int passed_fd = -1;
413 const char *e;
414 #ifdef HAVE_FORK
415 int daemon_pipe[2] = { -1, -1 };
416 #endif
417 #ifdef OS_IS_WIN32
418 pa_time_event *win32_timer;
419 struct timeval win32_tv;
420 #endif
421 int autospawn_fd = -1;
422 pa_bool_t autospawn_locked = FALSE;
423 #ifdef HAVE_DBUS
424 pa_dbusobj_server_lookup *server_lookup = NULL; /* /org/pulseaudio/server_lookup */
425 pa_dbus_connection *lookup_service_bus = NULL; /* Always the user bus. */
426 pa_dbus_connection *server_bus = NULL; /* The bus where we reserve org.pulseaudio.Server, either the user or the system bus. */
427 pa_bool_t start_server;
428 #endif
430 pa_log_set_ident("pulseaudio");
431 pa_log_set_level(PA_LOG_NOTICE);
432 pa_log_set_flags(PA_LOG_COLORS|PA_LOG_PRINT_FILE|PA_LOG_PRINT_LEVEL, PA_LOG_RESET);
434 #if defined(__linux__) && defined(__OPTIMIZE__)
436 Disable lazy relocations to make usage of external libraries
437 more deterministic for our RT threads. We abuse __OPTIMIZE__ as
438 a check whether we are a debug build or not. This all is
439 admittedly a bit snake-oilish.
442 if (!getenv("LD_BIND_NOW")) {
443 char *rp;
444 char *canonical_rp;
446 /* We have to execute ourselves, because the libc caches the
447 * value of $LD_BIND_NOW on initialization. */
449 pa_set_env("LD_BIND_NOW", "1");
451 if ((canonical_rp = pa_realpath(PA_BINARY))) {
453 if ((rp = pa_readlink("/proc/self/exe"))) {
455 if (pa_streq(rp, canonical_rp))
456 pa_assert_se(execv(rp, argv) == 0);
457 else
458 pa_log_warn("/proc/self/exe does not point to %s, cannot self execute. Are you playing games?", canonical_rp);
460 pa_xfree(rp);
462 } else
463 pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
465 pa_xfree(canonical_rp);
467 } else
468 pa_log_warn("Couldn't canonicalize binary path, cannot self execute.");
470 #endif
472 if ((e = getenv("PULSE_PASSED_FD"))) {
473 passed_fd = atoi(e);
475 if (passed_fd <= 2)
476 passed_fd = -1;
479 /* We might be autospawned, in which case have no idea in which
480 * context we have been started. Let's cleanup our execution
481 * context as good as possible */
483 pa_reset_personality();
484 pa_drop_root();
485 pa_close_all(passed_fd, -1);
486 pa_reset_sigs(-1);
487 pa_unblock_sigs(-1);
488 pa_reset_priority();
490 setlocale(LC_ALL, "");
491 pa_init_i18n();
493 conf = pa_daemon_conf_new();
495 if (pa_daemon_conf_load(conf, NULL) < 0)
496 goto finish;
498 if (pa_daemon_conf_env(conf) < 0)
499 goto finish;
501 if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
502 pa_log(_("Failed to parse command line."));
503 goto finish;
506 pa_log_set_level(conf->log_level);
507 pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target);
508 if (conf->log_meta)
509 pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
510 if (conf->log_time)
511 pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
512 pa_log_set_show_backtrace(conf->log_backtrace);
514 #ifdef HAVE_DBUS
515 /* conf->system_instance and conf->local_server_type control almost the
516 * same thing; make them agree about what is requested. */
517 switch (conf->local_server_type) {
518 case PA_SERVER_TYPE_UNSET:
519 conf->local_server_type = conf->system_instance ? PA_SERVER_TYPE_SYSTEM : PA_SERVER_TYPE_USER;
520 break;
521 case PA_SERVER_TYPE_USER:
522 case PA_SERVER_TYPE_NONE:
523 conf->system_instance = FALSE;
524 break;
525 case PA_SERVER_TYPE_SYSTEM:
526 conf->system_instance = TRUE;
527 break;
528 default:
529 pa_assert_not_reached();
532 start_server = conf->local_server_type == PA_SERVER_TYPE_USER || (getuid() == 0 && conf->local_server_type == PA_SERVER_TYPE_SYSTEM);
534 if (!start_server && conf->local_server_type == PA_SERVER_TYPE_SYSTEM) {
535 pa_log_notice(_("System mode refused for non-root user. Only starting the D-Bus server lookup service."));
536 conf->system_instance = FALSE;
538 #endif
540 LTDL_SET_PRELOADED_SYMBOLS();
541 pa_ltdl_init();
542 ltdl_init = TRUE;
544 if (conf->dl_search_path)
545 lt_dlsetsearchpath(conf->dl_search_path);
547 #ifdef OS_IS_WIN32
549 WSADATA data;
550 WSAStartup(MAKEWORD(2, 0), &data);
552 #endif
554 pa_random_seed();
556 switch (conf->cmd) {
557 case PA_CMD_DUMP_MODULES:
558 pa_dump_modules(conf, argc-d, argv+d);
559 retval = 0;
560 goto finish;
562 case PA_CMD_DUMP_CONF: {
564 if (d < argc) {
565 pa_log("Too many arguments.\n");
566 goto finish;
569 s = pa_daemon_conf_dump(conf);
570 fputs(s, stdout);
571 pa_xfree(s);
572 retval = 0;
573 goto finish;
576 case PA_CMD_DUMP_RESAMPLE_METHODS: {
577 int i;
579 if (d < argc) {
580 pa_log("Too many arguments.\n");
581 goto finish;
584 for (i = 0; i < PA_RESAMPLER_MAX; i++)
585 if (pa_resample_method_supported(i))
586 printf("%s\n", pa_resample_method_to_string(i));
588 retval = 0;
589 goto finish;
592 case PA_CMD_HELP :
593 pa_cmdline_help(argv[0]);
594 retval = 0;
595 goto finish;
597 case PA_CMD_VERSION :
599 if (d < argc) {
600 pa_log("Too many arguments.\n");
601 goto finish;
604 printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
605 retval = 0;
606 goto finish;
608 case PA_CMD_CHECK: {
609 pid_t pid;
611 if (d < argc) {
612 pa_log("Too many arguments.\n");
613 goto finish;
616 if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
617 pa_log_info(_("Daemon not running"));
618 else {
619 pa_log_info(_("Daemon running as PID %u"), pid);
620 retval = 0;
623 goto finish;
626 case PA_CMD_KILL:
628 if (d < argc) {
629 pa_log("Too many arguments.\n");
630 goto finish;
633 if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
634 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
635 else
636 retval = 0;
638 goto finish;
640 case PA_CMD_CLEANUP_SHM:
642 if (d < argc) {
643 pa_log("Too many arguments.\n");
644 goto finish;
647 if (pa_shm_cleanup() >= 0)
648 retval = 0;
650 goto finish;
652 default:
653 pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
656 if (d < argc) {
657 pa_log("Too many arguments.\n");
658 goto finish;
661 if (getuid() == 0 && !conf->system_instance)
662 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
663 #ifndef HAVE_DBUS /* A similar, only a notice worthy check was done earlier, if D-Bus is enabled. */
664 else if (getuid() != 0 && conf->system_instance) {
665 pa_log(_("Root privileges required."));
666 goto finish;
668 #endif
670 if (conf->cmd == PA_CMD_START && conf->system_instance) {
671 pa_log(_("--start not supported for system instances."));
672 goto finish;
675 if (conf->cmd == PA_CMD_START && (configured_address = check_configured_address())) {
676 pa_log_notice(_("User-configured server at %s, not autospawning."), configured_address);
677 pa_xfree(configured_address);
678 retval = 0;
679 goto finish;
682 if (conf->system_instance && !conf->disallow_exit)
683 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
685 if (conf->system_instance && !conf->disallow_module_loading)
686 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
688 if (conf->system_instance && !conf->disable_shm) {
689 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
690 conf->disable_shm = TRUE;
693 if (conf->system_instance && conf->exit_idle_time >= 0) {
694 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
695 conf->exit_idle_time = -1;
698 if (conf->cmd == PA_CMD_START) {
699 /* If we shall start PA only when it is not running yet, we
700 * first take the autospawn lock to make things
701 * synchronous. */
703 if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
704 pa_log("Failed to initialize autospawn lock");
705 goto finish;
708 if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
709 pa_log("Failed to acquire autospawn lock");
710 goto finish;
713 autospawn_locked = TRUE;
716 if (conf->daemonize) {
717 pid_t child;
719 if (pa_stdio_acquire() < 0) {
720 pa_log(_("Failed to acquire stdio."));
721 goto finish;
724 #ifdef HAVE_FORK
725 if (pipe(daemon_pipe) < 0) {
726 pa_log(_("pipe() failed: %s"), pa_cstrerror(errno));
727 goto finish;
730 if ((child = fork()) < 0) {
731 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
732 goto finish;
735 if (child != 0) {
736 ssize_t n;
737 /* Father */
739 pa_assert_se(pa_close(daemon_pipe[1]) == 0);
740 daemon_pipe[1] = -1;
742 if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
744 if (n < 0)
745 pa_log(_("read() failed: %s"), pa_cstrerror(errno));
747 retval = 1;
750 if (retval)
751 pa_log(_("Daemon startup failed."));
752 else
753 pa_log_info(_("Daemon startup successful."));
755 goto finish;
758 if (autospawn_fd >= 0) {
759 /* The lock file is unlocked from the parent, so we need
760 * to close it in the child */
762 pa_autospawn_lock_release();
763 pa_autospawn_lock_done(TRUE);
765 autospawn_locked = FALSE;
766 autospawn_fd = -1;
769 pa_assert_se(pa_close(daemon_pipe[0]) == 0);
770 daemon_pipe[0] = -1;
771 #endif
773 if (conf->auto_log_target)
774 pa_log_set_target(PA_LOG_SYSLOG);
776 #ifdef HAVE_SETSID
777 if (setsid() < 0) {
778 pa_log(_("setsid() failed: %s"), pa_cstrerror(errno));
779 goto finish;
781 #endif
783 /* We now are a session and process group leader. Let's fork
784 * again and let the father die, so that we'll become a
785 * process that can never acquire a TTY again, in a session and
786 * process group without leader */
788 #ifdef HAVE_FORK
789 if ((child = fork()) < 0) {
790 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
791 goto finish;
794 if (child != 0) {
795 retval = 0;
796 goto finish;
798 #endif
800 #ifdef SIGTTOU
801 signal(SIGTTOU, SIG_IGN);
802 #endif
803 #ifdef SIGTTIN
804 signal(SIGTTIN, SIG_IGN);
805 #endif
806 #ifdef SIGTSTP
807 signal(SIGTSTP, SIG_IGN);
808 #endif
810 pa_nullify_stdfds();
813 pa_set_env_and_record("PULSE_INTERNAL", "1");
814 pa_assert_se(chdir("/") == 0);
815 umask(0022);
817 #ifdef HAVE_SYS_RESOURCE_H
818 set_all_rlimits(conf);
819 #endif
820 pa_rtclock_hrtimer_enable();
822 pa_raise_priority(conf->nice_level);
824 if (conf->system_instance)
825 if (change_user() < 0)
826 goto finish;
828 pa_set_env_and_record("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
830 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
831 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
832 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
834 s = pa_uname_string();
835 pa_log_debug(_("Running on host: %s"), s);
836 pa_xfree(s);
838 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
840 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
842 #ifdef HAVE_VALGRIND_MEMCHECK_H
843 pa_log_debug(_("Compiled with Valgrind support: yes"));
844 #else
845 pa_log_debug(_("Compiled with Valgrind support: no"));
846 #endif
848 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
850 pa_log_debug(_("Running in VM: %s"), pa_yes_no(pa_running_in_vm()));
852 #ifdef __OPTIMIZE__
853 pa_log_debug(_("Optimized build: yes"));
854 #else
855 pa_log_debug(_("Optimized build: no"));
856 #endif
858 #ifdef NDEBUG
859 pa_log_debug(_("NDEBUG defined, all asserts disabled."));
860 #elif defined(FASTPATH)
861 pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
862 #else
863 pa_log_debug(_("All asserts enabled."));
864 #endif
866 if (!(s = pa_machine_id())) {
867 pa_log(_("Failed to get machine ID"));
868 goto finish;
870 pa_log_info(_("Machine ID is %s."), s);
871 pa_xfree(s);
873 if ((s = pa_session_id())) {
874 pa_log_info(_("Session ID is %s."), s);
875 pa_xfree(s);
878 if (!(s = pa_get_runtime_dir()))
879 goto finish;
880 pa_log_info(_("Using runtime directory %s."), s);
881 pa_xfree(s);
883 if (!(s = pa_get_state_dir()))
884 goto finish;
885 pa_log_info(_("Using state directory %s."), s);
886 pa_xfree(s);
888 pa_log_info(_("Using modules directory %s."), conf->dl_search_path);
890 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
892 if (pa_in_system_mode())
893 pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
894 "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
895 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
897 if (conf->use_pid_file) {
898 int z;
900 if ((z = pa_pid_file_create("pulseaudio")) != 0) {
902 if (conf->cmd == PA_CMD_START && z > 0) {
903 /* If we are already running and with are run in
904 * --start mode, then let's return this as success. */
906 retval = 0;
907 goto finish;
910 pa_log(_("pa_pid_file_create() failed."));
911 goto finish;
914 valid_pid_file = TRUE;
917 pa_disable_sigpipe();
919 if (pa_rtclock_hrtimer())
920 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
921 else
922 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
924 if (conf->lock_memory) {
925 #ifdef HAVE_SYS_MMAN_H
926 if (mlockall(MCL_FUTURE) < 0)
927 pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
928 else
929 pa_log_info("Sucessfully locked process into memory.");
930 #else
931 pa_log_warn("Memory locking requested but not supported on platform.");
932 #endif
935 pa_memtrap_install();
937 if (!getenv("PULSE_NO_SIMD")) {
938 pa_cpu_init_x86();
939 pa_cpu_init_arm();
942 pa_assert_se(mainloop = pa_mainloop_new());
944 if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
945 pa_log(_("pa_core_new() failed."));
946 goto finish;
949 c->default_sample_spec = conf->default_sample_spec;
950 c->default_channel_map = conf->default_channel_map;
951 c->default_n_fragments = conf->default_n_fragments;
952 c->default_fragment_size_msec = conf->default_fragment_size_msec;
953 c->exit_idle_time = conf->exit_idle_time;
954 c->scache_idle_time = conf->scache_idle_time;
955 c->resample_method = conf->resample_method;
956 c->realtime_priority = conf->realtime_priority;
957 c->realtime_scheduling = !!conf->realtime_scheduling;
958 c->disable_remixing = !!conf->disable_remixing;
959 c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
960 c->running_as_daemon = !!conf->daemonize;
961 c->disallow_exit = conf->disallow_exit;
962 c->flat_volumes = conf->flat_volumes;
963 #ifdef HAVE_DBUS
964 c->server_type = conf->local_server_type;
965 #endif
967 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
968 pa_signal_new(SIGINT, signal_callback, c);
969 pa_signal_new(SIGTERM, signal_callback, c);
970 #ifdef SIGUSR1
971 pa_signal_new(SIGUSR1, signal_callback, c);
972 #endif
973 #ifdef SIGUSR2
974 pa_signal_new(SIGUSR2, signal_callback, c);
975 #endif
976 #ifdef SIGHUP
977 pa_signal_new(SIGHUP, signal_callback, c);
978 #endif
980 #ifdef OS_IS_WIN32
981 win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
982 #endif
984 if (!conf->no_cpu_limit)
985 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
987 buf = pa_strbuf_new();
989 #ifdef HAVE_DBUS
990 if (start_server) {
991 #endif
992 if (conf->load_default_script_file) {
993 FILE *f;
995 if ((f = pa_daemon_conf_open_default_script_file(conf))) {
996 r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
997 fclose(f);
1001 if (r >= 0)
1002 r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
1004 pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
1005 pa_xfree(s);
1007 if (r < 0 && conf->fail) {
1008 pa_log(_("Failed to initialize daemon."));
1009 goto finish;
1012 if (!c->modules || pa_idxset_size(c->modules) == 0) {
1013 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
1014 goto finish;
1016 #ifdef HAVE_DBUS
1017 } else {
1018 /* When we just provide the D-Bus server lookup service, we don't want
1019 * any modules to be loaded. We haven't loaded any so far, so one might
1020 * think there's no way to contact the server, but receiving certain
1021 * signals could still cause modules to load. */
1022 conf->disallow_module_loading = TRUE;
1024 #endif
1026 /* We completed the initial module loading, so let's disable it
1027 * from now on, if requested */
1028 c->disallow_module_loading = !!conf->disallow_module_loading;
1030 #ifdef HAVE_DBUS
1031 if (!conf->system_instance) {
1032 if (!(server_lookup = pa_dbusobj_server_lookup_new(c)))
1033 goto finish;
1034 if (!(lookup_service_bus = register_dbus_name(c, DBUS_BUS_SESSION, "org.PulseAudio1")))
1035 goto finish;
1038 if (start_server && !(server_bus = register_dbus_name(c, conf->system_instance ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, "org.pulseaudio.Server")))
1039 goto finish;
1040 #endif
1042 #ifdef HAVE_FORK
1043 if (daemon_pipe[1] >= 0) {
1044 int ok = 0;
1045 pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
1046 pa_close(daemon_pipe[1]);
1047 daemon_pipe[1] = -1;
1049 #endif
1051 pa_log_info(_("Daemon startup complete."));
1053 retval = 0;
1054 if (pa_mainloop_run(mainloop, &retval) < 0)
1055 goto finish;
1057 pa_log_info(_("Daemon shutdown initiated."));
1059 finish:
1060 #ifdef HAVE_DBUS
1061 if (server_bus)
1062 pa_dbus_connection_unref(server_bus);
1063 if (lookup_service_bus)
1064 pa_dbus_connection_unref(lookup_service_bus);
1065 if (server_lookup)
1066 pa_dbusobj_server_lookup_free(server_lookup);
1067 #endif
1069 if (autospawn_fd >= 0) {
1070 if (autospawn_locked)
1071 pa_autospawn_lock_release();
1073 pa_autospawn_lock_done(FALSE);
1076 #ifdef OS_IS_WIN32
1077 if (win32_timer)
1078 pa_mainloop_get_api(mainloop)->time_free(win32_timer);
1079 #endif
1081 if (c) {
1082 pa_core_unref(c);
1083 pa_log_info(_("Daemon terminated."));
1086 if (!conf->no_cpu_limit)
1087 pa_cpu_limit_done();
1089 pa_signal_done();
1091 #ifdef HAVE_FORK
1092 if (daemon_pipe[1] >= 0)
1093 pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
1095 pa_close_pipe(daemon_pipe);
1096 #endif
1098 if (mainloop)
1099 pa_mainloop_free(mainloop);
1101 if (conf)
1102 pa_daemon_conf_free(conf);
1104 if (valid_pid_file)
1105 pa_pid_file_remove();
1107 /* This has no real purpose except making things valgrind-clean */
1108 pa_unset_env_recorded();
1110 #ifdef OS_IS_WIN32
1111 WSACleanup();
1112 #endif
1114 if (ltdl_init)
1115 pa_ltdl_done();
1117 #ifdef HAVE_DBUS
1118 dbus_shutdown();
1119 #endif
1121 return retval;