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