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