2004-07-16 19:56:36 +00:00
/***
2006-06-19 21:53:48 +00:00
This file is part of PulseAudio .
2007-01-04 13:43:45 +00:00
2007-02-13 15:35:19 +00:00
Copyright 2004 - 2006 Lennart Poettering
Copyright 2006 Pierre Ossman < ossman @ cendio . se > for Cendio AB
2006-06-19 21:53:48 +00:00
PulseAudio is free software ; you can redistribute it and / or modify
2004-11-14 14:58:54 +00:00
it under the terms of the GNU Lesser General Public License as published
2009-03-03 20:23:02 +00:00
by the Free Software Foundation ; either version 2.1 of the License ,
2004-07-16 19:56:36 +00:00
or ( at your option ) any later version .
2007-01-04 13:43:45 +00:00
2006-06-19 21:53:48 +00:00
PulseAudio is distributed in the hope that it will be useful , but
2004-07-16 19:56:36 +00:00
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
General Public License for more details .
2007-01-04 13:43:45 +00:00
2004-11-14 14:58:54 +00:00
You should have received a copy of the GNU Lesser General Public License
2014-11-26 14:14:51 +01:00
along with PulseAudio ; if not , see < http : //www.gnu.org/licenses/>.
2004-07-16 19:56:36 +00:00
* * */
2004-07-16 19:16:42 +00:00
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
2004-07-15 19:00:42 +00:00
# include <unistd.h>
# include <errno.h>
# include <string.h>
2004-07-14 21:52:41 +00:00
# include <stdlib.h>
2004-06-11 21:30:16 +00:00
# include <stdio.h>
# include <signal.h>
2004-06-08 23:54:24 +00:00
# include <stddef.h>
2004-06-11 00:33:43 +00:00
# include <ltdl.h>
2004-11-20 23:48:18 +00:00
# include <limits.h>
2006-01-10 17:51:06 +00:00
# include <unistd.h>
2006-05-18 10:36:36 +00:00
# include <locale.h>
2006-01-10 17:51:06 +00:00
# include <sys/types.h>
2009-06-24 22:01:55 +02:00
# include <sys/stat.h>
2006-07-19 17:44:19 +00:00
2009-06-07 00:43:03 +02:00
# ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
# endif
2006-07-20 13:16:23 +00:00
# ifdef HAVE_PWD_H
# include <pwd.h>
# endif
# ifdef HAVE_GRP_H
# include <grp.h>
# endif
2004-09-29 20:13:05 +00:00
# ifdef HAVE_LIBWRAP
# include <syslog.h>
# include <tcpd.h>
# endif
2007-10-28 19:13:50 +00:00
# ifdef HAVE_DBUS
# include <dbus/dbus.h>
# endif
2006-06-19 21:53:48 +00:00
2014-10-16 10:05:19 +01:00
# ifdef HAVE_SYSTEMD_DAEMON
# include <systemd/sd-daemon.h>
# endif
2010-01-09 11:55:15 +02:00
# include <pulse/client-conf.h>
2006-06-19 21:53:48 +00:00
# include <pulse/mainloop.h>
# include <pulse/mainloop-signal.h>
2006-07-20 00:28:18 +00:00
# include <pulse/timeval.h>
2006-06-19 21:53:48 +00:00
# include <pulse/xmalloc.h>
2011-08-10 10:30:15 +02:00
# include <pulsecore/i18n.h>
2008-09-08 17:22:27 +03:00
# include <pulsecore/lock-autospawn.h>
2011-01-04 17:03:13 +01:00
# include <pulsecore/socket.h>
2006-06-19 21:53:48 +00:00
# include <pulsecore/core-error.h>
2009-04-04 23:19:53 +03:00
# include <pulsecore/core-rtclock.h>
2011-08-18 12:32:48 +05:30
# include <pulsecore/core-scache.h>
2006-06-19 21:53:48 +00:00
# include <pulsecore/core.h>
# include <pulsecore/module.h>
# include <pulsecore/cli-command.h>
# include <pulsecore/log.h>
# include <pulsecore/core-util.h>
# include <pulsecore/sioman.h>
# include <pulsecore/cli-text.h>
# include <pulsecore/pid.h>
# include <pulsecore/random.h>
2007-10-28 19:13:50 +00:00
# include <pulsecore/macro.h>
# include <pulsecore/shm.h>
2009-04-21 22:56:08 +02:00
# include <pulsecore/memtrap.h>
2011-03-25 23:03:31 +00:00
# include <pulsecore/strlist.h>
2009-03-20 18:39:30 +02:00
# ifdef HAVE_DBUS
# include <pulsecore/dbus-shared.h>
# endif
2014-09-10 15:23:11 +02:00
# include <pulsecore/cpu.h>
2006-02-17 12:10:58 +00:00
# include "cmdline.h"
2004-09-03 20:14:23 +00:00
# include "cpulimit.h"
2004-09-17 20:06:17 +00:00
# include "daemon-conf.h"
2004-09-13 23:28:30 +00:00
# include "dumpmodules.h"
2004-09-23 15:47:11 +00:00
# include "caps.h"
2007-10-28 19:13:50 +00:00
# include "ltdl-bind-now.h"
2009-06-12 07:16:05 +03:00
# include "server-lookup.h"
2004-06-08 23:54:24 +00:00
build-sys: First pass at a meson-ified build system
This is a working implementation of a build with meson. The server,
utils, and most modules build with this, and it is possible to run from
a build tree and play/capture audio on ALSA devices.
There are a number of FIXMEs, of course, and a number of features that
need to be enabled (modules, dependencies, installation, etc.), but this
should provide everything we need to get there relatively quickly.
To use this, install meson (distro package, or mesonbuild.com) and run:
$ cd <pulseaudio src dir>
$ meson <builddir>
$ ninja -C <builddir>
2017-07-31 12:37:36 +01:00
# ifdef DISABLE_LIBTOOL_PRELOAD
/* FIXME: work around a libtool bug by making sure we have 2 elements. Bug has
* been reported : https : //debbugs.gnu.org/cgi/bugreport.cgi?bug=29576 */
const lt_dlsymlist lt_preloaded_symbols [ ] = {
{ " @PROGRAM@ " , NULL } ,
{ NULL , NULL }
} ;
# endif
2004-09-29 20:13:05 +00:00
# ifdef HAVE_LIBWRAP
/* Only one instance of these variables */
int allow_severity = LOG_INFO ;
int deny_severity = LOG_WARNING ;
# endif
2009-08-08 01:53:15 +02:00
# ifdef HAVE_OSS_WRAPPER
2006-05-26 17:59:39 +00:00
/* padsp looks for this symbol in the running process and disables
* itself if it finds it and it is set to 7 ( which is actually a bit
* mask ) . For details see padsp . */
int __padsp_disabled__ = 7 ;
# endif
2017-08-26 11:21:15 +02:00
static void signal_callback ( pa_mainloop_api * m , pa_signal_event * e , int sig , void * userdata ) {
pa_module * module = NULL ;
2014-09-02 12:09:44 +02:00
pa_log_info ( " Got signal %s. " , pa_sig2str ( sig ) ) ;
2004-09-03 20:14:23 +00:00
switch ( sig ) {
2006-01-10 17:51:06 +00:00
# ifdef SIGUSR1
2004-09-03 20:14:23 +00:00
case SIGUSR1 :
2017-08-26 11:21:15 +02:00
pa_module_load ( & module , userdata , " module-cli " , NULL ) ;
2005-01-12 18:51:38 +00:00
break ;
2006-01-10 17:51:06 +00:00
# endif
2007-01-04 13:43:45 +00:00
2006-01-10 17:51:06 +00:00
# ifdef SIGUSR2
2004-09-03 20:14:23 +00:00
case SIGUSR2 :
2017-08-26 11:21:15 +02:00
pa_module_load ( & module , userdata , " module-cli-protocol-unix " , NULL ) ;
2005-01-12 18:51:38 +00:00
break ;
2006-01-10 17:51:06 +00:00
# endif
2004-09-26 17:02:26 +00:00
2006-01-10 17:51:06 +00:00
# ifdef SIGHUP
2004-09-26 17:02:26 +00:00
case SIGHUP : {
2005-01-12 18:51:38 +00:00
char * c = pa_full_status_string ( userdata ) ;
2006-02-23 02:27:19 +00:00
pa_log_notice ( " %s " , c ) ;
2005-01-12 18:51:38 +00:00
pa_xfree ( c ) ;
2004-09-26 17:02:26 +00:00
return ;
}
2006-01-10 17:51:06 +00:00
# endif
2004-09-26 17:02:26 +00:00
2004-09-03 20:14:23 +00:00
case SIGINT :
case SIGTERM :
default :
2014-09-02 12:09:44 +02:00
pa_log_info ( " Exiting. " ) ;
2015-05-21 01:31:01 +02:00
m - > quit ( m , 0 ) ;
2005-01-12 18:51:38 +00:00
break ;
2004-09-03 20:14:23 +00:00
}
2004-06-11 21:30:16 +00:00
}
2006-07-20 13:16:23 +00:00
# if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
2006-07-19 17:44:19 +00:00
static int change_user ( void ) {
struct passwd * pw ;
struct group * gr ;
int r ;
2006-07-19 23:16:02 +00:00
/* This function is called only in system-wide mode. It creates a
* runtime dir in / var / run / with proper UID / GID and drops privs
* afterwards . */
2007-01-04 13:43:45 +00:00
2006-07-19 17:44:19 +00:00
if ( ! ( pw = getpwnam ( PA_SYSTEM_USER ) ) ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to find user '%s'. " ) , PA_SYSTEM_USER ) ;
2006-07-19 17:44:19 +00:00
return - 1 ;
}
if ( ! ( gr = getgrnam ( PA_SYSTEM_GROUP ) ) ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to find group '%s'. " ) , PA_SYSTEM_GROUP ) ;
2006-07-19 17:44:19 +00:00
return - 1 ;
}
2014-09-02 12:09:44 +02:00
pa_log_info ( " Found user '%s' (UID %lu) and group '%s' (GID %lu). " ,
2006-07-19 17:44:19 +00:00
PA_SYSTEM_USER , ( unsigned long ) pw - > pw_uid ,
PA_SYSTEM_GROUP , ( unsigned long ) gr - > gr_gid ) ;
if ( pw - > pw_gid ! = gr - > gr_gid ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " GID of user '%s' and of group '%s' don't match. " ) , PA_SYSTEM_USER , PA_SYSTEM_GROUP ) ;
2006-07-19 17:44:19 +00:00
return - 1 ;
}
2012-06-06 01:28:16 +05:30
if ( ! pa_streq ( pw - > pw_dir , PA_SYSTEM_RUNTIME_PATH ) )
2008-08-06 18:54:13 +02:00
pa_log_warn ( _ ( " Home directory of user '%s' is not '%s', ignoring. " ) , PA_SYSTEM_USER , PA_SYSTEM_RUNTIME_PATH ) ;
2006-07-19 17:44:19 +00:00
2013-06-27 19:28:09 +02:00
if ( pa_make_secure_dir ( PA_SYSTEM_RUNTIME_PATH , 0755 , pw - > pw_uid , gr - > gr_gid , true ) < 0 ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to create '%s': %s " ) , PA_SYSTEM_RUNTIME_PATH , pa_cstrerror ( errno ) ) ;
2006-07-19 17:44:19 +00:00
return - 1 ;
}
2007-01-04 13:43:45 +00:00
2013-06-27 19:28:09 +02:00
if ( pa_make_secure_dir ( PA_SYSTEM_STATE_PATH , 0700 , pw - > pw_uid , gr - > gr_gid , true ) < 0 ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to create '%s': %s " ) , PA_SYSTEM_STATE_PATH , pa_cstrerror ( errno ) ) ;
2008-05-21 22:50:58 +00:00
return - 1 ;
}
/* We don't create the config dir here, because we don't need to write to it */
2006-07-19 17:44:19 +00:00
if ( initgroups ( PA_SYSTEM_USER , gr - > gr_gid ) ! = 0 ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to change group list: %s " ) , pa_cstrerror ( errno ) ) ;
2006-07-19 17:44:19 +00:00
return - 1 ;
}
# if defined(HAVE_SETRESGID)
r = setresgid ( gr - > gr_gid , gr - > gr_gid , gr - > gr_gid ) ;
# elif defined(HAVE_SETEGID)
if ( ( r = setgid ( gr - > gr_gid ) ) > = 0 )
r = setegid ( gr - > gr_gid ) ;
# elif defined(HAVE_SETREGID)
r = setregid ( gr - > gr_gid , gr - > gr_gid ) ;
# else
2008-10-19 22:25:58 +02:00
# error "No API to drop privileges"
2006-07-19 17:44:19 +00:00
# endif
if ( r < 0 ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to change GID: %s " ) , pa_cstrerror ( errno ) ) ;
2006-07-19 17:44:19 +00:00
return - 1 ;
}
# if defined(HAVE_SETRESUID)
r = setresuid ( pw - > pw_uid , pw - > pw_uid , pw - > pw_uid ) ;
# elif defined(HAVE_SETEUID)
if ( ( r = setuid ( pw - > pw_uid ) ) > = 0 )
r = seteuid ( pw - > pw_uid ) ;
# elif defined(HAVE_SETREUID)
r = setreuid ( pw - > pw_uid , pw - > pw_uid ) ;
# else
2008-10-19 22:25:58 +02:00
# error "No API to drop privileges"
2006-07-19 17:44:19 +00:00
# endif
if ( r < 0 ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to change UID: %s " ) , pa_cstrerror ( errno ) ) ;
2006-07-19 17:44:19 +00:00
return - 1 ;
}
2012-04-05 15:37:19 +03:00
pa_drop_caps ( ) ;
2008-05-15 23:34:41 +00:00
pa_set_env ( " USER " , PA_SYSTEM_USER ) ;
pa_set_env ( " USERNAME " , PA_SYSTEM_USER ) ;
pa_set_env ( " LOGNAME " , PA_SYSTEM_USER ) ;
pa_set_env ( " HOME " , PA_SYSTEM_RUNTIME_PATH ) ;
2006-07-19 17:44:19 +00:00
/* Relevant for pa_runtime_path() */
2009-09-01 00:53:49 +02:00
if ( ! getenv ( " PULSE_RUNTIME_PATH " ) )
pa_set_env ( " PULSE_RUNTIME_PATH " , PA_SYSTEM_RUNTIME_PATH ) ;
if ( ! getenv ( " PULSE_CONFIG_PATH " ) )
pa_set_env ( " PULSE_CONFIG_PATH " , PA_SYSTEM_CONFIG_PATH ) ;
if ( ! getenv ( " PULSE_STATE_PATH " ) )
pa_set_env ( " PULSE_STATE_PATH " , PA_SYSTEM_STATE_PATH ) ;
2006-07-19 17:44:19 +00:00
2014-09-02 12:09:44 +02:00
pa_log_info ( " Successfully changed user to \" " PA_SYSTEM_USER " \" . " ) ;
2006-07-19 17:44:19 +00:00
return 0 ;
}
2006-07-20 13:16:23 +00:00
# else /* HAVE_PWD_H && HAVE_GRP_H */
static int change_user ( void ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " System wide mode unsupported on this platform. " ) ) ;
2006-07-20 13:16:23 +00:00
return - 1 ;
}
# endif /* HAVE_PWD_H && HAVE_GRP_H */
2006-07-20 01:25:37 +00:00
# ifdef HAVE_SYS_RESOURCE_H
2007-11-21 01:30:40 +00:00
static int set_one_rlimit ( const pa_rlimit * r , int resource , const char * name ) {
2006-07-20 01:25:37 +00:00
struct rlimit rl ;
2007-10-28 19:13:50 +00:00
pa_assert ( r ) ;
2006-07-20 01:25:37 +00:00
if ( ! r - > is_set )
2007-11-21 01:30:40 +00:00
return 0 ;
2006-07-20 01:25:37 +00:00
rl . rlim_cur = rl . rlim_max = r - > value ;
2007-11-21 01:30:40 +00:00
if ( setrlimit ( resource , & rl ) < 0 ) {
2014-09-02 12:09:44 +02:00
pa_log_info ( " setrlimit(%s, (%u, %u)) failed: %s " , name , ( unsigned ) r - > value , ( unsigned ) r - > value , pa_cstrerror ( errno ) ) ;
2007-11-21 01:30:40 +00:00
return - 1 ;
}
return 0 ;
2006-07-20 01:25:37 +00:00
}
static void set_all_rlimits ( const pa_daemon_conf * conf ) {
set_one_rlimit ( & conf - > rlimit_fsize , RLIMIT_FSIZE , " RLIMIT_FSIZE " ) ;
2008-05-15 23:34:41 +00:00
set_one_rlimit ( & conf - > rlimit_data , RLIMIT_DATA , " RLIMIT_DATA " ) ;
2006-07-20 01:25:37 +00:00
set_one_rlimit ( & conf - > rlimit_stack , RLIMIT_STACK , " RLIMIT_STACK " ) ;
2008-05-15 23:34:41 +00:00
set_one_rlimit ( & conf - > rlimit_core , RLIMIT_CORE , " RLIMIT_CORE " ) ;
2009-02-26 16:48:58 +11:00
# ifdef RLIMIT_RSS
2008-05-15 23:34:41 +00:00
set_one_rlimit ( & conf - > rlimit_rss , RLIMIT_RSS , " RLIMIT_RSS " ) ;
2009-02-26 16:48:58 +11:00
# endif
2006-07-20 01:25:37 +00:00
# ifdef RLIMIT_NPROC
set_one_rlimit ( & conf - > rlimit_nproc , RLIMIT_NPROC , " RLIMIT_NPROC " ) ;
# endif
2009-01-27 00:48:53 +01:00
# ifdef RLIMIT_NOFILE
2008-05-15 23:34:41 +00:00
set_one_rlimit ( & conf - > rlimit_nofile , RLIMIT_NOFILE , " RLIMIT_NOFILE " ) ;
2009-01-27 00:48:53 +01:00
# endif
2006-07-20 01:25:37 +00:00
# ifdef RLIMIT_MEMLOCK
set_one_rlimit ( & conf - > rlimit_memlock , RLIMIT_MEMLOCK , " RLIMIT_MEMLOCK " ) ;
2008-05-15 23:34:41 +00:00
# endif
2009-01-22 01:39:54 +01:00
# ifdef RLIMIT_AS
2008-05-15 23:34:41 +00:00
set_one_rlimit ( & conf - > rlimit_as , RLIMIT_AS , " RLIMIT_AS " ) ;
2009-01-22 01:39:54 +01:00
# endif
2008-05-15 23:34:41 +00:00
# ifdef RLIMIT_LOCKS
set_one_rlimit ( & conf - > rlimit_locks , RLIMIT_LOCKS , " RLIMIT_LOCKS " ) ;
# endif
# ifdef RLIMIT_SIGPENDING
set_one_rlimit ( & conf - > rlimit_sigpending , RLIMIT_SIGPENDING , " RLIMIT_SIGPENDING " ) ;
# endif
# ifdef RLIMIT_MSGQUEUE
set_one_rlimit ( & conf - > rlimit_msgqueue , RLIMIT_MSGQUEUE , " RLIMIT_MSGQUEUE " ) ;
2006-07-20 01:25:37 +00:00
# endif
2007-11-01 00:34:43 +00:00
# ifdef RLIMIT_NICE
set_one_rlimit ( & conf - > rlimit_nice , RLIMIT_NICE , " RLIMIT_NICE " ) ;
# endif
# ifdef RLIMIT_RTPRIO
set_one_rlimit ( & conf - > rlimit_rtprio , RLIMIT_RTPRIO , " RLIMIT_RTPRIO " ) ;
# endif
2008-05-15 23:34:41 +00:00
# ifdef RLIMIT_RTTIME
set_one_rlimit ( & conf - > rlimit_rttime , RLIMIT_RTTIME , " RLIMIT_RTTIME " ) ;
# endif
2006-07-20 01:25:37 +00:00
}
# endif
2010-01-09 11:55:15 +02:00
static char * check_configured_address ( void ) {
char * default_server = NULL ;
pa_client_conf * c = pa_client_conf_new ( ) ;
2014-06-08 16:32:54 +03:00
pa_client_conf_load ( c , true , true ) ;
2010-01-09 11:55:15 +02:00
if ( c - > default_server & & * c - > default_server )
default_server = pa_xstrdup ( c - > default_server ) ;
pa_client_conf_free ( c ) ;
return default_server ;
}
2009-03-20 18:39:30 +02:00
# ifdef HAVE_DBUS
2009-06-12 07:16:05 +03:00
static pa_dbus_connection * register_dbus_name ( pa_core * c , DBusBusType bus , const char * name ) {
2009-03-20 18:39:30 +02:00
DBusError error ;
pa_dbus_connection * conn ;
dbus_error_init ( & error ) ;
2009-04-06 02:31:22 +02:00
2009-06-12 07:16:05 +03:00
if ( ! ( conn = pa_dbus_bus_get ( c , bus , & error ) ) | | dbus_error_is_set ( & error ) ) {
2009-04-06 02:31:22 +02:00
pa_log_warn ( " Unable to contact D-Bus: %s: %s " , error . name , error . message ) ;
goto fail ;
2009-03-20 18:39:30 +02:00
}
2009-06-12 07:16:05 +03:00
if ( dbus_bus_request_name ( pa_dbus_connection_get ( conn ) , name , DBUS_NAME_FLAG_DO_NOT_QUEUE , & error ) = = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ) {
pa_log_debug ( " Got %s! " , name ) ;
2009-04-06 02:31:22 +02:00
return conn ;
}
if ( dbus_error_is_set ( & error ) )
2009-06-12 07:16:05 +03:00
pa_log_error ( " Failed to acquire %s: %s: %s " , name , error . name , error . message ) ;
2009-04-06 02:31:22 +02:00
else
2011-08-15 14:05:50 +02:00
pa_log_error ( " D-Bus name %s already taken. " , name ) ;
2009-04-06 02:31:22 +02:00
/* PA cannot be started twice by the same user and hence we can
2009-06-12 07:16:05 +03:00
* ignore mostly the case that a name is already taken . */
2009-04-06 02:31:22 +02:00
fail :
2009-03-20 18:39:30 +02:00
if ( conn )
pa_dbus_connection_unref ( conn ) ;
dbus_error_free ( & error ) ;
2009-04-06 02:31:22 +02:00
return NULL ;
2009-03-20 18:39:30 +02:00
}
# endif
2004-06-08 23:54:24 +00:00
int main ( int argc , char * argv [ ] ) {
2006-08-19 01:20:13 +00:00
pa_core * c = NULL ;
2006-01-11 01:17:39 +00:00
pa_strbuf * buf = NULL ;
2006-08-19 01:20:13 +00:00
pa_daemon_conf * conf = NULL ;
pa_mainloop * mainloop = NULL ;
2007-01-04 13:43:45 +00:00
char * s ;
2010-01-09 11:55:15 +02:00
char * configured_address ;
2007-10-28 19:13:50 +00:00
int r = 0 , retval = 1 , d = 0 ;
2013-06-27 19:28:09 +02:00
bool valid_pid_file = false ;
bool ltdl_init = false ;
2014-10-16 10:05:19 +01:00
int n_fds = 0 , * passed_fds = NULL ;
2008-05-15 23:34:41 +00:00
const char * e ;
# ifdef HAVE_FORK
int daemon_pipe [ 2 ] = { - 1 , - 1 } ;
2011-03-24 21:27:55 +00:00
int daemon_pipe2 [ 2 ] = { - 1 , - 1 } ;
2006-01-10 17:51:06 +00:00
# endif
2008-08-09 03:49:42 +02:00
int autospawn_fd = - 1 ;
2013-06-27 19:28:09 +02:00
bool autospawn_locked = false ;
2009-04-06 02:31:22 +02:00
# ifdef HAVE_DBUS
2009-06-12 07:16:05 +03:00
pa_dbusobj_server_lookup * server_lookup = NULL ; /* /org/pulseaudio/server_lookup */
pa_dbus_connection * lookup_service_bus = NULL ; /* Always the user bus. */
pa_dbus_connection * server_bus = NULL ; /* The bus where we reserve org.pulseaudio.Server, either the user or the system bus. */
2013-06-27 19:28:09 +02:00
bool start_server ;
2009-04-06 02:31:22 +02:00
# endif
2006-01-10 17:51:06 +00:00
2008-08-29 21:43:50 +02:00
pa_log_set_ident ( " pulseaudio " ) ;
2009-04-10 03:41:25 +02:00
pa_log_set_level ( PA_LOG_NOTICE ) ;
2009-02-21 22:45:56 +01:00
pa_log_set_flags ( PA_LOG_COLORS | PA_LOG_PRINT_FILE | PA_LOG_PRINT_LEVEL , PA_LOG_RESET ) ;
2008-08-29 21:43:50 +02:00
2018-01-26 03:58:19 +02:00
# if !defined(HAVE_BIND_NOW) && defined(__linux__) && defined(__OPTIMIZE__)
2007-10-28 19:13:50 +00:00
/*
Disable lazy relocations to make usage of external libraries
more deterministic for our RT threads . We abuse __OPTIMIZE__ as
2009-07-20 15:47:57 +01:00
a check whether we are a debug build or not . This all is
admittedly a bit snake - oilish .
2007-10-28 19:13:50 +00:00
*/
if ( ! getenv ( " LD_BIND_NOW " ) ) {
2007-10-29 15:33:07 +00:00
char * rp ;
2009-09-26 20:18:00 +01:00
char * canonical_rp ;
2007-10-28 19:13:50 +00:00
/* We have to execute ourselves, because the libc caches the
* value of $ LD_BIND_NOW on initialization . */
2007-10-29 15:33:07 +00:00
2008-05-15 23:34:41 +00:00
pa_set_env ( " LD_BIND_NOW " , " 1 " ) ;
2009-02-18 21:45:06 +01:00
2009-10-30 09:54:08 -05:00
if ( ( canonical_rp = pa_realpath ( PA_BINARY ) ) ) {
2009-09-26 20:18:00 +01:00
2009-10-30 05:08:48 +01:00
if ( ( rp = pa_readlink ( " /proc/self/exe " ) ) ) {
2009-07-20 15:47:57 +01:00
2009-10-30 05:08:48 +01:00
if ( pa_streq ( rp , canonical_rp ) )
pa_assert_se ( execv ( rp , argv ) = = 0 ) ;
else
pa_log_warn ( " /proc/self/exe does not point to %s, cannot self execute. Are you playing games? " , canonical_rp ) ;
2009-07-20 15:47:57 +01:00
2009-10-30 05:08:48 +01:00
pa_xfree ( rp ) ;
2009-07-20 15:47:57 +01:00
2009-10-30 05:08:48 +01:00
} else
pa_log_warn ( " Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()? " ) ;
pa_xfree ( canonical_rp ) ;
2009-09-26 20:18:00 +01:00
2009-10-30 05:08:48 +01:00
} else
pa_log_warn ( " Couldn't canonicalize binary path, cannot self execute. " ) ;
2007-10-28 19:13:50 +00:00
}
# endif
2014-10-16 10:05:19 +01:00
# ifdef HAVE_SYSTEMD_DAEMON
n_fds = sd_listen_fds ( 0 ) ;
if ( n_fds > 0 ) {
int i = n_fds ;
2008-05-15 23:34:41 +00:00
2014-10-16 10:05:19 +01:00
passed_fds = pa_xnew ( int , n_fds + 2 ) ;
passed_fds [ n_fds ] = passed_fds [ n_fds + 1 ] = - 1 ;
while ( i - - )
passed_fds [ i ] = SD_LISTEN_FDS_START + i ;
}
# endif
if ( ! passed_fds ) {
n_fds = 0 ;
passed_fds = pa_xnew ( int , 2 ) ;
passed_fds [ 0 ] = passed_fds [ 1 ] = - 1 ;
}
if ( ( e = getenv ( " PULSE_PASSED_FD " ) ) ) {
int passed_fd = atoi ( e ) ;
if ( passed_fd > 2 )
passed_fds [ n_fds ] = passed_fd ;
2008-05-15 23:34:41 +00:00
}
2009-06-19 17:37:18 +02:00
/* We might be autospawned, in which case have no idea in which
* context we have been started . Let ' s cleanup our execution
* context as good as possible */
2009-07-22 22:47:51 +02:00
2009-08-12 21:36:52 +02:00
pa_reset_personality ( ) ;
2009-06-19 17:37:18 +02:00
pa_drop_root ( ) ;
2014-10-16 10:05:19 +01:00
pa_close_allv ( passed_fds ) ;
pa_xfree ( passed_fds ) ;
2008-05-15 23:34:41 +00:00
pa_reset_sigs ( - 1 ) ;
pa_unblock_sigs ( - 1 ) ;
2009-08-12 21:37:40 +02:00
pa_reset_priority ( ) ;
2008-05-15 23:34:41 +00:00
2007-11-21 01:30:40 +00:00
setlocale ( LC_ALL , " " ) ;
2008-08-06 18:54:13 +02:00
pa_init_i18n ( ) ;
2004-09-17 20:06:17 +00:00
conf = pa_daemon_conf_new ( ) ;
2007-01-04 13:43:45 +00:00
2004-09-17 20:06:17 +00:00
if ( pa_daemon_conf_load ( conf , NULL ) < 0 )
2004-09-13 23:28:30 +00:00
goto finish ;
2004-12-11 00:10:41 +00:00
2004-09-17 20:06:17 +00:00
if ( pa_daemon_conf_env ( conf ) < 0 )
goto finish ;
2004-12-11 00:10:41 +00:00
2004-09-13 23:28:30 +00:00
if ( pa_cmdline_parse ( conf , argc , argv , & d ) < 0 ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to parse command line. " ) ) ;
2004-07-15 19:00:42 +00:00
goto finish ;
2004-07-12 21:28:11 +00:00
}
2004-12-11 00:10:41 +00:00
2013-06-19 11:59:08 +08:00
if ( conf - > log_target )
pa_log_set_target ( conf - > log_target ) ;
else {
pa_log_target target = { . type = PA_LOG_STDERR , . file = NULL } ;
pa_log_set_target ( & target ) ;
}
2009-02-21 22:45:56 +01:00
pa_log_set_level ( conf - > log_level ) ;
if ( conf - > log_meta )
pa_log_set_flags ( PA_LOG_PRINT_META , PA_LOG_SET ) ;
if ( conf - > log_time )
pa_log_set_flags ( PA_LOG_PRINT_TIME , PA_LOG_SET ) ;
2008-10-21 19:15:41 +02:00
pa_log_set_show_backtrace ( conf - > log_backtrace ) ;
2004-09-13 23:28:30 +00:00
2009-06-12 07:16:05 +03:00
# ifdef HAVE_DBUS
/* conf->system_instance and conf->local_server_type control almost the
* same thing ; make them agree about what is requested . */
switch ( conf - > local_server_type ) {
case PA_SERVER_TYPE_UNSET :
conf - > local_server_type = conf - > system_instance ? PA_SERVER_TYPE_SYSTEM : PA_SERVER_TYPE_USER ;
break ;
case PA_SERVER_TYPE_USER :
case PA_SERVER_TYPE_NONE :
2013-06-27 19:28:09 +02:00
conf - > system_instance = false ;
2009-06-12 07:16:05 +03:00
break ;
case PA_SERVER_TYPE_SYSTEM :
2013-06-27 19:28:09 +02:00
conf - > system_instance = true ;
2009-06-12 07:16:05 +03:00
break ;
default :
pa_assert_not_reached ( ) ;
}
2009-06-29 18:35:06 +03:00
start_server = conf - > local_server_type = = PA_SERVER_TYPE_USER | | ( getuid ( ) = = 0 & & conf - > local_server_type = = PA_SERVER_TYPE_SYSTEM ) ;
2009-06-12 07:16:05 +03:00
if ( ! start_server & & conf - > local_server_type = = PA_SERVER_TYPE_SYSTEM ) {
pa_log_notice ( _ ( " System mode refused for non-root user. Only starting the D-Bus server lookup service. " ) ) ;
2013-06-27 19:28:09 +02:00
conf - > system_instance = false ;
2009-06-12 07:16:05 +03:00
}
# endif
2007-11-21 01:30:40 +00:00
LTDL_SET_PRELOADED_SYMBOLS ( ) ;
pa_ltdl_init ( ) ;
2013-06-27 19:28:09 +02:00
ltdl_init = true ;
2007-11-21 01:30:40 +00:00
2004-09-13 23:28:30 +00:00
if ( conf - > dl_search_path )
lt_dlsetsearchpath ( conf - > dl_search_path ) ;
2007-11-21 01:30:40 +00:00
# ifdef OS_IS_WIN32
{
WSADATA data ;
WSAStartup ( MAKEWORD ( 2 , 0 ) , & data ) ;
}
# endif
pa_random_seed ( ) ;
2004-09-14 17:52:11 +00:00
switch ( conf - > cmd ) {
case PA_CMD_DUMP_MODULES :
pa_dump_modules ( conf , argc - d , argv + d ) ;
retval = 0 ;
goto finish ;
2004-09-05 00:03:16 +00:00
2004-09-14 17:52:11 +00:00
case PA_CMD_DUMP_CONF : {
2009-11-20 17:48:04 +01:00
if ( d < argc ) {
2016-08-16 07:03:25 +02:00
pa_log ( " Too many arguments. " ) ;
2009-11-20 17:48:04 +01:00
goto finish ;
}
2006-01-11 01:17:39 +00:00
s = pa_daemon_conf_dump ( conf ) ;
2004-09-14 17:52:11 +00:00
fputs ( s , stdout ) ;
pa_xfree ( s ) ;
retval = 0 ;
goto finish ;
}
2004-07-15 19:00:42 +00:00
2007-10-28 19:13:50 +00:00
case PA_CMD_DUMP_RESAMPLE_METHODS : {
int i ;
2009-11-20 17:48:04 +01:00
if ( d < argc ) {
2016-08-16 07:03:25 +02:00
pa_log ( " Too many arguments. " ) ;
2009-11-20 17:48:04 +01:00
goto finish ;
}
2007-10-28 19:13:50 +00:00
for ( i = 0 ; i < PA_RESAMPLER_MAX ; i + + )
if ( pa_resample_method_supported ( i ) )
printf ( " %s \n " , pa_resample_method_to_string ( i ) ) ;
2008-12-16 18:17:21 +01:00
retval = 0 ;
2007-10-28 19:13:50 +00:00
goto finish ;
}
2004-09-14 17:52:11 +00:00
case PA_CMD_HELP :
pa_cmdline_help ( argv [ 0 ] ) ;
retval = 0 ;
goto finish ;
2004-09-01 00:23:51 +00:00
2004-09-14 17:52:11 +00:00
case PA_CMD_VERSION :
2009-11-20 17:48:04 +01:00
if ( d < argc ) {
2016-08-16 07:03:25 +02:00
pa_log ( " Too many arguments. " ) ;
2009-11-20 17:48:04 +01:00
goto finish ;
}
2004-09-14 17:52:11 +00:00
printf ( PACKAGE_NAME " " PACKAGE_VERSION " \n " ) ;
retval = 0 ;
goto finish ;
2004-11-20 23:48:18 +00:00
case PA_CMD_CHECK : {
pid_t pid ;
2009-11-20 17:48:04 +01:00
if ( d < argc ) {
2016-08-16 07:03:25 +02:00
pa_log ( " Too many arguments. " ) ;
2009-11-20 17:48:04 +01:00
goto finish ;
}
2007-11-21 01:30:40 +00:00
if ( pa_pid_file_check_running ( & pid , " pulseaudio " ) < 0 )
2014-09-02 12:09:44 +02:00
pa_log_info ( " Daemon not running " ) ;
2007-11-21 01:30:40 +00:00
else {
2014-09-02 12:09:44 +02:00
pa_log_info ( " Daemon running as PID %u " , pid ) ;
2004-11-20 23:48:18 +00:00
retval = 0 ;
}
goto finish ;
}
case PA_CMD_KILL :
2009-11-20 17:48:04 +01:00
if ( d < argc ) {
2016-08-16 07:03:25 +02:00
pa_log ( " Too many arguments. " ) ;
2009-11-20 17:48:04 +01:00
goto finish ;
}
2007-11-21 01:30:40 +00:00
if ( pa_pid_file_kill ( SIGINT , NULL , " pulseaudio " ) < 0 )
2008-08-09 03:47:59 +02:00
pa_log ( _ ( " Failed to kill daemon: %s " ) , pa_cstrerror ( errno ) ) ;
2004-11-20 23:48:18 +00:00
else
retval = 0 ;
2007-01-04 13:43:45 +00:00
2004-11-20 23:48:18 +00:00
goto finish ;
2007-01-04 13:43:45 +00:00
2007-10-28 19:13:50 +00:00
case PA_CMD_CLEANUP_SHM :
2009-11-20 17:48:04 +01:00
if ( d < argc ) {
2016-08-16 07:03:25 +02:00
pa_log ( " Too many arguments. " ) ;
2009-11-20 17:48:04 +01:00
goto finish ;
}
2007-10-28 19:13:50 +00:00
if ( pa_shm_cleanup ( ) > = 0 )
retval = 0 ;
goto finish ;
2004-09-14 17:52:11 +00:00
default :
2008-06-11 17:38:50 +00:00
pa_assert ( conf - > cmd = = PA_CMD_DAEMON | | conf - > cmd = = PA_CMD_START ) ;
2004-09-14 17:52:11 +00:00
}
2004-09-01 00:23:51 +00:00
2009-11-20 17:48:04 +01:00
if ( d < argc ) {
2016-08-16 07:03:25 +02:00
pa_log ( " Too many arguments. " ) ;
2009-11-20 17:48:04 +01:00
goto finish ;
}
2011-01-06 00:51:33 +01:00
# ifdef HAVE_GETUID
2009-06-19 17:37:18 +02:00
if ( getuid ( ) = = 0 & & ! conf - > system_instance )
2008-08-06 18:54:13 +02:00
pa_log_warn ( _ ( " This program is not intended to be run as root (unless --system is specified). " ) ) ;
2009-06-12 07:16:05 +03:00
# ifndef HAVE_DBUS /* A similar, only a notice worthy check was done earlier, if D-Bus is enabled. */
2009-06-19 17:37:18 +02:00
else if ( getuid ( ) ! = 0 & & conf - > system_instance ) {
2008-10-19 22:25:58 +02:00
pa_log ( _ ( " Root privileges required. " ) ) ;
2006-07-19 17:44:19 +00:00
goto finish ;
}
2009-06-12 07:16:05 +03:00
# endif
2011-01-06 00:51:33 +01:00
# endif /* HAVE_GETUID */
2006-07-19 17:44:19 +00:00
2008-07-30 20:36:34 +02:00
if ( conf - > cmd = = PA_CMD_START & & conf - > system_instance ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " --start not supported for system instances. " ) ) ;
2008-07-30 20:36:34 +02:00
goto finish ;
}
2010-01-09 11:55:15 +02:00
if ( conf - > cmd = = PA_CMD_START & & ( configured_address = check_configured_address ( ) ) ) {
2011-03-25 23:03:31 +00:00
/* There is an server address in our config, but where did it come from?
* By default a standard X11 login will load module - x11 - publish which will
* inject PULSE_SERVER X11 property . If the PA daemon crashes , we will end
* up hitting this code path . So we have to check to see if our configured_address
* is the same as the value that would go into this property so that we can
* recover ( i . e . autospawn ) from a crash .
*/
char * ufn ;
2013-06-27 19:28:09 +02:00
bool start_anyway = false ;
2011-03-25 23:03:31 +00:00
if ( ( ufn = pa_runtime_path ( PA_NATIVE_DEFAULT_UNIX_SOCKET ) ) ) {
char * id ;
if ( ( id = pa_machine_id ( ) ) ) {
pa_strlist * server_list ;
char formatted_ufn [ 256 ] ;
pa_snprintf ( formatted_ufn , sizeof ( formatted_ufn ) , " {%s}unix:%s " , id , ufn ) ;
pa_xfree ( id ) ;
if ( ( server_list = pa_strlist_parse ( configured_address ) ) ) {
char * u = NULL ;
/* We only need to check the first server */
server_list = pa_strlist_pop ( server_list , & u ) ;
pa_strlist_free ( server_list ) ;
start_anyway = ( u & & pa_streq ( formatted_ufn , u ) ) ;
pa_xfree ( u ) ;
}
}
pa_xfree ( ufn ) ;
}
if ( ! start_anyway ) {
pa_log_notice ( _ ( " User-configured server at %s, refusing to start/autospawn. " ) , configured_address ) ;
pa_xfree ( configured_address ) ;
retval = 0 ;
goto finish ;
}
pa_log_notice ( _ ( " User-configured server at %s, which appears to be local. Probing deeper. " ) , configured_address ) ;
2010-01-09 11:55:15 +02:00
pa_xfree ( configured_address ) ;
}
2008-08-06 19:56:15 +02:00
if ( conf - > system_instance & & ! conf - > disallow_exit )
2015-06-15 17:34:07 +05:30
pa_log_warn ( _ ( " Running in system mode, but --disallow-exit not set. " ) ) ;
2008-08-06 19:56:15 +02:00
if ( conf - > system_instance & & ! conf - > disallow_module_loading )
2015-06-15 17:34:07 +05:30
pa_log_warn ( _ ( " Running in system mode, but --disallow-module-loading not set. " ) ) ;
2008-08-06 19:56:15 +02:00
if ( conf - > system_instance & & ! conf - > disable_shm ) {
2015-06-15 17:34:07 +05:30
pa_log_notice ( _ ( " Running in system mode, forcibly disabling SHM mode. " ) ) ;
2013-06-27 19:28:09 +02:00
conf - > disable_shm = true ;
2008-08-06 19:56:15 +02:00
}
2008-10-07 02:00:07 +02:00
if ( conf - > system_instance & & conf - > exit_idle_time > = 0 ) {
2015-06-15 17:34:07 +05:30
pa_log_notice ( _ ( " Running in system mode, forcibly disabling exit idle time. " ) ) ;
2008-10-07 02:00:07 +02:00
conf - > exit_idle_time = - 1 ;
2008-08-06 19:56:15 +02:00
}
2008-06-11 17:38:50 +00:00
if ( conf - > cmd = = PA_CMD_START ) {
/* If we shall start PA only when it is not running yet, we
* first take the autospawn lock to make things
* synchronous . */
2014-04-13 19:15:28 +02:00
/* This locking and thread synchronisation code doesn't work reliably
* on kFreeBSD ( Debian bug # 705435 ) , or in upstream FreeBSD ports
* ( bug reference : ports / 128947 , patched in SVN r231972 ) . */
# if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
2008-08-09 03:49:42 +02:00
if ( ( autospawn_fd = pa_autospawn_lock_init ( ) ) < 0 ) {
pa_log ( " Failed to initialize autospawn lock " ) ;
goto finish ;
}
2013-06-27 19:28:09 +02:00
if ( ( pa_autospawn_lock_acquire ( true ) < 0 ) ) {
2008-08-09 03:49:42 +02:00
pa_log ( " Failed to acquire autospawn lock " ) ;
goto finish ;
}
2013-06-27 19:28:09 +02:00
autospawn_locked = true ;
2014-04-13 19:15:28 +02:00
# endif
2008-06-11 17:38:50 +00:00
}
2004-09-13 23:28:30 +00:00
if ( conf - > daemonize ) {
2011-06-23 22:21:03 +02:00
# ifdef HAVE_FORK
2004-07-15 19:00:42 +00:00
pid_t child ;
2011-06-23 22:21:03 +02:00
# endif
2004-07-15 19:00:42 +00:00
if ( pa_stdio_acquire ( ) < 0 ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Failed to acquire stdio. " ) ) ;
2004-07-15 19:00:42 +00:00
goto finish ;
}
2006-01-10 17:51:06 +00:00
# ifdef HAVE_FORK
2004-07-15 19:00:42 +00:00
if ( pipe ( daemon_pipe ) < 0 ) {
2009-10-31 02:43:47 +01:00
pa_log ( _ ( " pipe() failed: %s " ) , pa_cstrerror ( errno ) ) ;
2004-07-15 19:00:42 +00:00
goto finish ;
}
2007-01-04 13:43:45 +00:00
2004-07-15 19:00:42 +00:00
if ( ( child = fork ( ) ) < 0 ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " fork() failed: %s " ) , pa_cstrerror ( errno ) ) ;
2011-03-25 09:12:51 +00:00
pa_close_pipe ( daemon_pipe ) ;
2004-07-15 19:00:42 +00:00
goto finish ;
}
if ( child ! = 0 ) {
2008-05-15 23:34:41 +00:00
ssize_t n ;
2004-07-15 19:00:42 +00:00
/* Father */
2007-10-28 19:13:50 +00:00
pa_assert_se ( pa_close ( daemon_pipe [ 1 ] ) = = 0 ) ;
2004-07-15 19:00:42 +00:00
daemon_pipe [ 1 ] = - 1 ;
2008-05-15 23:34:41 +00:00
if ( ( n = pa_loop_read ( daemon_pipe [ 0 ] , & retval , sizeof ( retval ) , NULL ) ) ! = sizeof ( retval ) ) {
if ( n < 0 )
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " read() failed: %s " ) , pa_cstrerror ( errno ) ) ;
2008-05-15 23:34:41 +00:00
2004-07-15 19:00:42 +00:00
retval = 1 ;
}
2004-12-11 00:10:41 +00:00
if ( retval )
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " Daemon startup failed. " ) ) ;
2004-12-11 00:10:41 +00:00
else
2014-09-02 12:09:44 +02:00
pa_log_info ( " Daemon startup successful. " ) ;
2007-01-04 13:43:45 +00:00
2004-07-15 19:00:42 +00:00
goto finish ;
}
2008-08-09 03:49:42 +02:00
if ( autospawn_fd > = 0 ) {
2008-06-11 17:38:50 +00:00
/* The lock file is unlocked from the parent, so we need
* to close it in the child */
2008-08-09 03:49:42 +02:00
pa_autospawn_lock_release ( ) ;
2013-06-27 19:28:09 +02:00
pa_autospawn_lock_done ( true ) ;
2008-08-09 03:49:42 +02:00
2013-06-27 19:28:09 +02:00
autospawn_locked = false ;
2008-08-09 03:49:42 +02:00
autospawn_fd = - 1 ;
2008-06-11 17:38:50 +00:00
}
2007-10-28 19:13:50 +00:00
pa_assert_se ( pa_close ( daemon_pipe [ 0 ] ) = = 0 ) ;
2004-07-15 19:00:42 +00:00
daemon_pipe [ 0 ] = - 1 ;
2006-01-10 17:51:06 +00:00
# endif
2004-09-05 00:03:16 +00:00
2013-06-19 11:59:08 +08:00
if ( ! conf - > log_target ) {
2014-10-17 13:32:03 +02:00
# ifdef HAVE_SYSTEMD_JOURNAL
2013-12-03 01:09:56 +01:00
pa_log_target target = { . type = PA_LOG_JOURNAL , . file = NULL } ;
# else
2013-06-19 11:59:08 +08:00
pa_log_target target = { . type = PA_LOG_SYSLOG , . file = NULL } ;
2013-12-03 01:09:56 +01:00
# endif
2013-06-19 11:59:08 +08:00
pa_log_set_target ( & target ) ;
}
2004-09-05 00:03:16 +00:00
2006-01-10 17:51:06 +00:00
# ifdef HAVE_SETSID
2009-10-31 02:43:47 +01:00
if ( setsid ( ) < 0 ) {
pa_log ( _ ( " setsid() failed: %s " ) , pa_cstrerror ( errno ) ) ;
goto finish ;
}
2006-01-10 17:51:06 +00:00
# endif
2011-03-24 21:27:55 +00:00
# ifdef HAVE_FORK
2009-10-31 02:43:47 +01:00
/* We now are a session and process group leader. Let's fork
* again and let the father die , so that we ' ll become a
* process that can never acquire a TTY again , in a session and
* process group without leader */
2004-12-14 14:09:00 +00:00
2011-03-24 21:27:55 +00:00
if ( pipe ( daemon_pipe2 ) < 0 ) {
pa_log ( _ ( " pipe() failed: %s " ) , pa_cstrerror ( errno ) ) ;
goto finish ;
}
2009-10-31 02:43:47 +01:00
if ( ( child = fork ( ) ) < 0 ) {
pa_log ( _ ( " fork() failed: %s " ) , pa_cstrerror ( errno ) ) ;
2011-03-25 09:12:51 +00:00
pa_close_pipe ( daemon_pipe2 ) ;
2009-10-31 02:43:47 +01:00
goto finish ;
}
if ( child ! = 0 ) {
2011-03-24 21:27:55 +00:00
ssize_t n ;
/* Father */
pa_assert_se ( pa_close ( daemon_pipe2 [ 1 ] ) = = 0 ) ;
daemon_pipe2 [ 1 ] = - 1 ;
if ( ( n = pa_loop_read ( daemon_pipe2 [ 0 ] , & retval , sizeof ( retval ) , NULL ) ) ! = sizeof ( retval ) ) {
if ( n < 0 )
pa_log ( _ ( " read() failed: %s " ) , pa_cstrerror ( errno ) ) ;
retval = 1 ;
}
/* We now have to take care of signalling the first fork with
* the return value we ' ve received from this fork . . . */
pa_assert ( daemon_pipe [ 1 ] > = 0 ) ;
pa_loop_write ( daemon_pipe [ 1 ] , & retval , sizeof ( retval ) , NULL ) ;
pa_close ( daemon_pipe [ 1 ] ) ;
daemon_pipe [ 1 ] = - 1 ;
2009-10-31 02:43:47 +01:00
goto finish ;
}
2011-03-24 21:27:55 +00:00
pa_assert_se ( pa_close ( daemon_pipe2 [ 0 ] ) = = 0 ) ;
daemon_pipe2 [ 0 ] = - 1 ;
/* We no longer need the (first) daemon_pipe as it's handled in our child above */
pa_close_pipe ( daemon_pipe ) ;
2006-01-10 17:51:06 +00:00
# endif
# ifdef SIGTTOU
2004-12-14 14:20:52 +00:00
signal ( SIGTTOU , SIG_IGN ) ;
2006-01-10 17:51:06 +00:00
# endif
# ifdef SIGTTIN
2004-12-14 14:20:52 +00:00
signal ( SIGTTIN , SIG_IGN ) ;
2006-01-10 17:51:06 +00:00
# endif
# ifdef SIGTSTP
2004-12-14 14:20:52 +00:00
signal ( SIGTSTP , SIG_IGN ) ;
2006-01-10 17:51:06 +00:00
# endif
2007-01-04 13:43:45 +00:00
2009-10-31 02:43:47 +01:00
pa_nullify_stdfds ( ) ;
2004-07-12 21:28:11 +00:00
}
2004-07-17 15:00:31 +00:00
2009-09-02 00:42:54 +02:00
pa_set_env_and_record ( " PULSE_INTERNAL " , " 1 " ) ;
2007-10-28 19:13:50 +00:00
pa_assert_se ( chdir ( " / " ) = = 0 ) ;
main: set umask to 077 instead of 022
It was reported that PulseAudio weakens the umask to 022 if it's
initially set to 077. That's not as big problem as it might seem,
but it's still a problem. The umask affects the permissions of the state
files, and those aren't readable by other users anyway in the per-user
mode, because PulseAudio puts them in directories that aren't
accessible to other users. In the system mode the state files will be
readable by everyone, though, even by those users that don't otherwise
have access to PulseAudio. The state files are slightly
privacy-sensitive, because they contain e.g. history of applications
that have used PulseAudio.
I can't think of any use cases where access to the state files by other
users would be necessary, either in the per-user mode or in the system
mode, so let's use umask 077. This doesn't prevent access to any
sockets in the system mode, because all directories that PulseAudio
creates in the system mode will have permissions 755 regardless of the
umask, and the sockets themselves always have permissions 777.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=102060
2017-08-17 20:24:39 +03:00
umask ( 0077 ) ;
2007-01-04 13:43:45 +00:00
2009-06-19 17:37:18 +02:00
# ifdef HAVE_SYS_RESOURCE_H
set_all_rlimits ( conf ) ;
# endif
pa_rtclock_hrtimer_enable ( ) ;
2013-11-01 14:50:51 +01:00
if ( conf - > high_priority )
pa_raise_priority ( conf - > nice_level ) ;
2009-06-19 17:37:18 +02:00
2008-05-15 23:34:41 +00:00
if ( conf - > system_instance )
2006-07-19 17:44:19 +00:00
if ( change_user ( ) < 0 )
goto finish ;
2008-05-15 23:34:41 +00:00
2009-09-02 00:42:54 +02:00
pa_set_env_and_record ( " PULSE_SYSTEM " , conf - > system_instance ? " 1 " : " 0 " ) ;
2008-05-21 22:50:58 +00:00
2014-09-02 12:09:44 +02:00
pa_log_info ( " This is PulseAudio %s " , PACKAGE_VERSION ) ;
pa_log_debug ( " Compilation host: %s " , CANONICAL_HOST ) ;
pa_log_debug ( " Compilation CFLAGS: %s " , PA_CFLAGS ) ;
2008-09-01 02:38:32 +02:00
2014-11-11 15:39:59 +01:00
# ifdef HAVE_LIBSAMPLERATE
pa_log_warn ( " Compiled with DEPRECATED libsamplerate support! " ) ;
# endif
2008-09-05 15:42:39 +03:00
s = pa_uname_string ( ) ;
2014-09-02 12:09:44 +02:00
pa_log_debug ( " Running on host: %s " , s ) ;
2008-09-05 15:42:39 +03:00
pa_xfree ( s ) ;
2014-09-02 12:09:44 +02:00
pa_log_debug ( " Found %u CPUs. " , pa_ncpus ( ) ) ;
2009-01-22 02:16:53 +01:00
2016-08-18 01:06:47 +02:00
pa_log_info ( " Page size is %zu bytes " , pa_page_size ( ) ) ;
2008-09-05 15:42:39 +03:00
2008-09-01 02:38:32 +02:00
# ifdef HAVE_VALGRIND_MEMCHECK_H
2014-09-02 12:09:44 +02:00
pa_log_debug ( " Compiled with Valgrind support: yes " ) ;
2008-09-01 02:38:32 +02:00
# else
2014-09-02 12:09:44 +02:00
pa_log_debug ( " Compiled with Valgrind support: no " ) ;
2008-09-01 02:38:32 +02:00
# endif
2014-09-02 12:09:44 +02:00
pa_log_debug ( " Running in valgrind mode: %s " , pa_yes_no ( pa_in_valgrind ( ) ) ) ;
2008-10-04 00:13:29 +02:00
2014-09-02 12:09:44 +02:00
pa_log_debug ( " Running in VM: %s " , pa_yes_no ( pa_running_in_vm ( ) ) ) ;
2009-11-05 03:22:48 +01:00
2018-12-07 15:48:49 +08:00
# ifdef HAVE_RUNNING_FROM_BUILD_TREE
pa_log_debug ( " Running from build tree: %s " , pa_yes_no ( pa_run_from_build_tree ( ) ) ) ;
# else
pa_log_debug ( " Running from build tree: no " ) ;
# endif
2008-09-01 02:38:32 +02:00
# ifdef __OPTIMIZE__
2014-09-02 12:09:44 +02:00
pa_log_debug ( " Optimized build: yes " ) ;
2008-09-01 02:38:32 +02:00
# else
2014-09-02 12:09:44 +02:00
pa_log_debug ( " Optimized build: no " ) ;
2008-09-01 02:38:32 +02:00
# endif
2009-03-20 13:29:42 +01:00
# ifdef NDEBUG
2014-09-02 12:09:44 +02:00
pa_log_debug ( " NDEBUG defined, all asserts disabled. " ) ;
2009-03-20 13:29:42 +01:00
# elif defined(FASTPATH)
2014-09-02 12:09:44 +02:00
pa_log_debug ( " FASTPATH defined, only fast path asserts disabled. " ) ;
2009-03-20 13:29:42 +01:00
# else
2014-09-02 12:09:44 +02:00
pa_log_debug ( " All asserts enabled. " ) ;
2009-03-20 13:29:42 +01:00
# endif
2008-08-07 02:23:45 +02:00
if ( ! ( s = pa_machine_id ( ) ) ) {
pa_log ( _ ( " Failed to get machine ID " ) ) ;
goto finish ;
}
2014-09-02 12:09:44 +02:00
pa_log_info ( " Machine ID is %s. " , s ) ;
2008-08-07 02:23:45 +02:00
pa_xfree ( s ) ;
2009-04-13 22:21:26 +02:00
if ( ( s = pa_session_id ( ) ) ) {
2014-09-02 12:09:44 +02:00
pa_log_info ( " Session ID is %s. " , s ) ;
2009-06-19 17:37:18 +02:00
pa_xfree ( s ) ;
2009-04-13 22:21:26 +02:00
}
2008-05-21 22:50:58 +00:00
if ( ! ( s = pa_get_runtime_dir ( ) ) )
goto finish ;
2014-09-02 12:09:44 +02:00
pa_log_info ( " Using runtime directory %s. " , s ) ;
2008-05-15 23:34:41 +00:00
pa_xfree ( s ) ;
2008-08-07 02:23:45 +02:00
2008-05-21 22:50:58 +00:00
if ( ! ( s = pa_get_state_dir ( ) ) )
2008-08-07 02:23:45 +02:00
goto finish ;
2014-09-02 12:09:44 +02:00
pa_log_info ( " Using state directory %s. " , s ) ;
2008-05-21 22:50:58 +00:00
pa_xfree ( s ) ;
2014-09-02 12:09:44 +02:00
pa_log_info ( " Using modules directory %s. " , conf - > dl_search_path ) ;
2009-08-21 03:43:53 +02:00
2014-09-02 12:09:44 +02:00
pa_log_info ( " Running in system mode: %s " , pa_yes_no ( pa_in_system_mode ( ) ) ) ;
2007-01-04 13:43:45 +00:00
2009-06-17 03:00:51 +02:00
if ( pa_in_system_mode ( ) )
2016-07-14 11:38:35 +09:00
pa_log_warn ( _ ( " OK, so you are running PA in system mode. Please make sure that you actually do want to do that. \n "
2014-11-29 21:09:30 +05:00
" Please read http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/WhatIsWrongWithSystemWide/ for an explanation why system mode is usually a bad idea. " ) ) ;
2009-06-17 03:00:51 +02:00
2004-11-20 23:48:18 +00:00
if ( conf - > use_pid_file ) {
2008-06-11 17:38:50 +00:00
int z ;
if ( ( z = pa_pid_file_create ( " pulseaudio " ) ) ! = 0 ) {
if ( conf - > cmd = = PA_CMD_START & & z > 0 ) {
/* If we are already running and with are run in
* - - start mode , then let ' s return this as success . */
retval = 0 ;
goto finish ;
}
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " pa_pid_file_create() failed. " ) ) ;
2004-11-20 23:48:18 +00:00
goto finish ;
2004-12-15 01:17:04 +00:00
}
2004-11-20 23:48:18 +00:00
2013-06-27 19:28:09 +02:00
valid_pid_file = true ;
2004-11-20 23:48:18 +00:00
}
2009-05-25 23:56:38 +02:00
pa_disable_sigpipe ( ) ;
2006-07-19 17:44:19 +00:00
2007-10-28 19:13:50 +00:00
if ( pa_rtclock_hrtimer ( ) )
2015-12-21 10:54:58 +05:30
pa_log_info ( " System supports high resolution timers " ) ;
2007-10-28 19:13:50 +00:00
else
2015-12-21 10:54:58 +05:30
pa_log_info ( " System appears to not support high resolution timers " ) ;
2007-10-28 19:13:50 +00:00
2009-06-07 00:43:03 +02:00
if ( conf - > lock_memory ) {
2013-09-18 16:22:00 +02:00
# if defined(HAVE_SYS_MMAN_H) && !defined(__ANDROID__)
2009-06-07 00:43:03 +02:00
if ( mlockall ( MCL_FUTURE ) < 0 )
pa_log_warn ( " mlockall() failed: %s " , pa_cstrerror ( errno ) ) ;
else
2010-12-20 17:20:57 +08:00
pa_log_info ( " Successfully locked process into memory. " ) ;
2009-06-07 00:43:03 +02:00
# else
pa_log_warn ( " Memory locking requested but not supported on platform. " ) ;
2007-10-28 19:13:50 +00:00
# endif
2009-06-07 00:43:03 +02:00
}
2007-10-28 19:13:50 +00:00
2009-04-21 22:56:08 +02:00
pa_memtrap_install ( ) ;
2007-10-28 19:13:50 +00:00
pa_assert_se ( mainloop = pa_mainloop_new ( ) ) ;
2004-06-08 23:54:24 +00:00
2016-04-15 23:07:36 +02:00
if ( ! ( c = pa_core_new ( pa_mainloop_get_api ( mainloop ) , ! conf - > disable_shm ,
! conf - > disable_shm & & ! conf - > disable_memfd & & pa_memfd_is_locally_supported ( ) ,
conf - > shm_size ) ) ) {
2008-08-06 18:54:13 +02:00
pa_log ( _ ( " pa_core_new() failed. " ) ) ;
2006-08-19 01:20:13 +00:00
goto finish ;
2006-08-22 12:46:05 +00:00
}
2006-08-19 01:20:13 +00:00
2007-10-28 19:13:50 +00:00
c - > default_sample_spec = conf - > default_sample_spec ;
2011-08-02 18:37:27 -05:00
c - > alternate_sample_rate = conf - > alternate_sample_rate ;
2009-02-21 16:32:42 +01:00
c - > default_channel_map = conf - > default_channel_map ;
2007-10-28 19:13:50 +00:00
c - > default_n_fragments = conf - > default_n_fragments ;
c - > default_fragment_size_msec = conf - > default_fragment_size_msec ;
2011-09-13 21:15:49 +01:00
c - > deferred_volume_safety_margin_usec = conf - > deferred_volume_safety_margin_usec ;
c - > deferred_volume_extra_delay_usec = conf - > deferred_volume_extra_delay_usec ;
2015-03-24 10:29:16 +01:00
c - > lfe_crossover_freq = conf - > lfe_crossover_freq ;
2007-10-28 19:13:50 +00:00
c - > exit_idle_time = conf - > exit_idle_time ;
c - > scache_idle_time = conf - > scache_idle_time ;
c - > resample_method = conf - > resample_method ;
2007-11-01 02:58:26 +00:00
c - > realtime_priority = conf - > realtime_priority ;
2014-10-23 15:00:29 +02:00
c - > realtime_scheduling = conf - > realtime_scheduling ;
2017-01-28 13:19:08 +05:30
c - > avoid_resampling = conf - > avoid_resampling ;
2014-10-23 15:00:29 +02:00
c - > disable_remixing = conf - > disable_remixing ;
2017-01-04 11:55:49 -05:00
c - > remixing_use_all_sink_channels = conf - > remixing_use_all_sink_channels ;
2014-10-23 15:00:29 +02:00
c - > disable_lfe_remixing = conf - > disable_lfe_remixing ;
c - > deferred_volume = conf - > deferred_volume ;
c - > running_as_daemon = conf - > daemonize ;
2008-08-06 19:39:12 +02:00
c - > disallow_exit = conf - > disallow_exit ;
2009-01-27 04:39:07 +01:00
c - > flat_volumes = conf - > flat_volumes ;
2009-06-29 18:35:06 +03:00
# ifdef HAVE_DBUS
2009-06-16 19:03:22 +03:00
c - > server_type = conf - > local_server_type ;
2009-06-29 18:35:06 +03:00
# endif
2007-10-28 19:13:50 +00:00
2014-09-10 15:23:11 +02:00
pa_cpu_init ( & c - > cpu_info ) ;
2010-09-14 15:21:49 +05:30
2007-10-28 19:13:50 +00:00
pa_assert_se ( pa_signal_init ( pa_mainloop_get_api ( mainloop ) ) = = 0 ) ;
2004-09-03 20:14:23 +00:00
pa_signal_new ( SIGINT , signal_callback , c ) ;
pa_signal_new ( SIGTERM , signal_callback , c ) ;
2006-01-10 17:51:06 +00:00
# ifdef SIGUSR1
2004-09-03 20:14:23 +00:00
pa_signal_new ( SIGUSR1 , signal_callback , c ) ;
2006-01-10 17:51:06 +00:00
# endif
# ifdef SIGUSR2
2004-09-03 20:14:23 +00:00
pa_signal_new ( SIGUSR2 , signal_callback , c ) ;
2006-01-10 17:51:06 +00:00
# endif
# ifdef SIGHUP
2004-09-26 17:02:26 +00:00
pa_signal_new ( SIGHUP , signal_callback , c ) ;
2006-01-10 17:51:06 +00:00
# endif
2007-01-04 13:43:45 +00:00
2007-10-28 19:13:50 +00:00
if ( ! conf - > no_cpu_limit )
pa_assert_se ( pa_cpu_limit_init ( pa_mainloop_get_api ( mainloop ) ) = = 0 ) ;
2007-01-04 13:43:45 +00:00
2004-07-14 21:52:41 +00:00
buf = pa_strbuf_new ( ) ;
2008-05-15 23:34:41 +00:00
2009-06-12 07:16:05 +03:00
# ifdef HAVE_DBUS
2012-03-13 00:06:22 +01:00
pa_assert_se ( dbus_threads_init_default ( ) ) ;
2009-06-12 07:16:05 +03:00
if ( start_server ) {
# endif
if ( conf - > load_default_script_file ) {
FILE * f ;
if ( ( f = pa_daemon_conf_open_default_script_file ( conf ) ) ) {
r = pa_cli_command_execute_file_stream ( c , f , buf , & conf - > fail ) ;
fclose ( f ) ;
}
2008-05-15 23:34:41 +00:00
}
2004-09-14 23:08:39 +00:00
2009-06-12 07:16:05 +03:00
if ( r > = 0 )
r = pa_cli_command_execute ( c , conf - > script_commands , buf , & conf - > fail ) ;
2008-05-15 23:34:41 +00:00
2015-06-12 18:17:07 +05:30
pa_log_error ( " %s " , s = pa_strbuf_to_string_free ( buf ) ) ;
2009-06-12 07:16:05 +03:00
pa_xfree ( s ) ;
2007-01-04 13:43:45 +00:00
2009-06-12 07:16:05 +03:00
if ( r < 0 & & conf - > fail ) {
pa_log ( _ ( " Failed to initialize daemon. " ) ) ;
goto finish ;
}
2007-11-01 11:23:45 +00:00
2009-06-12 07:16:05 +03:00
if ( ! c - > modules | | pa_idxset_size ( c - > modules ) = = 0 ) {
pa_log ( _ ( " Daemon startup without any loaded modules, refusing to work. " ) ) ;
goto finish ;
}
# ifdef HAVE_DBUS
} else {
/* When we just provide the D-Bus server lookup service, we don't want
* any modules to be loaded . We haven ' t loaded any so far , so one might
* think there ' s no way to contact the server , but receiving certain
* signals could still cause modules to load . */
2013-06-27 19:28:09 +02:00
conf - > disallow_module_loading = true ;
2008-05-15 23:34:41 +00:00
}
2009-06-12 07:16:05 +03:00
# endif
2004-11-20 23:48:18 +00:00
2009-06-12 07:16:05 +03:00
/* We completed the initial module loading, so let's disable it
* from now on , if requested */
2014-10-23 15:00:29 +02:00
c - > disallow_module_loading = conf - > disallow_module_loading ;
2008-05-15 23:34:41 +00:00
2009-03-20 18:39:30 +02:00
# ifdef HAVE_DBUS
2009-06-12 07:16:05 +03:00
if ( ! conf - > system_instance ) {
2011-10-06 23:28:37 +03:00
if ( ( server_lookup = pa_dbusobj_server_lookup_new ( c ) ) ) {
if ( ! ( lookup_service_bus = register_dbus_name ( c , DBUS_BUS_SESSION , " org.PulseAudio1 " ) ) )
goto finish ;
}
2009-06-12 07:16:05 +03:00
}
2011-10-06 23:28:37 +03:00
if ( start_server )
server_bus = register_dbus_name ( c , conf - > system_instance ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION , " org.pulseaudio.Server " ) ;
2009-03-20 18:39:30 +02:00
# endif
2010-01-14 02:33:49 +01:00
# ifdef HAVE_FORK
2011-03-24 21:27:55 +00:00
if ( daemon_pipe2 [ 1 ] > = 0 ) {
2010-01-14 02:33:49 +01:00
int ok = 0 ;
2011-03-24 21:27:55 +00:00
pa_loop_write ( daemon_pipe2 [ 1 ] , & ok , sizeof ( ok ) , NULL ) ;
pa_close ( daemon_pipe2 [ 1 ] ) ;
daemon_pipe2 [ 1 ] = - 1 ;
2010-01-14 02:33:49 +01:00
}
# endif
2014-09-02 12:09:44 +02:00
pa_log_info ( " Daemon startup complete. " ) ;
2008-05-15 23:34:41 +00:00
2015-08-13 19:58:27 -03:00
# ifdef HAVE_SYSTEMD_DAEMON
sd_notify ( 0 , " READY=1 " ) ;
# endif
2008-05-15 23:34:41 +00:00
retval = 0 ;
if ( pa_mainloop_run ( mainloop , & retval ) < 0 )
goto finish ;
2014-09-02 12:09:44 +02:00
pa_log_info ( " Daemon shutdown initiated. " ) ;
2008-05-15 23:34:41 +00:00
2015-08-13 19:58:27 -03:00
# ifdef HAVE_SYSTEMD_DAEMON
sd_notify ( 0 , " STOPPING=1 " ) ;
# endif
2008-05-15 23:34:41 +00:00
finish :
2009-04-06 02:31:22 +02:00
# ifdef HAVE_DBUS
2009-06-12 07:16:05 +03:00
if ( server_bus )
pa_dbus_connection_unref ( server_bus ) ;
if ( lookup_service_bus )
pa_dbus_connection_unref ( lookup_service_bus ) ;
if ( server_lookup )
pa_dbusobj_server_lookup_free ( server_lookup ) ;
2009-04-06 02:31:22 +02:00
# endif
2006-01-10 17:51:06 +00:00
2008-08-09 03:49:42 +02:00
if ( autospawn_fd > = 0 ) {
if ( autospawn_locked )
pa_autospawn_lock_release ( ) ;
2013-06-27 19:28:09 +02:00
pa_autospawn_lock_done ( false ) ;
2008-08-09 03:49:42 +02:00
}
2008-06-11 17:38:50 +00:00
2008-05-15 23:34:41 +00:00
if ( c ) {
2011-08-16 10:54:24 +01:00
/* Ensure all the modules/samples are unloaded when the core is still ref'ed,
* as unlink callback hooks in modules may need the core to be ref ' ed */
pa_module_unload_all ( c ) ;
pa_scache_free_all ( c ) ;
2008-05-15 23:34:41 +00:00
pa_core_unref ( c ) ;
2014-09-02 12:09:44 +02:00
pa_log_info ( " Daemon terminated. " ) ;
2008-05-15 23:34:41 +00:00
}
2004-06-23 23:17:30 +00:00
2006-07-25 20:51:15 +00:00
if ( ! conf - > no_cpu_limit )
pa_cpu_limit_done ( ) ;
2007-01-04 13:43:45 +00:00
2004-06-23 23:17:30 +00:00
pa_signal_done ( ) ;
2007-01-04 13:43:45 +00:00
2008-05-15 23:34:41 +00:00
# ifdef HAVE_FORK
2011-03-25 09:12:51 +00:00
/* If we have daemon_pipe[1] still open, this means we've failed after
* the first fork , but before the second . Therefore just write to it . */
if ( daemon_pipe [ 1 ] > = 0 )
pa_loop_write ( daemon_pipe [ 1 ] , & retval , sizeof ( retval ) , NULL ) ;
else if ( daemon_pipe2 [ 1 ] > = 0 )
2011-03-24 21:27:55 +00:00
pa_loop_write ( daemon_pipe2 [ 1 ] , & retval , sizeof ( retval ) , NULL ) ;
2008-06-11 17:38:50 +00:00
2011-03-24 21:27:55 +00:00
pa_close_pipe ( daemon_pipe2 ) ;
2011-03-25 09:12:51 +00:00
pa_close_pipe ( daemon_pipe ) ;
2008-05-15 23:34:41 +00:00
# endif
2004-07-15 19:00:42 +00:00
2006-08-19 01:20:13 +00:00
if ( mainloop )
pa_mainloop_free ( mainloop ) ;
2004-09-13 23:28:30 +00:00
if ( conf )
2004-09-17 20:06:17 +00:00
pa_daemon_conf_free ( conf ) ;
2004-07-15 19:00:42 +00:00
2004-11-20 23:48:18 +00:00
if ( valid_pid_file )
pa_pid_file_remove ( ) ;
2007-01-04 13:43:45 +00:00
2009-09-02 00:42:54 +02:00
/* This has no real purpose except making things valgrind-clean */
pa_unset_env_recorded ( ) ;
2006-01-10 17:51:06 +00:00
# ifdef OS_IS_WIN32
WSACleanup ( ) ;
# endif
2008-02-15 18:03:11 +00:00
if ( ltdl_init )
pa_ltdl_done ( ) ;
2007-10-28 19:13:50 +00:00
# ifdef HAVE_DBUS
dbus_shutdown ( ) ;
# endif
2007-01-04 13:43:45 +00:00
2004-06-23 23:17:30 +00:00
return retval ;
2004-06-08 23:54:24 +00:00
}