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