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