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