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