]> code.delx.au - pulseaudio/blob - src/daemon/main.c
Merge commit 'coling/lgpl21'
[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 set_one_rlimit(&conf->rlimit_rss, RLIMIT_RSS, "RLIMIT_RSS");
298 #ifdef RLIMIT_NPROC
299 set_one_rlimit(&conf->rlimit_nproc, RLIMIT_NPROC, "RLIMIT_NPROC");
300 #endif
301 #ifdef RLIMIT_NOFILE
302 set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
303 #endif
304 #ifdef RLIMIT_MEMLOCK
305 set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
306 #endif
307 #ifdef RLIMIT_AS
308 set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
309 #endif
310 #ifdef RLIMIT_LOCKS
311 set_one_rlimit(&conf->rlimit_locks, RLIMIT_LOCKS, "RLIMIT_LOCKS");
312 #endif
313 #ifdef RLIMIT_SIGPENDING
314 set_one_rlimit(&conf->rlimit_sigpending, RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING");
315 #endif
316 #ifdef RLIMIT_MSGQUEUE
317 set_one_rlimit(&conf->rlimit_msgqueue, RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE");
318 #endif
319 #ifdef RLIMIT_NICE
320 set_one_rlimit(&conf->rlimit_nice, RLIMIT_NICE, "RLIMIT_NICE");
321 #endif
322 #ifdef RLIMIT_RTPRIO
323 set_one_rlimit(&conf->rlimit_rtprio, RLIMIT_RTPRIO, "RLIMIT_RTPRIO");
324 #endif
325 #ifdef RLIMIT_RTTIME
326 set_one_rlimit(&conf->rlimit_rttime, RLIMIT_RTTIME, "RLIMIT_RTTIME");
327 #endif
328 }
329 #endif
330
331 int main(int argc, char *argv[]) {
332 pa_core *c = NULL;
333 pa_strbuf *buf = NULL;
334 pa_daemon_conf *conf = NULL;
335 pa_mainloop *mainloop = NULL;
336 char *s;
337 int r = 0, retval = 1, d = 0;
338 pa_bool_t suid_root, real_root;
339 pa_bool_t valid_pid_file = FALSE;
340 gid_t gid = (gid_t) -1;
341 pa_bool_t ltdl_init = FALSE;
342 int passed_fd = -1;
343 const char *e;
344 #ifdef HAVE_FORK
345 int daemon_pipe[2] = { -1, -1 };
346 #endif
347 #ifdef OS_IS_WIN32
348 pa_time_event *win32_timer;
349 struct timeval win32_tv;
350 #endif
351 int autospawn_fd = -1;
352 pa_bool_t autospawn_locked = FALSE;
353
354 pa_log_set_ident("pulseaudio");
355 pa_log_set_level(PA_LOG_INFO);
356 pa_log_set_flags(PA_LOG_COLORS|PA_LOG_PRINT_FILE|PA_LOG_PRINT_LEVEL, PA_LOG_RESET);
357
358 #if defined(__linux__) && defined(__OPTIMIZE__)
359 /*
360 Disable lazy relocations to make usage of external libraries
361 more deterministic for our RT threads. We abuse __OPTIMIZE__ as
362 a check whether we are a debug build or not.
363 */
364
365 if (!getenv("LD_BIND_NOW")) {
366 char *rp;
367
368 /* We have to execute ourselves, because the libc caches the
369 * value of $LD_BIND_NOW on initialization. */
370
371 pa_set_env("LD_BIND_NOW", "1");
372
373 if ((rp = pa_readlink("/proc/self/exe")))
374 pa_assert_se(execv(rp, argv) == 0);
375 else
376 pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
377 }
378 #endif
379
380 #ifdef HAVE_GETUID
381 real_root = getuid() == 0;
382 suid_root = !real_root && geteuid() == 0;
383 #else
384 real_root = FALSE;
385 suid_root = FALSE;
386 #endif
387
388 if (!real_root) {
389 /* Drop all capabilities except CAP_SYS_NICE */
390 pa_limit_caps();
391
392 /* Drop privileges, but keep CAP_SYS_NICE */
393 pa_drop_root();
394
395 /* After dropping root, the effective set is reset, hence,
396 * let's raise it again */
397 pa_limit_caps();
398
399 /* When capabilities are not supported we will not be able to
400 * aquire RT sched anymore. But yes, that's the way it is. It
401 * is just too risky tun let PA run as root all the time. */
402 }
403
404 if ((e = getenv("PULSE_PASSED_FD"))) {
405 passed_fd = atoi(e);
406
407 if (passed_fd <= 2)
408 passed_fd = -1;
409 }
410
411 pa_close_all(passed_fd, -1);
412
413 pa_reset_sigs(-1);
414 pa_unblock_sigs(-1);
415
416 /* At this point, we are a normal user, possibly with CAP_NICE if
417 * we were started SUID. If we are started as normal root, than we
418 * still are normal root. */
419
420 setlocale(LC_ALL, "");
421 pa_init_i18n();
422
423 conf = pa_daemon_conf_new();
424
425 if (pa_daemon_conf_load(conf, NULL) < 0)
426 goto finish;
427
428 if (pa_daemon_conf_env(conf) < 0)
429 goto finish;
430
431 if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
432 pa_log(_("Failed to parse command line."));
433 goto finish;
434 }
435
436 pa_log_set_level(conf->log_level);
437 pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target);
438 if (conf->log_meta)
439 pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
440 if (conf->log_time)
441 pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
442 pa_log_set_show_backtrace(conf->log_backtrace);
443
444 pa_log_debug("Started as real root: %s, suid root: %s", pa_yes_no(real_root), pa_yes_no(suid_root));
445
446 if (!real_root && pa_have_caps()) {
447 #ifdef HAVE_SYS_RESOURCE_H
448 struct rlimit rl;
449 #endif
450 pa_bool_t allow_high_priority = FALSE, allow_realtime = FALSE;
451
452 /* Let's better not enable high prio or RT by default */
453
454 if (conf->high_priority && !allow_high_priority) {
455 if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
456 pa_log_info(_("We're in the group '%s', allowing high-priority scheduling."), PA_REALTIME_GROUP);
457 allow_high_priority = TRUE;
458 }
459 }
460
461 if (conf->realtime_scheduling && !allow_realtime) {
462 if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
463 pa_log_info(_("We're in the group '%s', allowing real-time scheduling."), PA_REALTIME_GROUP);
464 allow_realtime = TRUE;
465 }
466 }
467
468 #ifdef HAVE_POLKIT
469 if (conf->high_priority && !allow_high_priority) {
470 if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) {
471 pa_log_info(_("PolicyKit grants us acquire-high-priority privilege."));
472 allow_high_priority = TRUE;
473 } else
474 pa_log_info(_("PolicyKit refuses acquire-high-priority privilege."));
475 }
476
477 if (conf->realtime_scheduling && !allow_realtime) {
478 if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) {
479 pa_log_info(_("PolicyKit grants us acquire-real-time privilege."));
480 allow_realtime = TRUE;
481 } else
482 pa_log_info(_("PolicyKit refuses acquire-real-time privilege."));
483 }
484 #endif
485
486 if (!allow_high_priority && !allow_realtime) {
487
488 /* OK, there's no further need to keep CAP_NICE. Hence
489 * let's give it up early */
490
491 pa_drop_caps();
492 }
493
494 #ifdef RLIMIT_RTPRIO
495 if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0)
496 if (rl.rlim_cur > 0) {
497 pa_log_info("RLIMIT_RTPRIO is set to %u, allowing real-time scheduling.", (unsigned) rl.rlim_cur);
498 allow_realtime = TRUE;
499 }
500 #endif
501 #ifdef RLIMIT_NICE
502 if (getrlimit(RLIMIT_NICE, &rl) >= 0)
503 if (rl.rlim_cur > 20 ) {
504 pa_log_info("RLIMIT_NICE is set to %u, allowing high-priority scheduling.", (unsigned) rl.rlim_cur);
505 allow_high_priority = TRUE;
506 }
507 #endif
508
509 if ((conf->high_priority && !allow_high_priority) ||
510 (conf->realtime_scheduling && !allow_realtime))
511 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"
512 "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"
513 "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."),
514 PA_REALTIME_GROUP, PA_REALTIME_GROUP);
515
516
517 if (!allow_realtime)
518 conf->realtime_scheduling = FALSE;
519
520 if (!allow_high_priority)
521 conf->high_priority = FALSE;
522 }
523
524 #ifdef HAVE_SYS_RESOURCE_H
525 /* Reset resource limits. If we are run as root (for system mode)
526 * this might end up increasing the limits, which is intended
527 * behaviour. For all other cases, i.e. started as normal user, or
528 * SUID root at this point we should have no CAP_SYS_RESOURCE and
529 * increasing the limits thus should fail. Which is, too, intended
530 * behaviour */
531
532 set_all_rlimits(conf);
533 #endif
534
535 if (conf->high_priority && !pa_can_high_priority()) {
536 pa_log_warn(_("High-priority scheduling enabled in configuration but not allowed by policy."));
537 conf->high_priority = FALSE;
538 }
539
540 if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))
541 pa_raise_priority(conf->nice_level);
542
543 pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
544
545 if (!real_root && pa_have_caps()) {
546 pa_bool_t drop;
547
548 drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling;
549
550 #ifdef RLIMIT_RTPRIO
551 if (!drop) {
552 struct rlimit rl;
553 /* At this point we still have CAP_NICE if we were loaded
554 * SUID root. If possible let's acquire RLIMIT_RTPRIO
555 * instead and give CAP_NICE up. */
556
557 if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
558
559 if (rl.rlim_cur >= 9)
560 drop = TRUE;
561 else {
562 rl.rlim_max = rl.rlim_cur = 9;
563
564 if (setrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
565 pa_log_info(_("Successfully increased RLIMIT_RTPRIO"));
566 drop = TRUE;
567 } else
568 pa_log_warn(_("RLIMIT_RTPRIO failed: %s"), pa_cstrerror(errno));
569 }
570 }
571 }
572 #endif
573
574 if (drop) {
575 pa_log_info(_("Giving up CAP_NICE"));
576 pa_drop_caps();
577 suid_root = FALSE;
578 }
579 }
580
581 if (conf->realtime_scheduling && !pa_can_realtime()) {
582 pa_log_warn(_("Real-time scheduling enabled in configuration but not allowed by policy."));
583 conf->realtime_scheduling = FALSE;
584 }
585
586 pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
587
588 LTDL_SET_PRELOADED_SYMBOLS();
589 pa_ltdl_init();
590 ltdl_init = TRUE;
591
592 if (conf->dl_search_path)
593 lt_dlsetsearchpath(conf->dl_search_path);
594
595 #ifdef OS_IS_WIN32
596 {
597 WSADATA data;
598 WSAStartup(MAKEWORD(2, 0), &data);
599 }
600 #endif
601
602 pa_random_seed();
603
604 switch (conf->cmd) {
605 case PA_CMD_DUMP_MODULES:
606 pa_dump_modules(conf, argc-d, argv+d);
607 retval = 0;
608 goto finish;
609
610 case PA_CMD_DUMP_CONF: {
611 s = pa_daemon_conf_dump(conf);
612 fputs(s, stdout);
613 pa_xfree(s);
614 retval = 0;
615 goto finish;
616 }
617
618 case PA_CMD_DUMP_RESAMPLE_METHODS: {
619 int i;
620
621 for (i = 0; i < PA_RESAMPLER_MAX; i++)
622 if (pa_resample_method_supported(i))
623 printf("%s\n", pa_resample_method_to_string(i));
624
625 retval = 0;
626 goto finish;
627 }
628
629 case PA_CMD_HELP :
630 pa_cmdline_help(argv[0]);
631 retval = 0;
632 goto finish;
633
634 case PA_CMD_VERSION :
635 printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
636 retval = 0;
637 goto finish;
638
639 case PA_CMD_CHECK: {
640 pid_t pid;
641
642 if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
643 pa_log_info(_("Daemon not running"));
644 else {
645 pa_log_info(_("Daemon running as PID %u"), pid);
646 retval = 0;
647 }
648
649 goto finish;
650
651 }
652 case PA_CMD_KILL:
653
654 if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
655 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
656 else
657 retval = 0;
658
659 goto finish;
660
661 case PA_CMD_CLEANUP_SHM:
662
663 if (pa_shm_cleanup() >= 0)
664 retval = 0;
665
666 goto finish;
667
668 default:
669 pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
670 }
671
672 if (real_root && !conf->system_instance)
673 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
674 else if (!real_root && conf->system_instance) {
675 pa_log(_("Root privileges required."));
676 goto finish;
677 }
678
679 if (conf->cmd == PA_CMD_START && conf->system_instance) {
680 pa_log(_("--start not supported for system instances."));
681 goto finish;
682 }
683
684 if (conf->system_instance && !conf->disallow_exit)
685 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
686
687 if (conf->system_instance && !conf->disallow_module_loading)
688 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
689
690 if (conf->system_instance && !conf->disable_shm) {
691 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
692 conf->disable_shm = TRUE;
693 }
694
695 if (conf->system_instance && conf->exit_idle_time >= 0) {
696 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
697 conf->exit_idle_time = -1;
698 }
699
700 if (conf->cmd == PA_CMD_START) {
701 /* If we shall start PA only when it is not running yet, we
702 * first take the autospawn lock to make things
703 * synchronous. */
704
705 if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
706 pa_log("Failed to initialize autospawn lock");
707 goto finish;
708 }
709
710 if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
711 pa_log("Failed to acquire autospawn lock");
712 goto finish;
713 }
714
715 autospawn_locked = TRUE;
716 }
717
718 if (conf->daemonize) {
719 pid_t child;
720 int tty_fd;
721
722 if (pa_stdio_acquire() < 0) {
723 pa_log(_("Failed to acquire stdio."));
724 goto finish;
725 }
726
727 #ifdef HAVE_FORK
728 if (pipe(daemon_pipe) < 0) {
729 pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
730 goto finish;
731 }
732
733 if ((child = fork()) < 0) {
734 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
735 goto finish;
736 }
737
738 if (child != 0) {
739 ssize_t n;
740 /* Father */
741
742 pa_assert_se(pa_close(daemon_pipe[1]) == 0);
743 daemon_pipe[1] = -1;
744
745 if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
746
747 if (n < 0)
748 pa_log(_("read() failed: %s"), pa_cstrerror(errno));
749
750 retval = 1;
751 }
752
753 if (retval)
754 pa_log(_("Daemon startup failed."));
755 else
756 pa_log_info(_("Daemon startup successful."));
757
758 goto finish;
759 }
760
761 if (autospawn_fd >= 0) {
762 /* The lock file is unlocked from the parent, so we need
763 * to close it in the child */
764
765 pa_autospawn_lock_release();
766 pa_autospawn_lock_done(TRUE);
767
768 autospawn_locked = FALSE;
769 autospawn_fd = -1;
770 }
771
772 pa_assert_se(pa_close(daemon_pipe[0]) == 0);
773 daemon_pipe[0] = -1;
774 #endif
775
776 if (conf->auto_log_target)
777 pa_log_set_target(PA_LOG_SYSLOG);
778
779 #ifdef HAVE_SETSID
780 setsid();
781 #endif
782 #ifdef HAVE_SETPGID
783 setpgid(0,0);
784 #endif
785
786 #ifndef OS_IS_WIN32
787 pa_close(0);
788 pa_close(1);
789 pa_close(2);
790
791 pa_assert_se(open("/dev/null", O_RDONLY) == 0);
792 pa_assert_se(open("/dev/null", O_WRONLY) == 1);
793 pa_assert_se(open("/dev/null", O_WRONLY) == 2);
794 #else
795 FreeConsole();
796 #endif
797
798 #ifdef SIGTTOU
799 signal(SIGTTOU, SIG_IGN);
800 #endif
801 #ifdef SIGTTIN
802 signal(SIGTTIN, SIG_IGN);
803 #endif
804 #ifdef SIGTSTP
805 signal(SIGTSTP, SIG_IGN);
806 #endif
807
808 #ifdef TIOCNOTTY
809 if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
810 ioctl(tty_fd, TIOCNOTTY, (char*) 0);
811 pa_assert_se(pa_close(tty_fd) == 0);
812 }
813 #endif
814 }
815
816 pa_set_env("PULSE_INTERNAL", "1");
817 pa_assert_se(chdir("/") == 0);
818 umask(0022);
819
820 if (conf->system_instance)
821 if (change_user() < 0)
822 goto finish;
823
824 pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
825
826 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
827 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
828 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
829
830 s = pa_uname_string();
831 pa_log_debug(_("Running on host: %s"), s);
832 pa_xfree(s);
833
834 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
835
836 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
837
838 #ifdef HAVE_VALGRIND_MEMCHECK_H
839 pa_log_debug(_("Compiled with Valgrind support: yes"));
840 #else
841 pa_log_debug(_("Compiled with Valgrind support: no"));
842 #endif
843
844 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
845
846 #ifdef __OPTIMIZE__
847 pa_log_debug(_("Optimized build: yes"));
848 #else
849 pa_log_debug(_("Optimized build: no"));
850 #endif
851
852 if (!(s = pa_machine_id())) {
853 pa_log(_("Failed to get machine ID"));
854 goto finish;
855 }
856 pa_log_info(_("Machine ID is %s."), s);
857 pa_xfree(s);
858
859 if (!(s = pa_get_runtime_dir()))
860 goto finish;
861 pa_log_info(_("Using runtime directory %s."), s);
862 pa_xfree(s);
863
864 if (!(s = pa_get_state_dir()))
865 goto finish;
866 pa_log_info(_("Using state directory %s."), s);
867 pa_xfree(s);
868
869 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
870
871 if (conf->use_pid_file) {
872 int z;
873
874 if ((z = pa_pid_file_create("pulseaudio")) != 0) {
875
876 if (conf->cmd == PA_CMD_START && z > 0) {
877 /* If we are already running and with are run in
878 * --start mode, then let's return this as success. */
879
880 retval = 0;
881 goto finish;
882 }
883
884 pa_log(_("pa_pid_file_create() failed."));
885 goto finish;
886 }
887
888 valid_pid_file = TRUE;
889 }
890
891 #ifdef SIGPIPE
892 signal(SIGPIPE, SIG_IGN);
893 #endif
894
895 if (pa_rtclock_hrtimer())
896 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
897 else
898 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
899
900 pa_rtclock_hrtimer_enable();
901
902 #ifdef SIGRTMIN
903 /* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */
904 pa_rtsig_configure(SIGRTMIN, SIGRTMAX-1);
905 #endif
906
907 pa_assert_se(mainloop = pa_mainloop_new());
908
909 if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
910 pa_log(_("pa_core_new() failed."));
911 goto finish;
912 }
913
914 c->default_sample_spec = conf->default_sample_spec;
915 c->default_channel_map = conf->default_channel_map;
916 c->default_n_fragments = conf->default_n_fragments;
917 c->default_fragment_size_msec = conf->default_fragment_size_msec;
918 c->exit_idle_time = conf->exit_idle_time;
919 c->scache_idle_time = conf->scache_idle_time;
920 c->resample_method = conf->resample_method;
921 c->realtime_priority = conf->realtime_priority;
922 c->realtime_scheduling = !!conf->realtime_scheduling;
923 c->disable_remixing = !!conf->disable_remixing;
924 c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
925 c->running_as_daemon = !!conf->daemonize;
926 c->disallow_exit = conf->disallow_exit;
927 c->flat_volumes = conf->flat_volumes;
928
929 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
930 pa_signal_new(SIGINT, signal_callback, c);
931 pa_signal_new(SIGTERM, signal_callback, c);
932 #ifdef SIGUSR1
933 pa_signal_new(SIGUSR1, signal_callback, c);
934 #endif
935 #ifdef SIGUSR2
936 pa_signal_new(SIGUSR2, signal_callback, c);
937 #endif
938 #ifdef SIGHUP
939 pa_signal_new(SIGHUP, signal_callback, c);
940 #endif
941
942 #ifdef OS_IS_WIN32
943 win32_timer = pa_mainloop_get_api(mainloop)->time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
944 #endif
945
946 oil_init();
947
948 if (!conf->no_cpu_limit)
949 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
950
951 buf = pa_strbuf_new();
952 if (conf->load_default_script_file) {
953 FILE *f;
954
955 if ((f = pa_daemon_conf_open_default_script_file(conf))) {
956 r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
957 fclose(f);
958 }
959 }
960
961 if (r >= 0)
962 r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
963
964 pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
965 pa_xfree(s);
966
967 /* We completed the initial module loading, so let's disable it
968 * from now on, if requested */
969 c->disallow_module_loading = !!conf->disallow_module_loading;
970
971 if (r < 0 && conf->fail) {
972 pa_log(_("Failed to initialize daemon."));
973 goto finish;
974 }
975
976 if (!c->modules || pa_idxset_size(c->modules) == 0) {
977 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
978 goto finish;
979 }
980
981 #ifdef HAVE_FORK
982 if (daemon_pipe[1] >= 0) {
983 int ok = 0;
984 pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
985 pa_close(daemon_pipe[1]);
986 daemon_pipe[1] = -1;
987 }
988 #endif
989
990 pa_log_info(_("Daemon startup complete."));
991
992 retval = 0;
993 if (pa_mainloop_run(mainloop, &retval) < 0)
994 goto finish;
995
996 pa_log_info(_("Daemon shutdown initiated."));
997
998 finish:
999
1000 if (autospawn_fd >= 0) {
1001 if (autospawn_locked)
1002 pa_autospawn_lock_release();
1003
1004 pa_autospawn_lock_done(FALSE);
1005 }
1006
1007 #ifdef OS_IS_WIN32
1008 if (win32_timer)
1009 pa_mainloop_get_api(mainloop)->time_free(win32_timer);
1010 #endif
1011
1012 if (c) {
1013 pa_core_unref(c);
1014 pa_log_info(_("Daemon terminated."));
1015 }
1016
1017 if (!conf->no_cpu_limit)
1018 pa_cpu_limit_done();
1019
1020 pa_signal_done();
1021
1022 #ifdef HAVE_FORK
1023 if (daemon_pipe[1] >= 0)
1024 pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
1025
1026 pa_close_pipe(daemon_pipe);
1027 #endif
1028
1029 if (mainloop)
1030 pa_mainloop_free(mainloop);
1031
1032 if (conf)
1033 pa_daemon_conf_free(conf);
1034
1035 if (valid_pid_file)
1036 pa_pid_file_remove();
1037
1038 #ifdef OS_IS_WIN32
1039 WSACleanup();
1040 #endif
1041
1042 if (ltdl_init)
1043 pa_ltdl_done();
1044
1045 #ifdef HAVE_DBUS
1046 dbus_shutdown();
1047 #endif
1048
1049 return retval;
1050 }