volume: add first mmx optimized function
[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_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     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
445     pa_reset_personality();
446     pa_drop_root();
447     pa_close_all(passed_fd, -1);
448     pa_reset_sigs(-1);
449     pa_unblock_sigs(-1);
450     pa_reset_priority();
451
452     setlocale(LC_ALL, "");
453     pa_init_i18n();
454
455     conf = pa_daemon_conf_new();
456
457     if (pa_daemon_conf_load(conf, NULL) < 0)
458         goto finish;
459
460     if (pa_daemon_conf_env(conf) < 0)
461         goto finish;
462
463     if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
464         pa_log(_("Failed to parse command line."));
465         goto finish;
466     }
467
468     pa_log_set_level(conf->log_level);
469     pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target);
470     if (conf->log_meta)
471         pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
472     if (conf->log_time)
473         pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
474     pa_log_set_show_backtrace(conf->log_backtrace);
475
476     LTDL_SET_PRELOADED_SYMBOLS();
477     pa_ltdl_init();
478     ltdl_init = TRUE;
479
480     if (conf->dl_search_path)
481         lt_dlsetsearchpath(conf->dl_search_path);
482
483 #ifdef OS_IS_WIN32
484     {
485         WSADATA data;
486         WSAStartup(MAKEWORD(2, 0), &data);
487     }
488 #endif
489
490     pa_random_seed();
491
492     switch (conf->cmd) {
493         case PA_CMD_DUMP_MODULES:
494             pa_dump_modules(conf, argc-d, argv+d);
495             retval = 0;
496             goto finish;
497
498         case PA_CMD_DUMP_CONF: {
499             s = pa_daemon_conf_dump(conf);
500             fputs(s, stdout);
501             pa_xfree(s);
502             retval = 0;
503             goto finish;
504         }
505
506         case PA_CMD_DUMP_RESAMPLE_METHODS: {
507             int i;
508
509             for (i = 0; i < PA_RESAMPLER_MAX; i++)
510                 if (pa_resample_method_supported(i))
511                     printf("%s\n", pa_resample_method_to_string(i));
512
513             retval = 0;
514             goto finish;
515         }
516
517         case PA_CMD_HELP :
518             pa_cmdline_help(argv[0]);
519             retval = 0;
520             goto finish;
521
522         case PA_CMD_VERSION :
523             printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
524             retval = 0;
525             goto finish;
526
527         case PA_CMD_CHECK: {
528             pid_t pid;
529
530             if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
531                 pa_log_info(_("Daemon not running"));
532             else {
533                 pa_log_info(_("Daemon running as PID %u"), pid);
534                 retval = 0;
535             }
536
537             goto finish;
538
539         }
540         case PA_CMD_KILL:
541
542             if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
543                 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
544             else
545                 retval = 0;
546
547             goto finish;
548
549         case PA_CMD_CLEANUP_SHM:
550
551             if (pa_shm_cleanup() >= 0)
552                 retval = 0;
553
554             goto finish;
555
556         default:
557             pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
558     }
559
560     if (getuid() == 0 && !conf->system_instance)
561         pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
562     else if (getuid() != 0 && conf->system_instance) {
563         pa_log(_("Root privileges required."));
564         goto finish;
565     }
566
567     if (conf->cmd == PA_CMD_START && conf->system_instance) {
568         pa_log(_("--start not supported for system instances."));
569         goto finish;
570     }
571
572     if (conf->system_instance && !conf->disallow_exit)
573         pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
574
575     if (conf->system_instance && !conf->disallow_module_loading)
576         pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
577
578     if (conf->system_instance && !conf->disable_shm) {
579         pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
580         conf->disable_shm = TRUE;
581     }
582
583     if (conf->system_instance && conf->exit_idle_time >= 0) {
584         pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
585         conf->exit_idle_time = -1;
586     }
587
588     if (conf->cmd == PA_CMD_START) {
589         /* If we shall start PA only when it is not running yet, we
590          * first take the autospawn lock to make things
591          * synchronous. */
592
593         if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
594             pa_log("Failed to initialize autospawn lock");
595             goto finish;
596         }
597
598         if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
599             pa_log("Failed to acquire autospawn lock");
600             goto finish;
601         }
602
603         autospawn_locked = TRUE;
604     }
605
606     if (conf->daemonize) {
607         pid_t child;
608         int tty_fd;
609
610         if (pa_stdio_acquire() < 0) {
611             pa_log(_("Failed to acquire stdio."));
612             goto finish;
613         }
614
615 #ifdef HAVE_FORK
616         if (pipe(daemon_pipe) < 0) {
617             pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
618             goto finish;
619         }
620
621         if ((child = fork()) < 0) {
622             pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
623             goto finish;
624         }
625
626         if (child != 0) {
627             ssize_t n;
628             /* Father */
629
630             pa_assert_se(pa_close(daemon_pipe[1]) == 0);
631             daemon_pipe[1] = -1;
632
633             if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
634
635                 if (n < 0)
636                     pa_log(_("read() failed: %s"), pa_cstrerror(errno));
637
638                 retval = 1;
639             }
640
641             if (retval)
642                 pa_log(_("Daemon startup failed."));
643             else
644                 pa_log_info(_("Daemon startup successful."));
645
646             goto finish;
647         }
648
649         if (autospawn_fd >= 0) {
650             /* The lock file is unlocked from the parent, so we need
651              * to close it in the child */
652
653             pa_autospawn_lock_release();
654             pa_autospawn_lock_done(TRUE);
655
656             autospawn_locked = FALSE;
657             autospawn_fd = -1;
658         }
659
660         pa_assert_se(pa_close(daemon_pipe[0]) == 0);
661         daemon_pipe[0] = -1;
662 #endif
663
664         if (conf->auto_log_target)
665             pa_log_set_target(PA_LOG_SYSLOG);
666
667 #ifdef HAVE_SETSID
668         setsid();
669 #endif
670 #ifdef HAVE_SETPGID
671         setpgid(0,0);
672 #endif
673
674 #ifndef OS_IS_WIN32
675         pa_close(0);
676         pa_close(1);
677         pa_close(2);
678
679         pa_assert_se(open("/dev/null", O_RDONLY) == 0);
680         pa_assert_se(open("/dev/null", O_WRONLY) == 1);
681         pa_assert_se(open("/dev/null", O_WRONLY) == 2);
682 #else
683         FreeConsole();
684 #endif
685
686 #ifdef SIGTTOU
687         signal(SIGTTOU, SIG_IGN);
688 #endif
689 #ifdef SIGTTIN
690         signal(SIGTTIN, SIG_IGN);
691 #endif
692 #ifdef SIGTSTP
693         signal(SIGTSTP, SIG_IGN);
694 #endif
695
696 #ifdef TIOCNOTTY
697         if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
698             ioctl(tty_fd, TIOCNOTTY, (char*) 0);
699             pa_assert_se(pa_close(tty_fd) == 0);
700         }
701 #endif
702     }
703
704     pa_set_env("PULSE_INTERNAL", "1");
705     pa_assert_se(chdir("/") == 0);
706     umask(0022);
707
708 #ifdef HAVE_SYS_RESOURCE_H
709     set_all_rlimits(conf);
710 #endif
711     pa_rtclock_hrtimer_enable();
712
713     pa_raise_priority(conf->nice_level);
714
715     if (conf->system_instance)
716         if (change_user() < 0)
717             goto finish;
718
719     pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
720
721     pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
722     pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
723     pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
724
725     s = pa_uname_string();
726     pa_log_debug(_("Running on host: %s"), s);
727     pa_xfree(s);
728
729     pa_log_debug(_("Found %u CPUs."), pa_ncpus());
730
731     pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
732
733 #ifdef HAVE_VALGRIND_MEMCHECK_H
734     pa_log_debug(_("Compiled with Valgrind support: yes"));
735 #else
736     pa_log_debug(_("Compiled with Valgrind support: no"));
737 #endif
738
739     pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
740
741 #ifdef __OPTIMIZE__
742     pa_log_debug(_("Optimized build: yes"));
743 #else
744     pa_log_debug(_("Optimized build: no"));
745 #endif
746
747 #ifdef NDEBUG
748     pa_log_debug(_("NDEBUG defined, all asserts disabled."));
749 #elif defined(FASTPATH)
750     pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
751 #else
752     pa_log_debug(_("All asserts enabled."));
753 #endif
754
755     if (!(s = pa_machine_id())) {
756         pa_log(_("Failed to get machine ID"));
757         goto finish;
758     }
759     pa_log_info(_("Machine ID is %s."), s);
760     pa_xfree(s);
761
762     if ((s = pa_session_id())) {
763         pa_log_info(_("Session ID is %s."), s);
764         pa_xfree(s);
765     }
766
767     if (!(s = pa_get_runtime_dir()))
768         goto finish;
769     pa_log_info(_("Using runtime directory %s."), s);
770     pa_xfree(s);
771
772     if (!(s = pa_get_state_dir()))
773         goto finish;
774     pa_log_info(_("Using state directory %s."), s);
775     pa_xfree(s);
776
777     pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
778
779     if (pa_in_system_mode())
780         pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
781                       "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
782                       "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
783
784     if (conf->use_pid_file) {
785         int z;
786
787         if ((z = pa_pid_file_create("pulseaudio")) != 0) {
788
789             if (conf->cmd == PA_CMD_START && z > 0) {
790                 /* If we are already running and with are run in
791                  * --start mode, then let's return this as success. */
792
793                 retval = 0;
794                 goto finish;
795             }
796
797             pa_log(_("pa_pid_file_create() failed."));
798             goto finish;
799         }
800
801         valid_pid_file = TRUE;
802     }
803
804     pa_disable_sigpipe();
805
806     if (pa_rtclock_hrtimer())
807         pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
808     else
809         pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
810
811     if (conf->lock_memory) {
812 #ifdef HAVE_SYS_MMAN_H
813         if (mlockall(MCL_FUTURE) < 0)
814             pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
815         else
816             pa_log_info("Sucessfully locked process into memory.");
817 #else
818         pa_log_warn("Memory locking requested but not supported on platform.");
819 #endif
820     }
821
822     pa_memtrap_install();
823
824     pa_volume_func_init_mmx();
825
826     pa_assert_se(mainloop = pa_mainloop_new());
827
828     if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
829         pa_log(_("pa_core_new() failed."));
830         goto finish;
831     }
832
833     c->default_sample_spec = conf->default_sample_spec;
834     c->default_channel_map = conf->default_channel_map;
835     c->default_n_fragments = conf->default_n_fragments;
836     c->default_fragment_size_msec = conf->default_fragment_size_msec;
837     c->exit_idle_time = conf->exit_idle_time;
838     c->scache_idle_time = conf->scache_idle_time;
839     c->resample_method = conf->resample_method;
840     c->realtime_priority = conf->realtime_priority;
841     c->realtime_scheduling = !!conf->realtime_scheduling;
842     c->disable_remixing = !!conf->disable_remixing;
843     c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
844     c->running_as_daemon = !!conf->daemonize;
845     c->disallow_exit = conf->disallow_exit;
846     c->flat_volumes = conf->flat_volumes;
847
848     pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
849     pa_signal_new(SIGINT, signal_callback, c);
850     pa_signal_new(SIGTERM, signal_callback, c);
851 #ifdef SIGUSR1
852     pa_signal_new(SIGUSR1, signal_callback, c);
853 #endif
854 #ifdef SIGUSR2
855     pa_signal_new(SIGUSR2, signal_callback, c);
856 #endif
857 #ifdef SIGHUP
858     pa_signal_new(SIGHUP, signal_callback, c);
859 #endif
860
861 #ifdef OS_IS_WIN32
862     win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
863 #endif
864
865     oil_init();
866
867     if (!conf->no_cpu_limit)
868         pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
869
870     buf = pa_strbuf_new();
871     if (conf->load_default_script_file) {
872         FILE *f;
873
874         if ((f = pa_daemon_conf_open_default_script_file(conf))) {
875             r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
876             fclose(f);
877         }
878     }
879
880     if (r >= 0)
881         r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
882
883     pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
884     pa_xfree(s);
885
886     /* We completed the initial module loading, so let's disable it
887      * from now on, if requested */
888     c->disallow_module_loading = !!conf->disallow_module_loading;
889
890     if (r < 0 && conf->fail) {
891         pa_log(_("Failed to initialize daemon."));
892         goto finish;
893     }
894
895     if (!c->modules || pa_idxset_size(c->modules) == 0) {
896         pa_log(_("Daemon startup without any loaded modules, refusing to work."));
897         goto finish;
898     }
899
900 #ifdef HAVE_FORK
901     if (daemon_pipe[1] >= 0) {
902         int ok = 0;
903         pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
904         pa_close(daemon_pipe[1]);
905         daemon_pipe[1] = -1;
906     }
907 #endif
908
909 #ifdef HAVE_DBUS
910     dbus = register_dbus(c);
911 #endif
912
913     pa_log_info(_("Daemon startup complete."));
914
915     retval = 0;
916     if (pa_mainloop_run(mainloop, &retval) < 0)
917         goto finish;
918
919     pa_log_info(_("Daemon shutdown initiated."));
920
921 finish:
922 #ifdef HAVE_DBUS
923     if (dbus)
924         pa_dbus_connection_unref(dbus);
925 #endif
926
927     if (autospawn_fd >= 0) {
928         if (autospawn_locked)
929             pa_autospawn_lock_release();
930
931         pa_autospawn_lock_done(FALSE);
932     }
933
934 #ifdef OS_IS_WIN32
935     if (win32_timer)
936         pa_mainloop_get_api(mainloop)->time_free(win32_timer);
937 #endif
938
939     if (c) {
940         pa_core_unref(c);
941         pa_log_info(_("Daemon terminated."));
942     }
943
944     if (!conf->no_cpu_limit)
945         pa_cpu_limit_done();
946
947     pa_signal_done();
948
949 #ifdef HAVE_FORK
950     if (daemon_pipe[1] >= 0)
951         pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
952
953     pa_close_pipe(daemon_pipe);
954 #endif
955
956     if (mainloop)
957         pa_mainloop_free(mainloop);
958
959     if (conf)
960         pa_daemon_conf_free(conf);
961
962     if (valid_pid_file)
963         pa_pid_file_remove();
964
965 #ifdef OS_IS_WIN32
966     WSACleanup();
967 #endif
968
969     if (ltdl_init)
970         pa_ltdl_done();
971
972 #ifdef HAVE_DBUS
973     dbus_shutdown();
974 #endif
975
976     return retval;
977 }