]> code.delx.au - pulseaudio/blob - src/daemon/main.c
Don't refuse to start on systems using GNU stow, graft, STORE et al
[pulseaudio] / src / daemon / main.c
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, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
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>
41
42 #ifdef HAVE_SYS_MMAN_H
43 #include <sys/mman.h>
44 #endif
45
46 #ifdef HAVE_SYS_IOCTL_H
47 #include <sys/ioctl.h>
48 #endif
49
50 #ifdef HAVE_PWD_H
51 #include <pwd.h>
52 #endif
53 #ifdef HAVE_GRP_H
54 #include <grp.h>
55 #endif
56
57 #ifdef HAVE_LIBWRAP
58 #include <syslog.h>
59 #include <tcpd.h>
60 #endif
61
62 #ifdef HAVE_DBUS
63 #include <dbus/dbus.h>
64 #endif
65
66 #include <pulse/mainloop.h>
67 #include <pulse/mainloop-signal.h>
68 #include <pulse/timeval.h>
69 #include <pulse/xmalloc.h>
70 #include <pulse/i18n.h>
71
72 #include <pulsecore/lock-autospawn.h>
73 #include <pulsecore/winsock.h>
74 #include <pulsecore/core-error.h>
75 #include <pulsecore/core-rtclock.h>
76 #include <pulsecore/core.h>
77 #include <pulsecore/memblock.h>
78 #include <pulsecore/module.h>
79 #include <pulsecore/cli-command.h>
80 #include <pulsecore/log.h>
81 #include <pulsecore/core-util.h>
82 #include <pulsecore/sioman.h>
83 #include <pulsecore/cli-text.h>
84 #include <pulsecore/pid.h>
85 #include <pulsecore/namereg.h>
86 #include <pulsecore/random.h>
87 #include <pulsecore/macro.h>
88 #include <pulsecore/mutex.h>
89 #include <pulsecore/thread.h>
90 #include <pulsecore/once.h>
91 #include <pulsecore/shm.h>
92 #include <pulsecore/memtrap.h>
93 #ifdef HAVE_DBUS
94 #include <pulsecore/dbus-shared.h>
95 #endif
96 #include <pulsecore/cpu-arm.h>
97 #include <pulsecore/cpu-x86.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
106 #ifdef HAVE_LIBWRAP
107 /* Only one instance of these variables */
108 int allow_severity = LOG_INFO;
109 int deny_severity = LOG_WARNING;
110 #endif
111
112 #ifdef HAVE_OSS_WRAPPER
113 /* padsp looks for this symbol in the running process and disables
114 * itself if it finds it and it is set to 7 (which is actually a bit
115 * mask). For details see padsp. */
116 int __padsp_disabled__ = 7;
117 #endif
118
119 #ifdef OS_IS_WIN32
120
121 static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval *tv, void *userdata) {
122 MSG msg;
123 struct timeval tvnext;
124
125 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
126 if (msg.message == WM_QUIT)
127 raise(SIGTERM);
128 else {
129 TranslateMessage(&msg);
130 DispatchMessage(&msg);
131 }
132 }
133
134 pa_timeval_add(pa_gettimeofday(&tvnext), 100000);
135 a->rtclock_time_restart(e, &tvnext);
136 }
137
138 #endif
139
140 static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
141 pa_log_info(_("Got signal %s."), pa_sig2str(sig));
142
143 switch (sig) {
144 #ifdef SIGUSR1
145 case SIGUSR1:
146 pa_module_load(userdata, "module-cli", NULL);
147 break;
148 #endif
149
150 #ifdef SIGUSR2
151 case SIGUSR2:
152 pa_module_load(userdata, "module-cli-protocol-unix", NULL);
153 break;
154 #endif
155
156 #ifdef SIGHUP
157 case SIGHUP: {
158 char *c = pa_full_status_string(userdata);
159 pa_log_notice("%s", c);
160 pa_xfree(c);
161 return;
162 }
163 #endif
164
165 case SIGINT:
166 case SIGTERM:
167 default:
168 pa_log_info(_("Exiting."));
169 m->quit(m, 1);
170 break;
171 }
172 }
173
174 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
175
176 static int change_user(void) {
177 struct passwd *pw;
178 struct group * gr;
179 int r;
180
181 /* This function is called only in system-wide mode. It creates a
182 * runtime dir in /var/run/ with proper UID/GID and drops privs
183 * afterwards. */
184
185 if (!(pw = getpwnam(PA_SYSTEM_USER))) {
186 pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER);
187 return -1;
188 }
189
190 if (!(gr = getgrnam(PA_SYSTEM_GROUP))) {
191 pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP);
192 return -1;
193 }
194
195 pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."),
196 PA_SYSTEM_USER, (unsigned long) pw->pw_uid,
197 PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid);
198
199 if (pw->pw_gid != gr->gr_gid) {
200 pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP);
201 return -1;
202 }
203
204 if (strcmp(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH) != 0)
205 pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
206
207 if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) {
208 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
209 return -1;
210 }
211
212 if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) {
213 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
214 return -1;
215 }
216
217 /* We don't create the config dir here, because we don't need to write to it */
218
219 if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) {
220 pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno));
221 return -1;
222 }
223
224 #if defined(HAVE_SETRESGID)
225 r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid);
226 #elif defined(HAVE_SETEGID)
227 if ((r = setgid(gr->gr_gid)) >= 0)
228 r = setegid(gr->gr_gid);
229 #elif defined(HAVE_SETREGID)
230 r = setregid(gr->gr_gid, gr->gr_gid);
231 #else
232 #error "No API to drop privileges"
233 #endif
234
235 if (r < 0) {
236 pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno));
237 return -1;
238 }
239
240 #if defined(HAVE_SETRESUID)
241 r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
242 #elif defined(HAVE_SETEUID)
243 if ((r = setuid(pw->pw_uid)) >= 0)
244 r = seteuid(pw->pw_uid);
245 #elif defined(HAVE_SETREUID)
246 r = setreuid(pw->pw_uid, pw->pw_uid);
247 #else
248 #error "No API to drop privileges"
249 #endif
250
251 if (r < 0) {
252 pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno));
253 return -1;
254 }
255
256 pa_set_env("USER", PA_SYSTEM_USER);
257 pa_set_env("USERNAME", PA_SYSTEM_USER);
258 pa_set_env("LOGNAME", PA_SYSTEM_USER);
259 pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH);
260
261 /* Relevant for pa_runtime_path() */
262 if (!getenv("PULSE_RUNTIME_PATH"))
263 pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH);
264
265 if (!getenv("PULSE_CONFIG_PATH"))
266 pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH);
267
268 if (!getenv("PULSE_STATE_PATH"))
269 pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
270
271 pa_log_info(_("Successfully dropped root privileges."));
272
273 return 0;
274 }
275
276 #else /* HAVE_PWD_H && HAVE_GRP_H */
277
278 static int change_user(void) {
279 pa_log(_("System wide mode unsupported on this platform."));
280 return -1;
281 }
282
283 #endif /* HAVE_PWD_H && HAVE_GRP_H */
284
285 #ifdef HAVE_SYS_RESOURCE_H
286
287 static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
288 struct rlimit rl;
289 pa_assert(r);
290
291 if (!r->is_set)
292 return 0;
293
294 rl.rlim_cur = rl.rlim_max = r->value;
295
296 if (setrlimit(resource, &rl) < 0) {
297 pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
298 return -1;
299 }
300
301 return 0;
302 }
303
304 static void set_all_rlimits(const pa_daemon_conf *conf) {
305 set_one_rlimit(&conf->rlimit_fsize, RLIMIT_FSIZE, "RLIMIT_FSIZE");
306 set_one_rlimit(&conf->rlimit_data, RLIMIT_DATA, "RLIMIT_DATA");
307 set_one_rlimit(&conf->rlimit_stack, RLIMIT_STACK, "RLIMIT_STACK");
308 set_one_rlimit(&conf->rlimit_core, RLIMIT_CORE, "RLIMIT_CORE");
309 #ifdef RLIMIT_RSS
310 set_one_rlimit(&conf->rlimit_rss, RLIMIT_RSS, "RLIMIT_RSS");
311 #endif
312 #ifdef RLIMIT_NPROC
313 set_one_rlimit(&conf->rlimit_nproc, RLIMIT_NPROC, "RLIMIT_NPROC");
314 #endif
315 #ifdef RLIMIT_NOFILE
316 set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
317 #endif
318 #ifdef RLIMIT_MEMLOCK
319 set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
320 #endif
321 #ifdef RLIMIT_AS
322 set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
323 #endif
324 #ifdef RLIMIT_LOCKS
325 set_one_rlimit(&conf->rlimit_locks, RLIMIT_LOCKS, "RLIMIT_LOCKS");
326 #endif
327 #ifdef RLIMIT_SIGPENDING
328 set_one_rlimit(&conf->rlimit_sigpending, RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING");
329 #endif
330 #ifdef RLIMIT_MSGQUEUE
331 set_one_rlimit(&conf->rlimit_msgqueue, RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE");
332 #endif
333 #ifdef RLIMIT_NICE
334 set_one_rlimit(&conf->rlimit_nice, RLIMIT_NICE, "RLIMIT_NICE");
335 #endif
336 #ifdef RLIMIT_RTPRIO
337 set_one_rlimit(&conf->rlimit_rtprio, RLIMIT_RTPRIO, "RLIMIT_RTPRIO");
338 #endif
339 #ifdef RLIMIT_RTTIME
340 set_one_rlimit(&conf->rlimit_rttime, RLIMIT_RTTIME, "RLIMIT_RTTIME");
341 #endif
342 }
343 #endif
344
345 #ifdef HAVE_DBUS
346 static pa_dbus_connection *register_dbus(pa_core *c) {
347 DBusError error;
348 pa_dbus_connection *conn;
349
350 dbus_error_init(&error);
351
352 if (!(conn = pa_dbus_bus_get(c, pa_in_system_mode() ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) {
353 pa_log_warn("Unable to contact D-Bus: %s: %s", error.name, error.message);
354 goto fail;
355 }
356
357 if (dbus_bus_request_name(pa_dbus_connection_get(conn), "org.pulseaudio.Server", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
358 pa_log_debug("Got org.pulseaudio.Server!");
359 return conn;
360 }
361
362 if (dbus_error_is_set(&error))
363 pa_log_warn("Failed to acquire org.pulseaudio.Server: %s: %s", error.name, error.message);
364 else
365 pa_log_warn("D-Bus name org.pulseaudio.Server already taken. Weird shit!");
366
367 /* PA cannot be started twice by the same user and hence we can
368 * ignore mostly the case that org.pulseaudio.Server is already
369 * taken. */
370
371 fail:
372
373 if (conn)
374 pa_dbus_connection_unref(conn);
375
376 dbus_error_free(&error);
377 return NULL;
378 }
379 #endif
380
381 int main(int argc, char *argv[]) {
382 pa_core *c = NULL;
383 pa_strbuf *buf = NULL;
384 pa_daemon_conf *conf = NULL;
385 pa_mainloop *mainloop = NULL;
386 char *s;
387 int r = 0, retval = 1, d = 0;
388 pa_bool_t valid_pid_file = FALSE;
389 pa_bool_t ltdl_init = FALSE;
390 int passed_fd = -1;
391 const char *e;
392 #ifdef HAVE_FORK
393 int daemon_pipe[2] = { -1, -1 };
394 #endif
395 #ifdef OS_IS_WIN32
396 pa_time_event *win32_timer;
397 struct timeval win32_tv;
398 #endif
399 int autospawn_fd = -1;
400 pa_bool_t autospawn_locked = FALSE;
401 #ifdef HAVE_DBUS
402 pa_dbus_connection *dbus = NULL;
403 #endif
404
405 pa_log_set_ident("pulseaudio");
406 pa_log_set_level(PA_LOG_NOTICE);
407 pa_log_set_flags(PA_LOG_COLORS|PA_LOG_PRINT_FILE|PA_LOG_PRINT_LEVEL, PA_LOG_RESET);
408
409 #if defined(__linux__) && defined(__OPTIMIZE__)
410 /*
411 Disable lazy relocations to make usage of external libraries
412 more deterministic for our RT threads. We abuse __OPTIMIZE__ as
413 a check whether we are a debug build or not. This all is
414 admittedly a bit snake-oilish.
415 */
416
417 if (!getenv("LD_BIND_NOW")) {
418 char *rp;
419 char *canonical_rp;
420
421 /* We have to execute ourselves, because the libc caches the
422 * value of $LD_BIND_NOW on initialization. */
423
424 pa_set_env("LD_BIND_NOW", "1");
425
426 canonical_rp = pa_realpath(PA_BINARY);
427
428 if ((rp = pa_readlink("/proc/self/exe"))) {
429
430 if (pa_streq(rp, canonical_rp))
431 pa_assert_se(execv(rp, argv) == 0);
432 else
433 pa_log_warn("/proc/self/exe does not point to %s, cannot self execute. Are you playing games?", canonical_rp);
434
435 pa_xfree(rp);
436
437 } else
438 pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
439
440 pa_xfree(canonical_rp);
441 }
442 #endif
443
444 if ((e = getenv("PULSE_PASSED_FD"))) {
445 passed_fd = atoi(e);
446
447 if (passed_fd <= 2)
448 passed_fd = -1;
449 }
450
451 /* We might be autospawned, in which case have no idea in which
452 * context we have been started. Let's cleanup our execution
453 * context as good as possible */
454
455 pa_reset_personality();
456 pa_drop_root();
457 pa_close_all(passed_fd, -1);
458 pa_reset_sigs(-1);
459 pa_unblock_sigs(-1);
460 pa_reset_priority();
461
462 setlocale(LC_ALL, "");
463 pa_init_i18n();
464
465 conf = pa_daemon_conf_new();
466
467 if (pa_daemon_conf_load(conf, NULL) < 0)
468 goto finish;
469
470 if (pa_daemon_conf_env(conf) < 0)
471 goto finish;
472
473 if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
474 pa_log(_("Failed to parse command line."));
475 goto finish;
476 }
477
478 pa_log_set_level(conf->log_level);
479 pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target);
480 if (conf->log_meta)
481 pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
482 if (conf->log_time)
483 pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
484 pa_log_set_show_backtrace(conf->log_backtrace);
485
486 LTDL_SET_PRELOADED_SYMBOLS();
487 pa_ltdl_init();
488 ltdl_init = TRUE;
489
490 if (conf->dl_search_path)
491 lt_dlsetsearchpath(conf->dl_search_path);
492
493 #ifdef OS_IS_WIN32
494 {
495 WSADATA data;
496 WSAStartup(MAKEWORD(2, 0), &data);
497 }
498 #endif
499
500 pa_random_seed();
501
502 switch (conf->cmd) {
503 case PA_CMD_DUMP_MODULES:
504 pa_dump_modules(conf, argc-d, argv+d);
505 retval = 0;
506 goto finish;
507
508 case PA_CMD_DUMP_CONF: {
509 s = pa_daemon_conf_dump(conf);
510 fputs(s, stdout);
511 pa_xfree(s);
512 retval = 0;
513 goto finish;
514 }
515
516 case PA_CMD_DUMP_RESAMPLE_METHODS: {
517 int i;
518
519 for (i = 0; i < PA_RESAMPLER_MAX; i++)
520 if (pa_resample_method_supported(i))
521 printf("%s\n", pa_resample_method_to_string(i));
522
523 retval = 0;
524 goto finish;
525 }
526
527 case PA_CMD_HELP :
528 pa_cmdline_help(argv[0]);
529 retval = 0;
530 goto finish;
531
532 case PA_CMD_VERSION :
533 printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
534 retval = 0;
535 goto finish;
536
537 case PA_CMD_CHECK: {
538 pid_t pid;
539
540 if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
541 pa_log_info(_("Daemon not running"));
542 else {
543 pa_log_info(_("Daemon running as PID %u"), pid);
544 retval = 0;
545 }
546
547 goto finish;
548
549 }
550 case PA_CMD_KILL:
551
552 if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
553 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
554 else
555 retval = 0;
556
557 goto finish;
558
559 case PA_CMD_CLEANUP_SHM:
560
561 if (pa_shm_cleanup() >= 0)
562 retval = 0;
563
564 goto finish;
565
566 default:
567 pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
568 }
569
570 if (getuid() == 0 && !conf->system_instance)
571 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
572 else if (getuid() != 0 && conf->system_instance) {
573 pa_log(_("Root privileges required."));
574 goto finish;
575 }
576
577 if (conf->cmd == PA_CMD_START && conf->system_instance) {
578 pa_log(_("--start not supported for system instances."));
579 goto finish;
580 }
581
582 if (conf->system_instance && !conf->disallow_exit)
583 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
584
585 if (conf->system_instance && !conf->disallow_module_loading)
586 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
587
588 if (conf->system_instance && !conf->disable_shm) {
589 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
590 conf->disable_shm = TRUE;
591 }
592
593 if (conf->system_instance && conf->exit_idle_time >= 0) {
594 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
595 conf->exit_idle_time = -1;
596 }
597
598 if (conf->cmd == PA_CMD_START) {
599 /* If we shall start PA only when it is not running yet, we
600 * first take the autospawn lock to make things
601 * synchronous. */
602
603 if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
604 pa_log("Failed to initialize autospawn lock");
605 goto finish;
606 }
607
608 if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
609 pa_log("Failed to acquire autospawn lock");
610 goto finish;
611 }
612
613 autospawn_locked = TRUE;
614 }
615
616 if (conf->daemonize) {
617 pid_t child;
618 int tty_fd;
619
620 if (pa_stdio_acquire() < 0) {
621 pa_log(_("Failed to acquire stdio."));
622 goto finish;
623 }
624
625 #ifdef HAVE_FORK
626 if (pipe(daemon_pipe) < 0) {
627 pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
628 goto finish;
629 }
630
631 if ((child = fork()) < 0) {
632 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
633 goto finish;
634 }
635
636 if (child != 0) {
637 ssize_t n;
638 /* Father */
639
640 pa_assert_se(pa_close(daemon_pipe[1]) == 0);
641 daemon_pipe[1] = -1;
642
643 if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
644
645 if (n < 0)
646 pa_log(_("read() failed: %s"), pa_cstrerror(errno));
647
648 retval = 1;
649 }
650
651 if (retval)
652 pa_log(_("Daemon startup failed."));
653 else
654 pa_log_info(_("Daemon startup successful."));
655
656 goto finish;
657 }
658
659 if (autospawn_fd >= 0) {
660 /* The lock file is unlocked from the parent, so we need
661 * to close it in the child */
662
663 pa_autospawn_lock_release();
664 pa_autospawn_lock_done(TRUE);
665
666 autospawn_locked = FALSE;
667 autospawn_fd = -1;
668 }
669
670 pa_assert_se(pa_close(daemon_pipe[0]) == 0);
671 daemon_pipe[0] = -1;
672 #endif
673
674 if (conf->auto_log_target)
675 pa_log_set_target(PA_LOG_SYSLOG);
676
677 #ifdef HAVE_SETSID
678 setsid();
679 #endif
680 #ifdef HAVE_SETPGID
681 setpgid(0,0);
682 #endif
683
684 #ifndef OS_IS_WIN32
685 pa_close(0);
686 pa_close(1);
687 pa_close(2);
688
689 pa_assert_se(open("/dev/null", O_RDONLY) == 0);
690 pa_assert_se(open("/dev/null", O_WRONLY) == 1);
691 pa_assert_se(open("/dev/null", O_WRONLY) == 2);
692 #else
693 FreeConsole();
694 #endif
695
696 #ifdef SIGTTOU
697 signal(SIGTTOU, SIG_IGN);
698 #endif
699 #ifdef SIGTTIN
700 signal(SIGTTIN, SIG_IGN);
701 #endif
702 #ifdef SIGTSTP
703 signal(SIGTSTP, SIG_IGN);
704 #endif
705
706 #ifdef TIOCNOTTY
707 if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
708 ioctl(tty_fd, TIOCNOTTY, (char*) 0);
709 pa_assert_se(pa_close(tty_fd) == 0);
710 }
711 #endif
712 }
713
714 pa_set_env_and_record("PULSE_INTERNAL", "1");
715 pa_assert_se(chdir("/") == 0);
716 umask(0022);
717
718 #ifdef HAVE_SYS_RESOURCE_H
719 set_all_rlimits(conf);
720 #endif
721 pa_rtclock_hrtimer_enable();
722
723 pa_raise_priority(conf->nice_level);
724
725 if (conf->system_instance)
726 if (change_user() < 0)
727 goto finish;
728
729 pa_set_env_and_record("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
730
731 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
732 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
733 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
734
735 s = pa_uname_string();
736 pa_log_debug(_("Running on host: %s"), s);
737 pa_xfree(s);
738
739 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
740
741 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
742
743 #ifdef HAVE_VALGRIND_MEMCHECK_H
744 pa_log_debug(_("Compiled with Valgrind support: yes"));
745 #else
746 pa_log_debug(_("Compiled with Valgrind support: no"));
747 #endif
748
749 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
750
751 #ifdef __OPTIMIZE__
752 pa_log_debug(_("Optimized build: yes"));
753 #else
754 pa_log_debug(_("Optimized build: no"));
755 #endif
756
757 #ifdef NDEBUG
758 pa_log_debug(_("NDEBUG defined, all asserts disabled."));
759 #elif defined(FASTPATH)
760 pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
761 #else
762 pa_log_debug(_("All asserts enabled."));
763 #endif
764
765 if (!(s = pa_machine_id())) {
766 pa_log(_("Failed to get machine ID"));
767 goto finish;
768 }
769 pa_log_info(_("Machine ID is %s."), s);
770 pa_xfree(s);
771
772 if ((s = pa_session_id())) {
773 pa_log_info(_("Session ID is %s."), s);
774 pa_xfree(s);
775 }
776
777 if (!(s = pa_get_runtime_dir()))
778 goto finish;
779 pa_log_info(_("Using runtime directory %s."), s);
780 pa_xfree(s);
781
782 if (!(s = pa_get_state_dir()))
783 goto finish;
784 pa_log_info(_("Using state directory %s."), s);
785 pa_xfree(s);
786
787 pa_log_info(_("Using modules directory %s."), conf->dl_search_path);
788
789 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
790
791 if (pa_in_system_mode())
792 pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
793 "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
794 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
795
796 if (conf->use_pid_file) {
797 int z;
798
799 if ((z = pa_pid_file_create("pulseaudio")) != 0) {
800
801 if (conf->cmd == PA_CMD_START && z > 0) {
802 /* If we are already running and with are run in
803 * --start mode, then let's return this as success. */
804
805 retval = 0;
806 goto finish;
807 }
808
809 pa_log(_("pa_pid_file_create() failed."));
810 goto finish;
811 }
812
813 valid_pid_file = TRUE;
814 }
815
816 pa_disable_sigpipe();
817
818 if (pa_rtclock_hrtimer())
819 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
820 else
821 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
822
823 if (conf->lock_memory) {
824 #ifdef HAVE_SYS_MMAN_H
825 if (mlockall(MCL_FUTURE) < 0)
826 pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
827 else
828 pa_log_info("Sucessfully locked process into memory.");
829 #else
830 pa_log_warn("Memory locking requested but not supported on platform.");
831 #endif
832 }
833
834 pa_memtrap_install();
835
836 if (!getenv("PULSE_NO_SIMD")) {
837 pa_cpu_init_x86();
838 pa_cpu_init_arm();
839 }
840
841 pa_assert_se(mainloop = pa_mainloop_new());
842
843 if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
844 pa_log(_("pa_core_new() failed."));
845 goto finish;
846 }
847
848 c->default_sample_spec = conf->default_sample_spec;
849 c->default_channel_map = conf->default_channel_map;
850 c->default_n_fragments = conf->default_n_fragments;
851 c->default_fragment_size_msec = conf->default_fragment_size_msec;
852 c->exit_idle_time = conf->exit_idle_time;
853 c->scache_idle_time = conf->scache_idle_time;
854 c->resample_method = conf->resample_method;
855 c->realtime_priority = conf->realtime_priority;
856 c->realtime_scheduling = !!conf->realtime_scheduling;
857 c->disable_remixing = !!conf->disable_remixing;
858 c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
859 c->running_as_daemon = !!conf->daemonize;
860 c->disallow_exit = conf->disallow_exit;
861 c->flat_volumes = conf->flat_volumes;
862
863 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
864 pa_signal_new(SIGINT, signal_callback, c);
865 pa_signal_new(SIGTERM, signal_callback, c);
866 #ifdef SIGUSR1
867 pa_signal_new(SIGUSR1, signal_callback, c);
868 #endif
869 #ifdef SIGUSR2
870 pa_signal_new(SIGUSR2, signal_callback, c);
871 #endif
872 #ifdef SIGHUP
873 pa_signal_new(SIGHUP, signal_callback, c);
874 #endif
875
876 #ifdef OS_IS_WIN32
877 win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
878 #endif
879
880 if (!conf->no_cpu_limit)
881 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
882
883 buf = pa_strbuf_new();
884 if (conf->load_default_script_file) {
885 FILE *f;
886
887 if ((f = pa_daemon_conf_open_default_script_file(conf))) {
888 r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
889 fclose(f);
890 }
891 }
892
893 if (r >= 0)
894 r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
895
896 pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
897 pa_xfree(s);
898
899 /* We completed the initial module loading, so let's disable it
900 * from now on, if requested */
901 c->disallow_module_loading = !!conf->disallow_module_loading;
902
903 if (r < 0 && conf->fail) {
904 pa_log(_("Failed to initialize daemon."));
905 goto finish;
906 }
907
908 if (!c->modules || pa_idxset_size(c->modules) == 0) {
909 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
910 goto finish;
911 }
912
913 #ifdef HAVE_FORK
914 if (daemon_pipe[1] >= 0) {
915 int ok = 0;
916 pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
917 pa_close(daemon_pipe[1]);
918 daemon_pipe[1] = -1;
919 }
920 #endif
921
922 #ifdef HAVE_DBUS
923 dbus = register_dbus(c);
924 #endif
925
926 pa_log_info(_("Daemon startup complete."));
927
928 retval = 0;
929 if (pa_mainloop_run(mainloop, &retval) < 0)
930 goto finish;
931
932 pa_log_info(_("Daemon shutdown initiated."));
933
934 finish:
935 #ifdef HAVE_DBUS
936 if (dbus)
937 pa_dbus_connection_unref(dbus);
938 #endif
939
940 if (autospawn_fd >= 0) {
941 if (autospawn_locked)
942 pa_autospawn_lock_release();
943
944 pa_autospawn_lock_done(FALSE);
945 }
946
947 #ifdef OS_IS_WIN32
948 if (win32_timer)
949 pa_mainloop_get_api(mainloop)->time_free(win32_timer);
950 #endif
951
952 if (c) {
953 pa_core_unref(c);
954 pa_log_info(_("Daemon terminated."));
955 }
956
957 if (!conf->no_cpu_limit)
958 pa_cpu_limit_done();
959
960 pa_signal_done();
961
962 #ifdef HAVE_FORK
963 if (daemon_pipe[1] >= 0)
964 pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
965
966 pa_close_pipe(daemon_pipe);
967 #endif
968
969 if (mainloop)
970 pa_mainloop_free(mainloop);
971
972 if (conf)
973 pa_daemon_conf_free(conf);
974
975 if (valid_pid_file)
976 pa_pid_file_remove();
977
978 /* This has no real purpose except making things valgrind-clean */
979 pa_unset_env_recorded();
980
981 #ifdef OS_IS_WIN32
982 WSACleanup();
983 #endif
984
985 if (ltdl_init)
986 pa_ltdl_done();
987
988 #ifdef HAVE_DBUS
989 dbus_shutdown();
990 #endif
991
992 return retval;
993 }