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