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