]>
code.delx.au - pulseaudio/blob - src/pulsecore/core-util.c
2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2004 Joe Marcus Clarke
6 Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as
10 published by the Free Software Foundation; either version 2.1 of the
11 License, or (at your option) any later version.
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with PulseAudio; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
39 #include <sys/types.h>
45 #include <sys/utsname.h>
46 #include <sys/socket.h>
55 #if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
56 #define SCHED_RESET_ON_FORK 0x40000000
60 #ifdef HAVE_SYS_RESOURCE_H
61 #include <sys/resource.h>
64 #ifdef HAVE_SYS_CAPABILITY_H
65 #include <sys/capability.h>
68 #ifdef HAVE_SYS_MMAN_H
92 #ifdef HAVE_LIBSAMPLERATE
93 #include <samplerate.h>
105 #include <sys/personality.h>
108 #include <pulse/xmalloc.h>
109 #include <pulse/util.h>
110 #include <pulse/utf8.h>
112 #include <pulsecore/core-error.h>
113 #include <pulsecore/winsock.h>
114 #include <pulsecore/log.h>
115 #include <pulsecore/macro.h>
116 #include <pulsecore/thread.h>
117 #include <pulsecore/strbuf.h>
118 #include <pulsecore/usergroup.h>
119 #include <pulsecore/strlist.h>
120 #include <pulsecore/cpu-x86.h>
122 #include "core-util.h"
124 /* Not all platforms have this */
126 #define MSG_NOSIGNAL 0
129 #define NEWLINE " \r\n "
130 #define WHITESPACE " \n\r \t "
132 static pa_strlist
* recorded_env
= NULL
;
136 #define PULSE_ROOTENV "PULSE_ROOT"
138 int pa_set_root ( HANDLE handle
) {
139 char library_path
[ MAX_PATH
+ sizeof ( PULSE_ROOTENV
) + 1 ], * sep
;
141 strcpy ( library_path
, PULSE_ROOTENV
"=" );
143 /* FIXME: Needs to set errno */
145 if (! GetModuleFileName ( handle
, library_path
+ sizeof ( PULSE_ROOTENV
), MAX_PATH
))
148 sep
= strrchr ( library_path
, PA_PATH_SEP_CHAR
);
152 if ( _putenv ( library_path
) < 0 )
160 /** Make a file descriptor nonblock. Doesn't do any error checking */
161 void pa_make_fd_nonblock ( int fd
) {
167 pa_assert_se (( v
= fcntl ( fd
, F_GETFL
)) >= 0 );
169 if (!( v
& O_NONBLOCK
))
170 pa_assert_se ( fcntl ( fd
, F_SETFL
, v
| O_NONBLOCK
) >= 0 );
172 #elif defined(OS_IS_WIN32)
174 if ( ioctlsocket ( fd
, FIONBIO
, & arg
) < 0 ) {
175 pa_assert_se ( WSAGetLastError () == WSAENOTSOCK
);
176 pa_log_warn ( "Only sockets can be made non-blocking!" );
179 pa_log_warn ( "Non-blocking I/O not supported.!" );
184 /* Set the FD_CLOEXEC flag for a fd */
185 void pa_make_fd_cloexec ( int fd
) {
191 pa_assert_se (( v
= fcntl ( fd
, F_GETFD
, 0 )) >= 0 );
193 if (!( v
& FD_CLOEXEC
))
194 pa_assert_se ( fcntl ( fd
, F_SETFD
, v
| FD_CLOEXEC
) >= 0 );
199 /** Creates a directory securely */
200 int pa_make_secure_dir ( const char * dir
, mode_t m
, uid_t uid
, gid_t gid
) {
211 u
= umask ((~ m
) & 0777 );
217 if ( r
< 0 && errno
!= EEXIST
)
221 if ( uid
== ( uid_t
)- 1 )
223 if ( gid
== ( gid_t
)- 1 )
225 ( void ) chown ( dir
, uid
, gid
);
233 if ( lstat ( dir
, & st
) < 0 )
235 if ( stat ( dir
, & st
) < 0 )
240 if (! S_ISDIR ( st
. st_mode
) ||
241 ( st
. st_uid
!= uid
) ||
242 ( st
. st_gid
!= gid
) ||
243 (( st
. st_mode
& 0777 ) != m
)) {
248 pa_log_warn ( "Secure directory creation not supported on Win32." );
261 /* Return a newly allocated sting containing the parent directory of the specified file */
262 char * pa_parent_dir ( const char * fn
) {
263 char * slash
, * dir
= pa_xstrdup ( fn
);
265 if (( slash
= ( char *) pa_path_get_filename ( dir
)) == dir
) {
275 /* Creates a the parent directory of the specified path securely */
276 int pa_make_secure_parent_dir ( const char * fn
, mode_t m
, uid_t uid
, gid_t gid
) {
280 if (!( dir
= pa_parent_dir ( fn
)))
283 if ( pa_make_secure_dir ( dir
, m
, uid
, gid
) < 0 )
293 /** Platform independent read function. Necessary since not all
294 * systems treat all file descriptors equal. If type is
295 * non-NULL it is used to cache the type of the fd. This is
296 * useful for making sure that only a single syscall is executed per
297 * function call. The variable pointed to should be initialized to 0
299 ssize_t
pa_read ( int fd
, void * buf
, size_t count
, int * type
) {
303 if (! type
|| * type
== 0 ) {
306 if (( r
= recv ( fd
, buf
, count
, 0 )) >= 0 )
309 if ( WSAGetLastError () != WSAENOTSOCK
) {
310 errno
= WSAGetLastError ();
323 if (( r
= read ( fd
, buf
, count
)) < 0 )
331 /** Similar to pa_read(), but handles writes */
332 ssize_t
pa_write ( int fd
, const void * buf
, size_t count
, int * type
) {
334 if (! type
|| * type
== 0 ) {
338 if (( r
= send ( fd
, buf
, count
, MSG_NOSIGNAL
)) < 0 ) {
350 if ( WSAGetLastError () != WSAENOTSOCK
) {
351 errno
= WSAGetLastError ();
355 if ( errno
!= ENOTSOCK
)
366 if (( r
= write ( fd
, buf
, count
)) < 0 )
374 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
375 * unless EOF is reached or an error occurred */
376 ssize_t
pa_loop_read ( int fd
, void * data
, size_t size
, int * type
) {
392 if (( r
= pa_read ( fd
, data
, size
, type
)) < 0 )
399 data
= ( uint8_t *) data
+ r
;
406 /** Similar to pa_loop_read(), but wraps write() */
407 ssize_t
pa_loop_write ( int fd
, const void * data
, size_t size
, int * type
) {
423 if (( r
= pa_write ( fd
, data
, size
, type
)) < 0 )
430 data
= ( const uint8_t *) data
+ r
;
437 /** Platform independent read function. Necessary since not all
438 * systems treat all file descriptors equal. */
439 int pa_close ( int fd
) {
444 if (( ret
= closesocket ( fd
)) == 0 )
447 if ( WSAGetLastError () != WSAENOTSOCK
) {
448 errno
= WSAGetLastError ();
456 if (( r
= close ( fd
)) < 0 )
464 /* Print a warning messages in case that the given signal is not
465 * blocked or trapped */
466 void pa_check_signal_is_blocked ( int sig
) {
467 #ifdef HAVE_SIGACTION
471 /* If POSIX threads are supported use thread-aware
472 * pthread_sigmask() function, to check if the signal is
473 * blocked. Otherwise fall back to sigprocmask() */
476 if ( pthread_sigmask ( SIG_SETMASK
, NULL
, & set
) < 0 ) {
478 if ( sigprocmask ( SIG_SETMASK
, NULL
, & set
) < 0 ) {
479 pa_log ( "sigprocmask(): %s" , pa_cstrerror ( errno
));
486 if ( sigismember (& set
, sig
))
489 /* Check whether the signal is trapped */
491 if ( sigaction ( sig
, NULL
, & sa
) < 0 ) {
492 pa_log ( "sigaction(): %s" , pa_cstrerror ( errno
));
496 if ( sa
. sa_handler
!= SIG_DFL
)
499 pa_log_warn ( "%s is not trapped. This might cause malfunction!" , pa_sig2str ( sig
));
500 #else /* HAVE_SIGACTION */
501 pa_log_warn ( "%s might not be trapped. This might cause malfunction!" , pa_sig2str ( sig
));
505 /* The following function is based on an example from the GNU libc
506 * documentation. This function is similar to GNU's asprintf(). */
507 char * pa_sprintf_malloc ( const char * format
, ...) {
517 c
= pa_xrealloc ( c
, size
);
519 va_start ( ap
, format
);
520 r
= vsnprintf ( c
, size
, format
, ap
);
525 if ( r
> - 1 && ( size_t ) r
< size
)
528 if ( r
> - 1 ) /* glibc 2.1 */
535 /* Same as the previous function, but use a va_list instead of an
537 char * pa_vsprintf_malloc ( const char * format
, va_list ap
) {
547 c
= pa_xrealloc ( c
, size
);
550 r
= vsnprintf ( c
, size
, format
, aq
);
555 if ( r
> - 1 && ( size_t ) r
< size
)
558 if ( r
> - 1 ) /* glibc 2.1 */
565 /* Similar to OpenBSD's strlcpy() function */
566 char * pa_strlcpy ( char * b
, const char * s
, size_t l
) {
584 static int set_scheduler ( int rtprio
) {
585 struct sched_param sp
;
591 dbus_error_init (& error
);
595 sp
. sched_priority
= rtprio
;
597 #ifdef SCHED_RESET_ON_FORK
598 if ( pthread_setschedparam ( pthread_self (), SCHED_RR
| SCHED_RESET_ON_FORK
, & sp
) == 0 ) {
599 pa_log_debug ( "SCHED_RR|SCHED_RESET_ON_FORK worked." );
604 if ( pthread_setschedparam ( pthread_self (), SCHED_RR
, & sp
) == 0 ) {
605 pa_log_debug ( "SCHED_RR worked." );
610 /* Try to talk to RealtimeKit */
612 if (!( bus
= dbus_bus_get ( DBUS_BUS_SYSTEM
, & error
))) {
613 pa_log ( "Failed to connect to system bus: %s \n " , error
. message
);
614 dbus_error_free (& error
);
619 /* We need to disable exit on disconnect because otherwise
620 * dbus_shutdown will kill us. See
621 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
622 dbus_connection_set_exit_on_disconnect ( bus
, FALSE
);
624 r
= rtkit_make_realtime ( bus
, 0 , rtprio
);
625 dbus_connection_unref ( bus
);
628 pa_log_debug ( "RealtimeKit worked." );
640 /* Make the current thread a realtime thread, and acquire the highest
641 * rtprio we can get that is less or equal the specified parameter. If
642 * the thread is already realtime, don't do anything. */
643 int pa_make_realtime ( int rtprio
) {
645 #ifdef _POSIX_PRIORITY_SCHEDULING
648 if ( set_scheduler ( rtprio
) >= 0 ) {
649 pa_log_info ( "Successfully enabled SCHED_RR scheduling for thread, with priority %i." , rtprio
);
653 for ( p
= rtprio
- 1 ; p
>= 1 ; p
--)
654 if ( set_scheduler ( p
)) {
655 pa_log_info ( "Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i." , p
, rtprio
);
659 pa_log_info ( "Failed to acquire real-time scheduling: %s" , pa_cstrerror ( errno
));
668 static int set_nice ( int nice_level
) {
674 dbus_error_init (& error
);
677 if ( setpriority ( PRIO_PROCESS
, 0 , nice_level
) >= 0 ) {
678 pa_log_debug ( "setpriority() worked." );
683 /* Try to talk to RealtimeKit */
685 if (!( bus
= dbus_bus_get ( DBUS_BUS_SYSTEM
, & error
))) {
686 pa_log ( "Failed to connect to system bus: %s \n " , error
. message
);
687 dbus_error_free (& error
);
692 /* We need to disable exit on disconnect because otherwise
693 * dbus_shutdown will kill us. See
694 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
695 dbus_connection_set_exit_on_disconnect ( bus
, FALSE
);
697 r
= rtkit_make_high_priority ( bus
, 0 , nice_level
);
698 dbus_connection_unref ( bus
);
701 pa_log_debug ( "RealtimeKit worked." );
711 /* Raise the priority of the current process as much as possible that
712 * is <= the specified nice level..*/
713 int pa_raise_priority ( int nice_level
) {
715 #ifdef HAVE_SYS_RESOURCE_H
718 if ( set_nice ( nice_level
) >= 0 ) {
719 pa_log_info ( "Successfully gained nice level %i." , nice_level
);
723 for ( n
= nice_level
+ 1 ; n
< 0 ; n
++)
724 if ( set_nice ( n
) > 0 ) {
725 pa_log_info ( "Successfully acquired nice level %i, which is lower than the requested %i." , n
, nice_level
);
729 pa_log_info ( "Failed to acquire high-priority scheduling: %s" , pa_cstrerror ( errno
));
734 if ( nice_level
< 0 ) {
735 if (! SetPriorityClass ( GetCurrentProcess (), HIGH_PRIORITY_CLASS
)) {
736 pa_log_warn ( "SetPriorityClass() failed: 0x%08X" , GetLastError ());
741 pa_log_info ( "Successfully gained high priority class." );
748 /* Reset the priority to normal, inverting the changes made by
749 * pa_raise_priority() and pa_make_realtime()*/
750 void pa_reset_priority ( void ) {
751 #ifdef HAVE_SYS_RESOURCE_H
752 struct sched_param sp
;
754 setpriority ( PRIO_PROCESS
, 0 , 0 );
757 pthread_setschedparam ( pthread_self (), SCHED_OTHER
, & sp
);
761 SetPriorityClass ( GetCurrentProcess (), NORMAL_PRIORITY_CLASS
);
765 int pa_match ( const char * expr
, const char * v
) {
770 if ( regcomp (& re
, expr
, REG_NOSUB
| REG_EXTENDED
) != 0 ) {
775 if (( k
= regexec (& re
, v
, 0 , NULL
, 0 )) == 0 )
777 else if ( k
== REG_NOMATCH
)
790 /* Try to parse a boolean string value.*/
791 int pa_parse_boolean ( const char * v
) {
795 /* First we check language independant */
796 if (! strcmp ( v
, "1" ) || v
[ 0 ] == 'y' || v
[ 0 ] == 'Y' || v
[ 0 ] == 't' || v
[ 0 ] == 'T' || ! strcasecmp ( v
, "on" ))
798 else if (! strcmp ( v
, "0" ) || v
[ 0 ] == 'n' || v
[ 0 ] == 'N' || v
[ 0 ] == 'f' || v
[ 0 ] == 'F' || ! strcasecmp ( v
, "off" ))
801 /* And then we check language dependant */
802 if (( expr
= nl_langinfo ( YESEXPR
)))
804 if ( pa_match ( expr
, v
) > 0 )
807 if (( expr
= nl_langinfo ( NOEXPR
)))
809 if ( pa_match ( expr
, v
) > 0 )
816 /* Split the specified string wherever one of the strings in delimiter
817 * occurs. Each time it is called returns a newly allocated string
818 * with pa_xmalloc(). The variable state points to, should be
819 * initiallized to NULL before the first call. */
820 char * pa_split ( const char * c
, const char * delimiter
, const char ** state
) {
821 const char * current
= * state
? * state
: c
;
827 l
= strcspn ( current
, delimiter
);
833 return pa_xstrndup ( current
, l
);
836 /* Split a string into words. Otherwise similar to pa_split(). */
837 char * pa_split_spaces ( const char * c
, const char ** state
) {
838 const char * current
= * state
? * state
: c
;
841 if (!* current
|| * c
== 0 )
844 current
+= strspn ( current
, WHITESPACE
);
845 l
= strcspn ( current
, WHITESPACE
);
849 return pa_xstrndup ( current
, l
);
852 PA_STATIC_TLS_DECLARE ( signame
, pa_xfree
);
854 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
855 const char * pa_sig2str ( int sig
) {
868 char buf
[ SIG2STR_MAX
];
870 if ( sig2str ( sig
, buf
) == 0 ) {
871 pa_xfree ( PA_STATIC_TLS_GET ( signame
));
872 t
= pa_sprintf_malloc ( "SIG%s" , buf
);
873 PA_STATIC_TLS_SET ( signame
, t
);
881 case SIGHUP
: return "SIGHUP" ;
883 case SIGINT
: return "SIGINT" ;
885 case SIGQUIT
: return "SIGQUIT" ;
887 case SIGILL
: return "SIGULL" ;
889 case SIGTRAP
: return "SIGTRAP" ;
891 case SIGABRT
: return "SIGABRT" ;
893 case SIGBUS
: return "SIGBUS" ;
895 case SIGFPE
: return "SIGFPE" ;
897 case SIGKILL
: return "SIGKILL" ;
900 case SIGUSR1
: return "SIGUSR1" ;
902 case SIGSEGV
: return "SIGSEGV" ;
904 case SIGUSR2
: return "SIGUSR2" ;
907 case SIGPIPE
: return "SIGPIPE" ;
910 case SIGALRM
: return "SIGALRM" ;
912 case SIGTERM
: return "SIGTERM" ;
914 case SIGSTKFLT
: return "SIGSTKFLT" ;
917 case SIGCHLD
: return "SIGCHLD" ;
920 case SIGCONT
: return "SIGCONT" ;
923 case SIGSTOP
: return "SIGSTOP" ;
926 case SIGTSTP
: return "SIGTSTP" ;
929 case SIGTTIN
: return "SIGTTIN" ;
932 case SIGTTOU
: return "SIGTTOU" ;
935 case SIGURG
: return "SIGURG" ;
938 case SIGXCPU
: return "SIGXCPU" ;
941 case SIGXFSZ
: return "SIGXFSZ" ;
944 case SIGVTALRM
: return "SIGVTALRM" ;
947 case SIGPROF
: return "SIGPROF" ;
950 case SIGWINCH
: return "SIGWINCH" ;
953 case SIGIO
: return "SIGIO" ;
956 case SIGPWR
: return "SIGPWR" ;
959 case SIGSYS
: return "SIGSYS" ;
964 if ( sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
965 pa_xfree ( PA_STATIC_TLS_GET ( signame
));
966 t
= pa_sprintf_malloc ( "SIGRTMIN+%i" , sig
- SIGRTMIN
);
967 PA_STATIC_TLS_SET ( signame
, t
);
976 pa_xfree ( PA_STATIC_TLS_GET ( signame
));
977 t
= pa_sprintf_malloc ( "SIG%i" , sig
);
978 PA_STATIC_TLS_SET ( signame
, t
);
984 /* Check whether the specified GID and the group name match */
985 static int is_group ( gid_t gid
, const char * name
) {
986 struct group
* group
= NULL
;
990 if (!( group
= pa_getgrgid_malloc ( gid
)))
995 pa_log ( "pa_getgrgid_malloc(%u): %s" , gid
, pa_cstrerror ( errno
));
1000 r
= strcmp ( name
, group
-> gr_name
) == 0 ;
1003 pa_getgrgid_free ( group
);
1008 /* Check the current user is member of the specified group */
1009 int pa_own_uid_in_group ( const char * name
, gid_t
* gid
) {
1010 GETGROUPS_T
* gids
, tgid
;
1011 long n
= sysconf ( _SC_NGROUPS_MAX
);
1016 gids
= pa_xmalloc ( sizeof ( GETGROUPS_T
) * ( size_t ) n
);
1018 if (( n
= getgroups (( int ) n
, gids
)) < 0 ) {
1019 pa_log ( "getgroups(): %s" , pa_cstrerror ( errno
));
1023 for ( i
= 0 ; i
< n
; i
++) {
1025 if (( k
= is_group ( gids
[ i
], name
)) < 0 )
1034 if (( k
= is_group ( tgid
= getgid (), name
)) < 0 )
1050 /* Check whether the specifc user id is a member of the specified group */
1051 int pa_uid_in_group ( uid_t uid
, const char * name
) {
1052 struct group
* group
= NULL
;
1057 if (!( group
= pa_getgrnam_malloc ( name
)))
1065 for ( i
= group
-> gr_mem
; * i
; i
++) {
1066 struct passwd
* pw
= NULL
;
1069 if (!( pw
= pa_getpwnam_malloc (* i
)))
1072 if ( pw
-> pw_uid
== uid
)
1075 pa_getpwnam_free ( pw
);
1082 pa_getgrnam_free ( group
);
1087 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
1088 gid_t
pa_get_gid_of_group ( const char * name
) {
1089 gid_t ret
= ( gid_t
) - 1 ;
1090 struct group
* gr
= NULL
;
1093 if (!( gr
= pa_getgrnam_malloc ( name
)))
1103 pa_getgrnam_free ( gr
);
1107 int pa_check_in_group ( gid_t g
) {
1108 gid_t gids
[ NGROUPS_MAX
];
1111 if (( r
= getgroups ( NGROUPS_MAX
, gids
)) < 0 )
1121 #else /* HAVE_GRP_H */
1123 int pa_own_uid_in_group ( const char * name
, gid_t
* gid
) {
1129 int pa_uid_in_group ( uid_t uid
, const char * name
) {
1134 gid_t
pa_get_gid_of_group ( const char * name
) {
1139 int pa_check_in_group ( gid_t g
) {
1146 /* Lock or unlock a file entirely.
1147 (advisory on UNIX, mandatory on Windows) */
1148 int pa_lock_fd ( int fd
, int b
) {
1150 struct flock f_lock
;
1152 /* Try a R/W lock first */
1154 f_lock
. l_type
= ( short ) ( b
? F_WRLCK
: F_UNLCK
);
1155 f_lock
. l_whence
= SEEK_SET
;
1159 if ( fcntl ( fd
, F_SETLKW
, & f_lock
) >= 0 )
1162 /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
1163 if ( b
&& errno
== EBADF
) {
1164 f_lock
. l_type
= F_RDLCK
;
1165 if ( fcntl ( fd
, F_SETLKW
, & f_lock
) >= 0 )
1169 pa_log ( "%slock: %s" , ! b
? "un" : "" , pa_cstrerror ( errno
));
1173 HANDLE h
= ( HANDLE
) _get_osfhandle ( fd
);
1175 if ( b
&& LockFile ( h
, 0 , 0 , 0xFFFFFFFF , 0xFFFFFFFF ))
1177 if (! b
&& UnlockFile ( h
, 0 , 0 , 0xFFFFFFFF , 0xFFFFFFFF ))
1180 pa_log ( "%slock failed: 0x%08X" , ! b
? "un" : "" , GetLastError ());
1182 /* FIXME: Needs to set errno! */
1188 /* Remove trailing newlines from a string */
1189 char * pa_strip_nl ( char * s
) {
1192 s
[ strcspn ( s
, NEWLINE
)] = 0 ;
1196 char * pa_strip ( char * s
) {
1199 /* Drops trailing whitespace. Modifies the string in
1200 * place. Returns pointer to first non-space character */
1202 s
+= strspn ( s
, WHITESPACE
);
1204 for ( e
= s
; * e
; e
++)
1205 if (! strchr ( WHITESPACE
, * e
))
1216 /* Create a temporary lock file and lock it. */
1217 int pa_lock_lockfile ( const char * fn
) {
1224 if (( fd
= pa_open_cloexec ( fn
, O_CREAT
| O_RDWR
1228 , S_IRUSR
| S_IWUSR
)) < 0 ) {
1229 pa_log_warn ( "Failed to create lock file '%s': %s" , fn
, pa_cstrerror ( errno
));
1233 if ( pa_lock_fd ( fd
, 1 ) < 0 ) {
1234 pa_log_warn ( "Failed to lock file '%s'." , fn
);
1238 if ( fstat ( fd
, & st
) < 0 ) {
1239 pa_log_warn ( "Failed to fstat() file '%s': %s" , fn
, pa_cstrerror ( errno
));
1243 /* Check whether the file has been removed meanwhile. When yes,
1244 * restart this loop, otherwise, we're done */
1245 if ( st
. st_nlink
>= 1 )
1248 if ( pa_lock_fd ( fd
, 0 ) < 0 ) {
1249 pa_log_warn ( "Failed to unlock file '%s'." , fn
);
1253 if ( pa_close ( fd
) < 0 ) {
1254 pa_log_warn ( "Failed to close file '%s': %s" , fn
, pa_cstrerror ( errno
));
1265 int saved_errno
= errno
;
1267 errno
= saved_errno
;
1273 /* Unlock a temporary lcok file */
1274 int pa_unlock_lockfile ( const char * fn
, int fd
) {
1279 if ( unlink ( fn
) < 0 ) {
1280 pa_log_warn ( "Unable to remove lock file '%s': %s" , fn
, pa_cstrerror ( errno
));
1285 if ( pa_lock_fd ( fd
, 0 ) < 0 ) {
1286 pa_log_warn ( "Failed to unlock file '%s'." , fn
);
1290 if ( pa_close ( fd
) < 0 ) {
1291 pa_log_warn ( "Failed to close '%s': %s" , fn
, pa_cstrerror ( errno
));
1298 static char * get_pulse_home ( void ) {
1303 if (!( h
= pa_get_home_dir_malloc ())) {
1304 pa_log_error ( "Failed to get home directory." );
1308 if ( stat ( h
, & st
) < 0 ) {
1309 pa_log_error ( "Failed to stat home directory %s: %s" , h
, pa_cstrerror ( errno
));
1313 if ( st
. st_uid
!= getuid ()) {
1314 pa_log_error ( "Home directory %s not ours." , h
);
1319 ret
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
".pulse" , h
);
1327 char * pa_get_state_dir ( void ) {
1330 /* The state directory shall contain dynamic data that should be
1331 * kept across reboots, and is private to this user */
1333 if (!( d
= pa_xstrdup ( getenv ( "PULSE_STATE_PATH" ))))
1334 if (!( d
= get_pulse_home ()))
1337 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1338 * dir then this will break. */
1340 if ( pa_make_secure_dir ( d
, 0700U , ( uid_t
) - 1 , ( gid_t
) - 1 ) < 0 ) {
1341 pa_log_error ( "Failed to create secure directory: %s" , pa_cstrerror ( errno
));
1349 char * pa_get_home_dir_malloc ( void ) {
1351 size_t allocated
= 128 ;
1354 homedir
= pa_xmalloc ( allocated
);
1356 if (! pa_get_home_dir ( homedir
, allocated
)) {
1361 if ( strlen ( homedir
) < allocated
- 1 )
1371 char * pa_get_binary_name_malloc ( void ) {
1373 size_t allocated
= 128 ;
1376 t
= pa_xmalloc ( allocated
);
1378 if (! pa_get_binary_name ( t
, allocated
)) {
1383 if ( strlen ( t
) < allocated
- 1 )
1393 static char * make_random_dir ( mode_t m
) {
1394 static const char table
[] =
1395 "abcdefghijklmnopqrstuvwxyz"
1396 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1402 fn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"pulse-XXXXXXXXXXXX" , pa_get_temp_dir ());
1403 pathlen
= strlen ( fn
);
1411 for ( i
= pathlen
- 12 ; i
< pathlen
; i
++)
1412 fn
[ i
] = table
[ rand () % ( sizeof ( table
)- 1 )];
1414 u
= umask ((~ m
) & 0777 );
1417 saved_errno
= errno
;
1419 errno
= saved_errno
;
1424 if ( errno
!= EEXIST
) {
1425 pa_log_error ( "Failed to create random directory %s: %s" , fn
, pa_cstrerror ( errno
));
1432 static int make_random_dir_and_link ( mode_t m
, const char * k
) {
1435 if (!( p
= make_random_dir ( m
)))
1438 if ( symlink ( p
, k
) < 0 ) {
1439 int saved_errno
= errno
;
1441 if ( errno
!= EEXIST
)
1442 pa_log_error ( "Failed to symlink %s to %s: %s" , k
, p
, pa_cstrerror ( errno
));
1447 errno
= saved_errno
;
1455 char * pa_get_runtime_dir ( void ) {
1456 char * d
, * k
= NULL
, * p
= NULL
, * t
= NULL
, * mid
;
1460 /* The runtime directory shall contain dynamic data that needs NOT
1461 * to be kept accross reboots and is usuallly private to the user,
1462 * except in system mode, where it might be accessible by other
1463 * users, too. Since we need POSIX locking and UNIX sockets in
1464 * this directory, we link it to a random subdir in /tmp, if it
1465 * was not explicitly configured. */
1467 m
= pa_in_system_mode () ? 0755U : 0700U ;
1469 if (( d
= getenv ( "PULSE_RUNTIME_PATH" ))) {
1471 if ( pa_make_secure_dir ( d
, m
, ( uid_t
) - 1 , ( gid_t
) - 1 ) < 0 ) {
1472 pa_log_error ( "Failed to create secure directory: %s" , pa_cstrerror ( errno
));
1476 return pa_xstrdup ( d
);
1479 if (!( d
= get_pulse_home ()))
1482 if ( pa_make_secure_dir ( d
, m
, ( uid_t
) - 1 , ( gid_t
) - 1 ) < 0 ) {
1483 pa_log_error ( "Failed to create secure directory: %s" , pa_cstrerror ( errno
));
1488 if (!( mid
= pa_machine_id ())) {
1493 k
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s-runtime" , d
, mid
);
1498 /* OK, first let's check if the "runtime" symlink is already
1501 if (!( p
= pa_readlink ( k
))) {
1503 if ( errno
!= ENOENT
) {
1504 pa_log_error ( "Failed to stat runtime directory %s: %s" , k
, pa_cstrerror ( errno
));
1508 /* Hmm, so the runtime directory didn't exist yet, so let's
1509 * create one in /tmp and symlink that to it */
1511 if ( make_random_dir_and_link ( 0700 , k
) < 0 ) {
1513 /* Mhmm, maybe another process was quicker than us,
1514 * let's check if that was valid */
1515 if ( errno
== EEXIST
)
1524 /* Make sure that this actually makes sense */
1525 if (! pa_is_path_absolute ( p
)) {
1526 pa_log_error ( "Path %s in link %s is not absolute." , p
, k
);
1531 /* Hmm, so this symlink is still around, make sure nobody fools
1534 if ( lstat ( p
, & st
) < 0 ) {
1536 if ( errno
!= ENOENT
) {
1537 pa_log_error ( "Failed to stat runtime directory %s: %s" , p
, pa_cstrerror ( errno
));
1543 if ( S_ISDIR ( st
. st_mode
) &&
1544 ( st
. st_uid
== getuid ()) &&
1545 (( st
. st_mode
& 0777 ) == 0700 )) {
1551 pa_log_info ( "Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory." );
1557 /* Hmm, so the link points to some nonexisting or invalid
1558 * dir. Let's replace it by a new link. We first create a
1559 * temporary link and then rename that to allow concurrent
1560 * execution of this function. */
1562 t
= pa_sprintf_malloc ( "%s.tmp" , k
);
1564 if ( make_random_dir_and_link ( 0700 , t
) < 0 ) {
1566 if ( errno
!= EEXIST
) {
1567 pa_log_error ( "Failed to symlink %s: %s" , t
, pa_cstrerror ( errno
));
1574 /* Hmm, someone lese was quicker then us. Let's give
1575 * him some time to finish, and retry. */
1580 /* OK, we succeeded in creating the temporary symlink, so
1581 * let's rename it */
1582 if ( rename ( t
, k
) < 0 ) {
1583 pa_log_error ( "Failed to rename %s to %s: %s" , t
, k
, pa_cstrerror ( errno
));
1599 /* Try to open a configuration file. If "env" is specified, open the
1600 * value of the specified environment variable. Otherwise look for a
1601 * file "local" in the home directory or a file "global" in global
1602 * file system. If "result" is non-NULL, a pointer to a newly
1603 * allocated buffer containing the used configuration file is
1605 FILE * pa_open_config_file ( const char * global
, const char * local
, const char * env
, char ** result
) {
1610 if (! getenv ( PULSE_ROOTENV
))
1614 if ( env
&& ( fn
= getenv ( env
))) {
1618 if (! ExpandEnvironmentStrings ( fn
, buf
, PATH_MAX
))
1619 /* FIXME: Needs to set errno! */
1624 if (( f
= pa_fopen_cloexec ( fn
, "r" ))) {
1626 * result
= pa_xstrdup ( fn
);
1631 pa_log_warn ( "Failed to open configuration file '%s': %s" , fn
, pa_cstrerror ( errno
));
1641 if (( e
= getenv ( "PULSE_CONFIG_PATH" )))
1642 fn
= lfn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , e
, local
);
1643 else if (( h
= pa_get_home_dir_malloc ())) {
1644 fn
= lfn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s" , h
, local
);
1650 if (! ExpandEnvironmentStrings ( lfn
, buf
, PATH_MAX
)) {
1651 /* FIXME: Needs to set errno! */
1658 if (( f
= pa_fopen_cloexec ( fn
, "r" ))) {
1660 * result
= pa_xstrdup ( fn
);
1666 if ( errno
!= ENOENT
) {
1667 pa_log_warn ( "Failed to open configuration file '%s': %s" , fn
, pa_cstrerror ( errno
));
1679 if (! ExpandEnvironmentStrings ( global
, buf
, PATH_MAX
))
1680 /* FIXME: Needs to set errno! */
1685 if (( f
= pa_fopen_cloexec ( global
, "r" ))) {
1688 * result
= pa_xstrdup ( global
);
1698 char * pa_find_config_file ( const char * global
, const char * local
, const char * env
) {
1703 if (! getenv ( PULSE_ROOTENV
))
1707 if ( env
&& ( fn
= getenv ( env
))) {
1710 if (! ExpandEnvironmentStrings ( fn
, buf
, PATH_MAX
))
1711 /* FIXME: Needs to set errno! */
1716 if ( access ( fn
, R_OK
) == 0 )
1717 return pa_xstrdup ( fn
);
1719 pa_log_warn ( "Failed to access configuration file '%s': %s" , fn
, pa_cstrerror ( errno
));
1728 if (( e
= getenv ( "PULSE_CONFIG_PATH" )))
1729 fn
= lfn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , e
, local
);
1730 else if (( h
= pa_get_home_dir_malloc ())) {
1731 fn
= lfn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s" , h
, local
);
1737 if (! ExpandEnvironmentStrings ( lfn
, buf
, PATH_MAX
)) {
1738 /* FIXME: Needs to set errno! */
1745 if ( access ( fn
, R_OK
) == 0 ) {
1746 char * r
= pa_xstrdup ( fn
);
1751 if ( errno
!= ENOENT
) {
1752 pa_log_warn ( "Failed to access configuration file '%s': %s" , fn
, pa_cstrerror ( errno
));
1762 if (! ExpandEnvironmentStrings ( global
, buf
, PATH_MAX
))
1763 /* FIXME: Needs to set errno! */
1768 if ( access ( global
, R_OK
) == 0 )
1769 return pa_xstrdup ( global
);
1777 /* Format the specified data as a hexademical string */
1778 char * pa_hexstr ( const uint8_t * d
, size_t dlength
, char * s
, size_t slength
) {
1779 size_t i
= 0 , j
= 0 ;
1780 const char hex
[] = "0123456789abcdef" ;
1784 pa_assert ( slength
> 0 );
1786 while ( i
< dlength
&& j
+ 3 <= slength
) {
1787 s
[ j
++] = hex
[* d
>> 4 ];
1788 s
[ j
++] = hex
[* d
& 0xF ];
1794 s
[ j
< slength
? j
: slength
] = 0 ;
1798 /* Convert a hexadecimal digit to a number or -1 if invalid */
1799 static int hexc ( char c
) {
1800 if ( c
>= '0' && c
<= '9' )
1803 if ( c
>= 'A' && c
<= 'F' )
1804 return c
- 'A' + 10 ;
1806 if ( c
>= 'a' && c
<= 'f' )
1807 return c
- 'a' + 10 ;
1813 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1814 size_t pa_parsehex ( const char * p
, uint8_t * d
, size_t dlength
) {
1820 while ( j
< dlength
&& * p
) {
1823 if (( b
= hexc (*( p
++))) < 0 )
1826 d
[ j
] = ( uint8_t ) ( b
<< 4 );
1831 if (( b
= hexc (*( p
++))) < 0 )
1834 d
[ j
] |= ( uint8_t ) b
;
1841 /* Returns nonzero when *s starts with *pfx */
1842 pa_bool_t
pa_startswith ( const char * s
, const char * pfx
) {
1850 return strlen ( s
) >= l
&& strncmp ( s
, pfx
, l
) == 0 ;
1853 /* Returns nonzero when *s ends with *sfx */
1854 pa_bool_t
pa_endswith ( const char * s
, const char * sfx
) {
1863 return l1
>= l2
&& strcmp ( s
+ l1
- l2
, sfx
) == 0 ;
1866 pa_bool_t
pa_is_path_absolute ( const char * fn
) {
1872 return strlen ( fn
) >= 3 && isalpha ( fn
[ 0 ]) && fn
[ 1 ] == ':' && fn
[ 2 ] == ' \\ ' ;
1876 char * pa_make_path_absolute ( const char * p
) {
1882 if ( pa_is_path_absolute ( p
))
1883 return pa_xstrdup ( p
);
1885 if (!( cwd
= pa_getcwd ()))
1886 return pa_xstrdup ( p
);
1888 r
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , cwd
, p
);
1893 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
1894 * if fn is non-null and starts with / return fn
1895 * otherwise append fn to the run time path and return it */
1896 static char * get_path ( const char * fn
, pa_bool_t prependmid
, pa_bool_t rt
) {
1899 rtp
= rt
? pa_get_runtime_dir () : pa_get_state_dir ();
1904 if ( pa_is_path_absolute ( fn
))
1905 return pa_xstrdup ( fn
);
1913 if (!( mid
= pa_machine_id ())) {
1918 r
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s-%s" , rtp
, mid
, fn
);
1921 r
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , rtp
, fn
);
1929 char * pa_runtime_path ( const char * fn
) {
1930 return get_path ( fn
, FALSE
, TRUE
);
1933 char * pa_state_path ( const char * fn
, pa_bool_t appendmid
) {
1934 return get_path ( fn
, appendmid
, FALSE
);
1937 /* Convert the string s to a signed integer in *ret_i */
1938 int pa_atoi ( const char * s
, int32_t * ret_i
) {
1946 l
= strtol ( s
, & x
, 0 );
1948 if (! x
|| * x
|| errno
) {
1954 if (( int32_t ) l
!= l
) {
1959 * ret_i
= ( int32_t ) l
;
1964 /* Convert the string s to an unsigned integer in *ret_u */
1965 int pa_atou ( const char * s
, uint32_t * ret_u
) {
1973 l
= strtoul ( s
, & x
, 0 );
1975 if (! x
|| * x
|| errno
) {
1981 if (( uint32_t ) l
!= l
) {
1986 * ret_u
= ( uint32_t ) l
;
1991 #ifdef HAVE_STRTOF_L
1992 static locale_t c_locale
= NULL
;
1994 static void c_locale_destroy ( void ) {
1995 freelocale ( c_locale
);
1999 int pa_atod ( const char * s
, double * ret_d
) {
2006 /* This should be locale independent */
2008 #ifdef HAVE_STRTOF_L
2012 if (( c_locale
= newlocale ( LC_ALL_MASK
, "C" , NULL
)))
2013 atexit ( c_locale_destroy
);
2019 f
= strtod_l ( s
, & x
, c_locale
);
2027 if (! x
|| * x
|| errno
) {
2038 /* Same as snprintf, but guarantees NUL-termination on every platform */
2039 size_t pa_snprintf ( char * str
, size_t size
, const char * format
, ...) {
2044 pa_assert ( size
> 0 );
2047 va_start ( ap
, format
);
2048 ret
= pa_vsnprintf ( str
, size
, format
, ap
);
2054 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2055 size_t pa_vsnprintf ( char * str
, size_t size
, const char * format
, va_list ap
) {
2059 pa_assert ( size
> 0 );
2062 ret
= vsnprintf ( str
, size
, format
, ap
);
2069 if (( size_t ) ret
> size
- 1 )
2072 return ( size_t ) ret
;
2075 /* Truncate the specified string, but guarantee that the string
2076 * returned still validates as UTF8 */
2077 char * pa_truncate_utf8 ( char * c
, size_t l
) {
2079 pa_assert ( pa_utf8_valid ( c
));
2086 while ( l
> 0 && ! pa_utf8_valid ( c
))
2092 char * pa_getcwd ( void ) {
2096 char * p
= pa_xmalloc ( l
);
2100 if ( errno
!= ERANGE
)
2108 void * pa_will_need ( const void * p
, size_t l
) {
2109 #ifdef RLIMIT_MEMLOCK
2120 a
= PA_PAGE_ALIGN_PTR ( p
);
2121 size
= ( size_t ) (( const uint8_t *) p
+ l
- ( const uint8_t *) a
);
2123 #ifdef HAVE_POSIX_MADVISE
2124 if (( r
= posix_madvise (( void *) a
, size
, POSIX_MADV_WILLNEED
)) == 0 ) {
2125 pa_log_debug ( "posix_madvise() worked fine!" );
2130 /* Most likely the memory was not mmap()ed from a file and thus
2131 * madvise() didn't work, so let's misuse mlock() do page this
2132 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2133 * inviting, the man page of mlock() tells us: "All pages that
2134 * contain a part of the specified address range are guaranteed to
2135 * be resident in RAM when the call returns successfully." */
2137 #ifdef RLIMIT_MEMLOCK
2138 pa_assert_se ( getrlimit ( RLIMIT_MEMLOCK
, & rlim
) == 0 );
2140 if ( rlim
. rlim_cur
< PA_PAGE_SIZE
) {
2141 pa_log_debug ( "posix_madvise() failed (or doesn't exist), resource limits don't allow mlock(), can't page in data: %s" , pa_cstrerror ( r
));
2146 bs
= PA_PAGE_ALIGN (( size_t ) rlim
. rlim_cur
);
2148 bs
= PA_PAGE_SIZE
* 4 ;
2151 pa_log_debug ( "posix_madvise() failed (or doesn't exist), trying mlock(): %s" , pa_cstrerror ( r
));
2154 while ( size
> 0 && bs
> 0 ) {
2159 if ( mlock ( a
, bs
) < 0 ) {
2160 bs
= PA_PAGE_ALIGN ( bs
/ 2 );
2164 pa_assert_se ( munlock ( a
, bs
) == 0 );
2166 a
= ( const uint8_t *) a
+ bs
;
2172 pa_log_debug ( "mlock() failed too (or doesn't exist), giving up: %s" , pa_cstrerror ( errno
));
2174 pa_log_debug ( "mlock() worked fine!" );
2179 void pa_close_pipe ( int fds
[ 2 ]) {
2183 pa_assert_se ( pa_close ( fds
[ 0 ]) == 0 );
2186 pa_assert_se ( pa_close ( fds
[ 1 ]) == 0 );
2188 fds
[ 0 ] = fds
[ 1 ] = - 1 ;
2191 char * pa_readlink ( const char * p
) {
2200 if (( n
= readlink ( p
, c
, l
- 1 )) < 0 ) {
2205 if (( size_t ) n
< l
- 1 ) {
2215 int pa_close_all ( int except_fd
, ...) {
2220 va_start ( ap
, except_fd
);
2223 for ( n
= 1 ; va_arg ( ap
, int ) >= 0 ; n
++)
2228 p
= pa_xnew ( int , n
+ 1 );
2230 va_start ( ap
, except_fd
);
2233 if ( except_fd
>= 0 ) {
2237 while (( fd
= va_arg ( ap
, int )) >= 0 )
2244 r
= pa_close_allv ( p
);
2250 int pa_close_allv ( const int except_fds
[]) {
2258 if (( d
= opendir ( "/proc/self/fd" ))) {
2262 while (( de
= readdir ( d
))) {
2268 if ( de
-> d_name
[ 0 ] == '.' )
2272 l
= strtol ( de
-> d_name
, & e
, 10 );
2273 if ( errno
!= 0 || ! e
|| * e
) {
2281 if (( long ) fd
!= l
) {
2294 for ( i
= 0 ; except_fds
[ i
] >= 0 ; i
++)
2295 if ( except_fds
[ i
] == fd
) {
2303 if ( pa_close ( fd
) < 0 ) {
2304 saved_errno
= errno
;
2306 errno
= saved_errno
;
2318 if ( getrlimit ( RLIMIT_NOFILE
, & rl
) >= 0 )
2319 maxfd
= ( int ) rl
. rlim_max
;
2321 maxfd
= sysconf ( _SC_OPEN_MAX
);
2323 for ( fd
= 3 ; fd
< maxfd
; fd
++) {
2328 for ( i
= 0 ; except_fds
[ i
] >= 0 ; i
++)
2329 if ( except_fds
[ i
] == fd
) {
2337 if ( pa_close ( fd
) < 0 && errno
!= EBADF
)
2344 int pa_unblock_sigs ( int except
, ...) {
2349 va_start ( ap
, except
);
2352 for ( n
= 1 ; va_arg ( ap
, int ) >= 0 ; n
++)
2357 p
= pa_xnew ( int , n
+ 1 );
2359 va_start ( ap
, except
);
2366 while (( sig
= va_arg ( ap
, int )) >= 0 )
2373 r
= pa_unblock_sigsv ( p
);
2379 int pa_unblock_sigsv ( const int except
[]) {
2383 if ( sigemptyset (& ss
) < 0 )
2386 for ( i
= 0 ; except
[ i
] > 0 ; i
++)
2387 if ( sigaddset (& ss
, except
[ i
]) < 0 )
2390 return sigprocmask ( SIG_SETMASK
, & ss
, NULL
);
2393 int pa_reset_sigs ( int except
, ...) {
2398 va_start ( ap
, except
);
2401 for ( n
= 1 ; va_arg ( ap
, int ) >= 0 ; n
++)
2406 p
= pa_xnew ( int , n
+ 1 );
2408 va_start ( ap
, except
);
2415 while (( sig
= va_arg ( ap
, int )) >= 0 )
2422 r
= pa_reset_sigsv ( p
);
2428 int pa_reset_sigsv ( const int except
[]) {
2431 for ( sig
= 1 ; sig
< NSIG
; sig
++) {
2432 pa_bool_t reset
= TRUE
;
2443 for ( i
= 0 ; except
[ i
] > 0 ; i
++) {
2444 if ( sig
== except
[ i
]) {
2453 struct sigaction sa
;
2455 memset (& sa
, 0 , sizeof ( sa
));
2456 sa
. sa_handler
= SIG_DFL
;
2458 /* On Linux the first two RT signals are reserved by
2459 * glibc, and sigaction() will return EINVAL for them. */
2460 if (( sigaction ( sig
, & sa
, NULL
) < 0 ))
2461 if ( errno
!= EINVAL
)
2469 void pa_set_env ( const char * key
, const char * value
) {
2473 /* This is not thread-safe */
2475 putenv ( pa_sprintf_malloc ( "%s=%s" , key
, value
));
2478 void pa_set_env_and_record ( const char * key
, const char * value
) {
2482 /* This is not thread-safe */
2484 pa_set_env ( key
, value
);
2485 recorded_env
= pa_strlist_prepend ( recorded_env
, key
);
2488 void pa_unset_env_recorded ( void ) {
2490 /* This is not thread-safe */
2495 recorded_env
= pa_strlist_pop ( recorded_env
, & s
);
2505 pa_bool_t
pa_in_system_mode ( void ) {
2508 if (!( e
= getenv ( "PULSE_SYSTEM" )))
2514 char * pa_get_user_name_malloc ( void ) {
2518 #ifdef _SC_LOGIN_NAME_MAX
2519 k
= ( ssize_t
) sysconf ( _SC_LOGIN_NAME_MAX
);
2525 u
= pa_xnew ( char , k
+ 1 );
2527 if (!( pa_get_user_name ( u
, k
))) {
2535 char * pa_get_host_name_malloc ( void ) {
2544 if (! pa_get_host_name ( c
, l
)) {
2546 if ( errno
!= EINVAL
&& errno
!= ENAMETOOLONG
)
2549 } else if ( strlen ( c
) < l
- 1 ) {
2557 u
= pa_utf8_filter ( c
);
2562 /* Hmm, the hostname is as long the space we offered the
2563 * function, we cannot know if it fully fit in, so let's play
2564 * safe and retry. */
2573 char * pa_machine_id ( void ) {
2577 /* The returned value is supposed be some kind of ascii identifier
2578 * that is unique and stable across reboots. */
2580 /* First we try the D-Bus UUID, which is the best option we have,
2581 * since it fits perfectly our needs and is not as volatile as the
2582 * hostname which might be set from dhcp. */
2584 if (( f
= pa_fopen_cloexec ( PA_MACHINE_ID
, "r" ))) {
2585 char ln
[ 34 ] = "" , * r
;
2587 r
= fgets ( ln
, sizeof ( ln
)- 1 , f
);
2593 return pa_utf8_filter ( ln
);
2596 if (( h
= pa_get_host_name_malloc ()))
2599 /* If no hostname was set we use the POSIX hostid. It's usually
2600 * the IPv4 address. Might not be that stable. */
2601 return pa_sprintf_malloc ( "%08lx" , ( unsigned long ) gethostid
);
2604 char * pa_session_id ( void ) {
2607 if (!( e
= getenv ( "XDG_SESSION_COOKIE" )))
2610 return pa_utf8_filter ( e
);
2613 char * pa_uname_string ( void ) {
2616 pa_assert_se ( uname (& u
) >= 0 );
2618 return pa_sprintf_malloc ( "%s %s %s %s" , u
. sysname
, u
. machine
, u
. release
, u
. version
);
2621 #ifdef HAVE_VALGRIND_MEMCHECK_H
2622 pa_bool_t
pa_in_valgrind ( void ) {
2625 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
2626 * here instead of really checking whether we run in valgrind or
2630 b
= getenv ( "VALGRIND" ) ? 2 : 1 ;
2636 unsigned pa_gcd ( unsigned a
, unsigned b
) {
2647 void pa_reduce ( unsigned * num
, unsigned * den
) {
2649 unsigned gcd
= pa_gcd (* num
, * den
);
2657 pa_assert ( pa_gcd (* num
, * den
) == 1 );
2660 unsigned pa_ncpus ( void ) {
2663 #ifdef _SC_NPROCESSORS_CONF
2664 ncpus
= sysconf ( _SC_NPROCESSORS_CONF
);
2669 return ncpus
<= 0 ? 1 : ( unsigned ) ncpus
;
2672 char * pa_replace ( const char * s
, const char * a
, const char * b
) {
2681 sb
= pa_strbuf_new ();
2686 if (!( p
= strstr ( s
, a
)))
2689 pa_strbuf_putsn ( sb
, s
, p
- s
);
2690 pa_strbuf_puts ( sb
, b
);
2694 pa_strbuf_puts ( sb
, s
);
2696 return pa_strbuf_tostring_free ( sb
);
2699 char * pa_escape ( const char * p
, const char * chars
) {
2702 pa_strbuf
* buf
= pa_strbuf_new ();
2704 for ( s
= p
; * s
; ++ s
) {
2706 pa_strbuf_putc ( buf
, ' \\ ' );
2708 for ( c
= chars
; * c
; ++ c
) {
2710 pa_strbuf_putc ( buf
, ' \\ ' );
2715 pa_strbuf_putc ( buf
, * s
);
2718 return pa_strbuf_tostring_free ( buf
);
2721 char * pa_unescape ( char * p
) {
2723 pa_bool_t escaped
= FALSE
;
2725 for ( s
= p
, d
= p
; * s
; s
++) {
2726 if (! escaped
&& * s
== ' \\ ' ) {
2740 char * pa_realpath ( const char * path
) {
2744 /* We want only abolsute paths */
2745 if ( path
[ 0 ] != '/' ) {
2750 #if defined(__GLIBC__) || defined(__APPLE__)
2754 if (!( r
= realpath ( path
, NULL
)))
2757 /* We copy this here in case our pa_xmalloc() is not
2758 * implemented on top of libc malloc() */
2762 #elif defined(PATH_MAX)
2765 path_buf
= pa_xmalloc ( PATH_MAX
);
2767 if (!( t
= realpath ( path
, path_buf
))) {
2773 #error "It's not clear whether this system supports realpath(..., NULL) like GNU libc does. If it doesn't we need a private version of realpath() here."
2779 void pa_disable_sigpipe ( void ) {
2782 struct sigaction sa
;
2786 if ( sigaction ( SIGPIPE
, NULL
, & sa
) < 0 ) {
2787 pa_log ( "sigaction(): %s" , pa_cstrerror ( errno
));
2791 sa
. sa_handler
= SIG_IGN
;
2793 if ( sigaction ( SIGPIPE
, & sa
, NULL
) < 0 ) {
2794 pa_log ( "sigaction(): %s" , pa_cstrerror ( errno
));
2800 void pa_xfreev ( void ** a
) {
2806 for ( p
= a
; * p
; p
++)
2812 char ** pa_split_spaces_strv ( const char * s
) {
2814 unsigned i
= 0 , n
= 8 ;
2815 const char * state
= NULL
;
2817 t
= pa_xnew ( char *, n
);
2818 while (( e
= pa_split_spaces ( s
, & state
))) {
2823 t
= pa_xrenew ( char *, t
, n
);
2836 char * pa_maybe_prefix_path ( const char * path
, const char * prefix
) {
2839 if ( pa_is_path_absolute ( path
))
2840 return pa_xstrdup ( path
);
2842 return pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , prefix
, path
);
2845 size_t pa_pipe_buf ( int fd
) {
2850 if (( n
= fpathconf ( fd
, _PC_PIPE_BUF
)) >= 0 )
2861 void pa_reset_personality ( void ) {
2864 if ( personality ( PER_LINUX
) < 0 )
2865 pa_log_warn ( "Uh, personality() failed: %s" , pa_cstrerror ( errno
));
2870 #if defined(__linux__) && !defined(__OPTIMIZE__)
2872 pa_bool_t
pa_run_from_build_tree ( void ) {
2874 pa_bool_t b
= FALSE
;
2876 /* We abuse __OPTIMIZE__ as a check whether we are a debug build
2879 if (( rp
= pa_readlink ( "/proc/self/exe" ))) {
2880 b
= pa_startswith ( rp
, PA_BUILDDIR
);
2889 const char * pa_get_temp_dir ( void ) {
2892 if (( t
= getenv ( "TMPDIR" )) &&
2893 pa_is_path_absolute ( t
))
2896 if (( t
= getenv ( "TMP" )) &&
2897 pa_is_path_absolute ( t
))
2900 if (( t
= getenv ( "TEMP" )) &&
2901 pa_is_path_absolute ( t
))
2904 if (( t
= getenv ( "TEMPDIR" )) &&
2905 pa_is_path_absolute ( t
))
2911 int pa_open_cloexec ( const char * fn
, int flags
, mode_t mode
) {
2919 if (( fd
= open ( fn
, flags
| O_CLOEXEC
, mode
)) >= 0 )
2922 if ( errno
!= EINVAL
)
2926 if (( fd
= open ( fn
, flags
, mode
)) < 0 )
2930 /* Some implementations might simply ignore O_CLOEXEC if it is not
2931 * understood, make sure FD_CLOEXEC is enabled anyway */
2933 pa_make_fd_cloexec ( fd
);
2937 int pa_socket_cloexec ( int domain
, int type
, int protocol
) {
2941 if (( fd
= socket ( domain
, type
| SOCK_CLOEXEC
, protocol
)) >= 0 )
2944 if ( errno
!= EINVAL
)
2948 if (( fd
= socket ( domain
, type
, protocol
)) < 0 )
2952 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
2953 * not understood, make sure FD_CLOEXEC is enabled anyway */
2955 pa_make_fd_cloexec ( fd
);
2959 int pa_pipe_cloexec ( int pipefd
[ 2 ]) {
2963 if (( r
= pipe2 ( pipefd
, O_CLOEXEC
)) >= 0 )
2966 if ( errno
!= EINVAL
&& errno
!= ENOSYS
)
2971 if (( r
= pipe ( pipefd
)) < 0 )
2975 pa_make_fd_cloexec ( pipefd
[ 0 ]);
2976 pa_make_fd_cloexec ( pipefd
[ 1 ]);
2981 int pa_accept_cloexec ( int sockfd
, struct sockaddr
* addr
, socklen_t
* addrlen
) {
2985 if (( fd
= accept4 ( sockfd
, addr
, addrlen
, SOCK_CLOEXEC
)) >= 0 )
2988 if ( errno
!= EINVAL
&& errno
!= ENOSYS
)
2993 if (( fd
= accept ( sockfd
, addr
, addrlen
)) < 0 )
2997 pa_make_fd_cloexec ( fd
);
3001 FILE * pa_fopen_cloexec ( const char * path
, const char * mode
) {
3005 m
= pa_sprintf_malloc ( "%se" , mode
);
3008 if (( f
= fopen ( path
, m
))) {
3015 if ( errno
!= EINVAL
)
3018 if (!( f
= fopen ( path
, mode
)))
3022 pa_make_fd_cloexec ( fileno ( f
));
3026 void pa_nullify_stdfds ( void ) {
3029 pa_close ( STDIN_FILENO
);
3030 pa_close ( STDOUT_FILENO
);
3031 pa_close ( STDERR_FILENO
);
3033 pa_assert_se ( open ( "/dev/null" , O_RDONLY
) == STDIN_FILENO
);
3034 pa_assert_se ( open ( "/dev/null" , O_WRONLY
) == STDOUT_FILENO
);
3035 pa_assert_se ( open ( "/dev/null" , O_WRONLY
) == STDERR_FILENO
);
3042 char * pa_read_line_from_file ( const char * fn
) {
3044 char ln
[ 256 ] = "" , * r
;
3046 if (!( f
= pa_fopen_cloexec ( fn
, "r" )))
3049 r
= fgets ( ln
, sizeof ( ln
)- 1 , f
);
3058 return pa_xstrdup ( ln
);
3061 pa_bool_t
pa_running_in_vm ( void ) {
3063 #if defined(__i386__) || defined(__x86_64__)
3065 /* Both CPUID and DMI are x86 specific interfaces... */
3067 uint32_t eax
= 0x40000000 ;
3074 const char * const dmi_vendors
[] = {
3075 "/sys/class/dmi/id/sys_vendor" ,
3076 "/sys/class/dmi/id/board_vendor" ,
3077 "/sys/class/dmi/id/bios_vendor"
3082 for ( i
= 0 ; i
< PA_ELEMENTSOF ( dmi_vendors
); i
++) {
3085 if (( s
= pa_read_line_from_file ( dmi_vendors
[ i
]))) {
3087 if ( pa_startswith ( s
, "QEMU" ) ||
3088 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3089 pa_startswith ( s
, "VMware" ) ||
3090 pa_startswith ( s
, "VMW" ) ||
3091 pa_startswith ( s
, "Microsoft Corporation" ) ||
3092 pa_startswith ( s
, "innotek GmbH" ) ||
3093 pa_startswith ( s
, "Xen" )) {
3105 /* http://lwn.net/Articles/301888/ */
3108 __asm__
__volatile__ (
3109 /* ebx/rbx is being used for PIC! */
3110 " push %%" PA_REG_b
" \n\t "
3112 " mov %%ebx, %1 \n\t "
3113 " pop %%" PA_REG_b
" \n\t "
3115 : "=a" ( eax
), "=r" ( sig
. sig32
[ 0 ]), "=c" ( sig
. sig32
[ 1 ]), "=d" ( sig
. sig32
[ 2 ])
3119 if ( pa_streq ( sig
. text
, "XenVMMXenVMM" ) ||
3120 pa_streq ( sig
. text
, "KVMKVMKVM" ) ||
3121 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3122 pa_streq ( sig
. text
, "VMwareVMware" ) ||
3123 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3124 pa_streq ( sig
. text
, "Microsoft Hv" ))