]> code.delx.au - pulseaudio/blob - src/daemon/main.c
Merge commit 'flameeyes/master'
[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
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 ((e = getenv("PULSE_PASSED_FD"))) {
405 passed_fd = atoi(e);
406
407 if (passed_fd <= 2)
408 passed_fd = -1;
409 }
410
411 /* We might be autospawned, in which case have no idea in which
412 * context we have been started. Let's cleanup our execution
413 * context as good as possible */
414 pa_drop_root();
415 pa_close_all(passed_fd, -1);
416 pa_reset_sigs(-1);
417 pa_unblock_sigs(-1);
418
419 setlocale(LC_ALL, "");
420 pa_init_i18n();
421
422 conf = pa_daemon_conf_new();
423
424 if (pa_daemon_conf_load(conf, NULL) < 0)
425 goto finish;
426
427 if (pa_daemon_conf_env(conf) < 0)
428 goto finish;
429
430 if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
431 pa_log(_("Failed to parse command line."));
432 goto finish;
433 }
434
435 pa_log_set_level(conf->log_level);
436 pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target);
437 if (conf->log_meta)
438 pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
439 if (conf->log_time)
440 pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
441 pa_log_set_show_backtrace(conf->log_backtrace);
442
443 LTDL_SET_PRELOADED_SYMBOLS();
444 pa_ltdl_init();
445 ltdl_init = TRUE;
446
447 if (conf->dl_search_path)
448 lt_dlsetsearchpath(conf->dl_search_path);
449
450 #ifdef OS_IS_WIN32
451 {
452 WSADATA data;
453 WSAStartup(MAKEWORD(2, 0), &data);
454 }
455 #endif
456
457 pa_random_seed();
458
459 switch (conf->cmd) {
460 case PA_CMD_DUMP_MODULES:
461 pa_dump_modules(conf, argc-d, argv+d);
462 retval = 0;
463 goto finish;
464
465 case PA_CMD_DUMP_CONF: {
466 s = pa_daemon_conf_dump(conf);
467 fputs(s, stdout);
468 pa_xfree(s);
469 retval = 0;
470 goto finish;
471 }
472
473 case PA_CMD_DUMP_RESAMPLE_METHODS: {
474 int i;
475
476 for (i = 0; i < PA_RESAMPLER_MAX; i++)
477 if (pa_resample_method_supported(i))
478 printf("%s\n", pa_resample_method_to_string(i));
479
480 retval = 0;
481 goto finish;
482 }
483
484 case PA_CMD_HELP :
485 pa_cmdline_help(argv[0]);
486 retval = 0;
487 goto finish;
488
489 case PA_CMD_VERSION :
490 printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
491 retval = 0;
492 goto finish;
493
494 case PA_CMD_CHECK: {
495 pid_t pid;
496
497 if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
498 pa_log_info(_("Daemon not running"));
499 else {
500 pa_log_info(_("Daemon running as PID %u"), pid);
501 retval = 0;
502 }
503
504 goto finish;
505
506 }
507 case PA_CMD_KILL:
508
509 if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
510 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
511 else
512 retval = 0;
513
514 goto finish;
515
516 case PA_CMD_CLEANUP_SHM:
517
518 if (pa_shm_cleanup() >= 0)
519 retval = 0;
520
521 goto finish;
522
523 default:
524 pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
525 }
526
527 if (getuid() == 0 && !conf->system_instance)
528 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
529 else if (getuid() != 0 && conf->system_instance) {
530 pa_log(_("Root privileges required."));
531 goto finish;
532 }
533
534 if (conf->cmd == PA_CMD_START && conf->system_instance) {
535 pa_log(_("--start not supported for system instances."));
536 goto finish;
537 }
538
539 if (conf->system_instance && !conf->disallow_exit)
540 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
541
542 if (conf->system_instance && !conf->disallow_module_loading)
543 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
544
545 if (conf->system_instance && !conf->disable_shm) {
546 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
547 conf->disable_shm = TRUE;
548 }
549
550 if (conf->system_instance && conf->exit_idle_time >= 0) {
551 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
552 conf->exit_idle_time = -1;
553 }
554
555 if (conf->cmd == PA_CMD_START) {
556 /* If we shall start PA only when it is not running yet, we
557 * first take the autospawn lock to make things
558 * synchronous. */
559
560 if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
561 pa_log("Failed to initialize autospawn lock");
562 goto finish;
563 }
564
565 if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
566 pa_log("Failed to acquire autospawn lock");
567 goto finish;
568 }
569
570 autospawn_locked = TRUE;
571 }
572
573 if (conf->daemonize) {
574 pid_t child;
575 int tty_fd;
576
577 if (pa_stdio_acquire() < 0) {
578 pa_log(_("Failed to acquire stdio."));
579 goto finish;
580 }
581
582 #ifdef HAVE_FORK
583 if (pipe(daemon_pipe) < 0) {
584 pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
585 goto finish;
586 }
587
588 if ((child = fork()) < 0) {
589 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
590 goto finish;
591 }
592
593 if (child != 0) {
594 ssize_t n;
595 /* Father */
596
597 pa_assert_se(pa_close(daemon_pipe[1]) == 0);
598 daemon_pipe[1] = -1;
599
600 if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
601
602 if (n < 0)
603 pa_log(_("read() failed: %s"), pa_cstrerror(errno));
604
605 retval = 1;
606 }
607
608 if (retval)
609 pa_log(_("Daemon startup failed."));
610 else
611 pa_log_info(_("Daemon startup successful."));
612
613 goto finish;
614 }
615
616 if (autospawn_fd >= 0) {
617 /* The lock file is unlocked from the parent, so we need
618 * to close it in the child */
619
620 pa_autospawn_lock_release();
621 pa_autospawn_lock_done(TRUE);
622
623 autospawn_locked = FALSE;
624 autospawn_fd = -1;
625 }
626
627 pa_assert_se(pa_close(daemon_pipe[0]) == 0);
628 daemon_pipe[0] = -1;
629 #endif
630
631 if (conf->auto_log_target)
632 pa_log_set_target(PA_LOG_SYSLOG);
633
634 #ifdef HAVE_SETSID
635 setsid();
636 #endif
637 #ifdef HAVE_SETPGID
638 setpgid(0,0);
639 #endif
640
641 #ifndef OS_IS_WIN32
642 pa_close(0);
643 pa_close(1);
644 pa_close(2);
645
646 pa_assert_se(open("/dev/null", O_RDONLY) == 0);
647 pa_assert_se(open("/dev/null", O_WRONLY) == 1);
648 pa_assert_se(open("/dev/null", O_WRONLY) == 2);
649 #else
650 FreeConsole();
651 #endif
652
653 #ifdef SIGTTOU
654 signal(SIGTTOU, SIG_IGN);
655 #endif
656 #ifdef SIGTTIN
657 signal(SIGTTIN, SIG_IGN);
658 #endif
659 #ifdef SIGTSTP
660 signal(SIGTSTP, SIG_IGN);
661 #endif
662
663 #ifdef TIOCNOTTY
664 if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
665 ioctl(tty_fd, TIOCNOTTY, (char*) 0);
666 pa_assert_se(pa_close(tty_fd) == 0);
667 }
668 #endif
669 }
670
671 pa_set_env("PULSE_INTERNAL", "1");
672 pa_assert_se(chdir("/") == 0);
673 umask(0022);
674
675 #ifdef HAVE_SYS_RESOURCE_H
676 set_all_rlimits(conf);
677 #endif
678 pa_rtclock_hrtimer_enable();
679
680 pa_raise_priority(conf->nice_level);
681
682 if (conf->system_instance)
683 if (change_user() < 0)
684 goto finish;
685
686 pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
687
688 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
689 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
690 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
691
692 s = pa_uname_string();
693 pa_log_debug(_("Running on host: %s"), s);
694 pa_xfree(s);
695
696 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
697
698 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
699
700 #ifdef HAVE_VALGRIND_MEMCHECK_H
701 pa_log_debug(_("Compiled with Valgrind support: yes"));
702 #else
703 pa_log_debug(_("Compiled with Valgrind support: no"));
704 #endif
705
706 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
707
708 #ifdef __OPTIMIZE__
709 pa_log_debug(_("Optimized build: yes"));
710 #else
711 pa_log_debug(_("Optimized build: no"));
712 #endif
713
714 #ifdef NDEBUG
715 pa_log_debug(_("NDEBUG defined, all asserts disabled."));
716 #elif defined(FASTPATH)
717 pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
718 #else
719 pa_log_debug(_("All asserts enabled."));
720 #endif
721
722 if (!(s = pa_machine_id())) {
723 pa_log(_("Failed to get machine ID"));
724 goto finish;
725 }
726 pa_log_info(_("Machine ID is %s."), s);
727 pa_xfree(s);
728
729 if ((s = pa_session_id())) {
730 pa_log_info(_("Session ID is %s."), s);
731 pa_xfree(s);
732 }
733
734 if (!(s = pa_get_runtime_dir()))
735 goto finish;
736 pa_log_info(_("Using runtime directory %s."), s);
737 pa_xfree(s);
738
739 if (!(s = pa_get_state_dir()))
740 goto finish;
741 pa_log_info(_("Using state directory %s."), s);
742 pa_xfree(s);
743
744 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
745
746 if (pa_in_system_mode())
747 pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
748 "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
749 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
750
751 if (conf->use_pid_file) {
752 int z;
753
754 if ((z = pa_pid_file_create("pulseaudio")) != 0) {
755
756 if (conf->cmd == PA_CMD_START && z > 0) {
757 /* If we are already running and with are run in
758 * --start mode, then let's return this as success. */
759
760 retval = 0;
761 goto finish;
762 }
763
764 pa_log(_("pa_pid_file_create() failed."));
765 goto finish;
766 }
767
768 valid_pid_file = TRUE;
769 }
770
771 pa_disable_sigpipe();
772
773 if (pa_rtclock_hrtimer())
774 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
775 else
776 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
777
778 if (conf->lock_memory) {
779 #ifdef HAVE_SYS_MMAN_H
780 if (mlockall(MCL_FUTURE) < 0)
781 pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
782 else
783 pa_log_info("Sucessfully locked process into memory.");
784 #else
785 pa_log_warn("Memory locking requested but not supported on platform.");
786 #endif
787 }
788
789 pa_memtrap_install();
790
791 pa_assert_se(mainloop = pa_mainloop_new());
792
793 if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
794 pa_log(_("pa_core_new() failed."));
795 goto finish;
796 }
797
798 c->default_sample_spec = conf->default_sample_spec;
799 c->default_channel_map = conf->default_channel_map;
800 c->default_n_fragments = conf->default_n_fragments;
801 c->default_fragment_size_msec = conf->default_fragment_size_msec;
802 c->exit_idle_time = conf->exit_idle_time;
803 c->scache_idle_time = conf->scache_idle_time;
804 c->resample_method = conf->resample_method;
805 c->realtime_priority = conf->realtime_priority;
806 c->realtime_scheduling = !!conf->realtime_scheduling;
807 c->disable_remixing = !!conf->disable_remixing;
808 c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
809 c->running_as_daemon = !!conf->daemonize;
810 c->disallow_exit = conf->disallow_exit;
811 c->flat_volumes = conf->flat_volumes;
812
813 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
814 pa_signal_new(SIGINT, signal_callback, c);
815 pa_signal_new(SIGTERM, signal_callback, c);
816 #ifdef SIGUSR1
817 pa_signal_new(SIGUSR1, signal_callback, c);
818 #endif
819 #ifdef SIGUSR2
820 pa_signal_new(SIGUSR2, signal_callback, c);
821 #endif
822 #ifdef SIGHUP
823 pa_signal_new(SIGHUP, signal_callback, c);
824 #endif
825
826 #ifdef OS_IS_WIN32
827 win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
828 #endif
829
830 oil_init();
831
832 if (!conf->no_cpu_limit)
833 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
834
835 buf = pa_strbuf_new();
836 if (conf->load_default_script_file) {
837 FILE *f;
838
839 if ((f = pa_daemon_conf_open_default_script_file(conf))) {
840 r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
841 fclose(f);
842 }
843 }
844
845 if (r >= 0)
846 r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
847
848 pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
849 pa_xfree(s);
850
851 /* We completed the initial module loading, so let's disable it
852 * from now on, if requested */
853 c->disallow_module_loading = !!conf->disallow_module_loading;
854
855 if (r < 0 && conf->fail) {
856 pa_log(_("Failed to initialize daemon."));
857 goto finish;
858 }
859
860 if (!c->modules || pa_idxset_size(c->modules) == 0) {
861 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
862 goto finish;
863 }
864
865 #ifdef HAVE_FORK
866 if (daemon_pipe[1] >= 0) {
867 int ok = 0;
868 pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
869 pa_close(daemon_pipe[1]);
870 daemon_pipe[1] = -1;
871 }
872 #endif
873
874 #ifdef HAVE_DBUS
875 dbus = register_dbus(c);
876 #endif
877
878 pa_log_info(_("Daemon startup complete."));
879
880 retval = 0;
881 if (pa_mainloop_run(mainloop, &retval) < 0)
882 goto finish;
883
884 pa_log_info(_("Daemon shutdown initiated."));
885
886 finish:
887 #ifdef HAVE_DBUS
888 if (dbus)
889 pa_dbus_connection_unref(dbus);
890 #endif
891
892 if (autospawn_fd >= 0) {
893 if (autospawn_locked)
894 pa_autospawn_lock_release();
895
896 pa_autospawn_lock_done(FALSE);
897 }
898
899 #ifdef OS_IS_WIN32
900 if (win32_timer)
901 pa_mainloop_get_api(mainloop)->time_free(win32_timer);
902 #endif
903
904 if (c) {
905 pa_core_unref(c);
906 pa_log_info(_("Daemon terminated."));
907 }
908
909 if (!conf->no_cpu_limit)
910 pa_cpu_limit_done();
911
912 pa_signal_done();
913
914 #ifdef HAVE_FORK
915 if (daemon_pipe[1] >= 0)
916 pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
917
918 pa_close_pipe(daemon_pipe);
919 #endif
920
921 if (mainloop)
922 pa_mainloop_free(mainloop);
923
924 if (conf)
925 pa_daemon_conf_free(conf);
926
927 if (valid_pid_file)
928 pa_pid_file_remove();
929
930 #ifdef OS_IS_WIN32
931 WSACleanup();
932 #endif
933
934 if (ltdl_init)
935 pa_ltdl_done();
936
937 #ifdef HAVE_DBUS
938 dbus_shutdown();
939 #endif
940
941 return retval;
942 }