]>
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>
54 #if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
55 #define SCHED_RESET_ON_FORK 0x40000000
59 #ifdef HAVE_SYS_RESOURCE_H
60 #include <sys/resource.h>
63 #ifdef HAVE_SYS_CAPABILITY_H
64 #include <sys/capability.h>
67 #ifdef HAVE_SYS_MMAN_H
91 #ifdef HAVE_LIBSAMPLERATE
92 #include <samplerate.h>
104 #include <sys/personality.h>
107 #include <pulse/xmalloc.h>
108 #include <pulse/util.h>
109 #include <pulse/utf8.h>
111 #include <pulsecore/core-error.h>
112 #include <pulsecore/socket.h>
113 #include <pulsecore/log.h>
114 #include <pulsecore/macro.h>
115 #include <pulsecore/thread.h>
116 #include <pulsecore/strbuf.h>
117 #include <pulsecore/usergroup.h>
118 #include <pulsecore/strlist.h>
119 #include <pulsecore/cpu-x86.h>
121 #include "core-util.h"
123 /* Not all platforms have this */
125 #define MSG_NOSIGNAL 0
128 #define NEWLINE " \r\n "
129 #define WHITESPACE " \n\r \t "
131 static pa_strlist
* recorded_env
= NULL
;
135 #define PULSE_ROOTENV "PULSE_ROOT"
137 int pa_set_root ( HANDLE handle
) {
138 char library_path
[ MAX_PATH
+ sizeof ( PULSE_ROOTENV
) + 1 ], * sep
;
140 strcpy ( library_path
, PULSE_ROOTENV
"=" );
142 /* FIXME: Needs to set errno */
144 if (! GetModuleFileName ( handle
, library_path
+ sizeof ( PULSE_ROOTENV
), MAX_PATH
))
147 sep
= strrchr ( library_path
, PA_PATH_SEP_CHAR
);
151 if ( _putenv ( library_path
) < 0 )
159 /** Make a file descriptor nonblock. Doesn't do any error checking */
160 void pa_make_fd_nonblock ( int fd
) {
166 pa_assert_se (( v
= fcntl ( fd
, F_GETFL
)) >= 0 );
168 if (!( v
& O_NONBLOCK
))
169 pa_assert_se ( fcntl ( fd
, F_SETFL
, v
| O_NONBLOCK
) >= 0 );
171 #elif defined(OS_IS_WIN32)
173 if ( ioctlsocket ( fd
, FIONBIO
, & arg
) < 0 ) {
174 pa_assert_se ( WSAGetLastError () == WSAENOTSOCK
);
175 pa_log_warn ( "Only sockets can be made non-blocking!" );
178 pa_log_warn ( "Non-blocking I/O not supported.!" );
183 /* Set the FD_CLOEXEC flag for a fd */
184 void pa_make_fd_cloexec ( int fd
) {
190 pa_assert_se (( v
= fcntl ( fd
, F_GETFD
, 0 )) >= 0 );
192 if (!( v
& FD_CLOEXEC
))
193 pa_assert_se ( fcntl ( fd
, F_SETFD
, v
| FD_CLOEXEC
) >= 0 );
198 /** Creates a directory securely */
199 int pa_make_secure_dir ( const char * dir
, mode_t m
, uid_t uid
, gid_t gid
) {
201 int r
, saved_errno
, fd
;
210 u
= umask ((~ m
) & 0777 );
216 if ( r
< 0 && errno
!= EEXIST
)
233 if ( fstat ( fd
, & st
) < 0 ) {
234 pa_assert_se ( pa_close ( fd
) >= 0 );
238 if (! S_ISDIR ( st
. st_mode
)) {
239 pa_assert_se ( pa_close ( fd
) >= 0 );
245 if ( uid
== ( uid_t
)- 1 )
247 if ( gid
== ( gid_t
)- 1 )
249 ( void ) fchown ( fd
, uid
, gid
);
253 ( void ) fchmod ( fd
, m
);
256 pa_assert_se ( pa_close ( fd
) >= 0 );
261 if ( lstat ( dir
, & st
) < 0 )
263 if ( stat ( dir
, & st
) < 0 )
268 if (! S_ISDIR ( st
. st_mode
) ||
269 ( st
. st_uid
!= uid
) ||
270 ( st
. st_gid
!= gid
) ||
271 (( st
. st_mode
& 0777 ) != m
)) {
276 pa_log_warn ( "Secure directory creation not supported on Win32." );
289 /* Return a newly allocated sting containing the parent directory of the specified file */
290 char * pa_parent_dir ( const char * fn
) {
291 char * slash
, * dir
= pa_xstrdup ( fn
);
293 if (( slash
= ( char *) pa_path_get_filename ( dir
)) == dir
) {
303 /* Creates a the parent directory of the specified path securely */
304 int pa_make_secure_parent_dir ( const char * fn
, mode_t m
, uid_t uid
, gid_t gid
) {
308 if (!( dir
= pa_parent_dir ( fn
)))
311 if ( pa_make_secure_dir ( dir
, m
, uid
, gid
) < 0 )
321 /** Platform independent read function. Necessary since not all
322 * systems treat all file descriptors equal. If type is
323 * non-NULL it is used to cache the type of the fd. This is
324 * useful for making sure that only a single syscall is executed per
325 * function call. The variable pointed to should be initialized to 0
327 ssize_t
pa_read ( int fd
, void * buf
, size_t count
, int * type
) {
331 if (! type
|| * type
== 0 ) {
334 if (( r
= recv ( fd
, buf
, count
, 0 )) >= 0 )
337 if ( WSAGetLastError () != WSAENOTSOCK
) {
338 errno
= WSAGetLastError ();
351 if (( r
= read ( fd
, buf
, count
)) < 0 )
359 /** Similar to pa_read(), but handles writes */
360 ssize_t
pa_write ( int fd
, const void * buf
, size_t count
, int * type
) {
362 if (! type
|| * type
== 0 ) {
366 if (( r
= send ( fd
, buf
, count
, MSG_NOSIGNAL
)) < 0 ) {
378 if ( WSAGetLastError () != WSAENOTSOCK
) {
379 errno
= WSAGetLastError ();
383 if ( errno
!= ENOTSOCK
)
394 if (( r
= write ( fd
, buf
, count
)) < 0 )
402 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
403 * unless EOF is reached or an error occurred */
404 ssize_t
pa_loop_read ( int fd
, void * data
, size_t size
, int * type
) {
420 if (( r
= pa_read ( fd
, data
, size
, type
)) < 0 )
427 data
= ( uint8_t *) data
+ r
;
434 /** Similar to pa_loop_read(), but wraps write() */
435 ssize_t
pa_loop_write ( int fd
, const void * data
, size_t size
, int * type
) {
451 if (( r
= pa_write ( fd
, data
, size
, type
)) < 0 )
458 data
= ( const uint8_t *) data
+ r
;
465 /** Platform independent read function. Necessary since not all
466 * systems treat all file descriptors equal. */
467 int pa_close ( int fd
) {
472 if (( ret
= closesocket ( fd
)) == 0 )
475 if ( WSAGetLastError () != WSAENOTSOCK
) {
476 errno
= WSAGetLastError ();
484 if (( r
= close ( fd
)) < 0 )
492 /* Print a warning messages in case that the given signal is not
493 * blocked or trapped */
494 void pa_check_signal_is_blocked ( int sig
) {
495 #ifdef HAVE_SIGACTION
499 /* If POSIX threads are supported use thread-aware
500 * pthread_sigmask() function, to check if the signal is
501 * blocked. Otherwise fall back to sigprocmask() */
504 if ( pthread_sigmask ( SIG_SETMASK
, NULL
, & set
) < 0 ) {
506 if ( sigprocmask ( SIG_SETMASK
, NULL
, & set
) < 0 ) {
507 pa_log ( "sigprocmask(): %s" , pa_cstrerror ( errno
));
514 if ( sigismember (& set
, sig
))
517 /* Check whether the signal is trapped */
519 if ( sigaction ( sig
, NULL
, & sa
) < 0 ) {
520 pa_log ( "sigaction(): %s" , pa_cstrerror ( errno
));
524 if ( sa
. sa_handler
!= SIG_DFL
)
527 pa_log_warn ( "%s is not trapped. This might cause malfunction!" , pa_sig2str ( sig
));
528 #else /* HAVE_SIGACTION */
529 pa_log_warn ( "%s might not be trapped. This might cause malfunction!" , pa_sig2str ( sig
));
533 /* The following function is based on an example from the GNU libc
534 * documentation. This function is similar to GNU's asprintf(). */
535 char * pa_sprintf_malloc ( const char * format
, ...) {
545 c
= pa_xrealloc ( c
, size
);
547 va_start ( ap
, format
);
548 r
= vsnprintf ( c
, size
, format
, ap
);
553 if ( r
> - 1 && ( size_t ) r
< size
)
556 if ( r
> - 1 ) /* glibc 2.1 */
563 /* Same as the previous function, but use a va_list instead of an
565 char * pa_vsprintf_malloc ( const char * format
, va_list ap
) {
575 c
= pa_xrealloc ( c
, size
);
578 r
= vsnprintf ( c
, size
, format
, aq
);
583 if ( r
> - 1 && ( size_t ) r
< size
)
586 if ( r
> - 1 ) /* glibc 2.1 */
593 /* Similar to OpenBSD's strlcpy() function */
594 char * pa_strlcpy ( char * b
, const char * s
, size_t l
) {
612 static int set_scheduler ( int rtprio
) {
613 struct sched_param sp
;
619 dbus_error_init (& error
);
623 sp
. sched_priority
= rtprio
;
625 #ifdef SCHED_RESET_ON_FORK
626 if ( pthread_setschedparam ( pthread_self (), SCHED_RR
| SCHED_RESET_ON_FORK
, & sp
) == 0 ) {
627 pa_log_debug ( "SCHED_RR|SCHED_RESET_ON_FORK worked." );
632 if ( pthread_setschedparam ( pthread_self (), SCHED_RR
, & sp
) == 0 ) {
633 pa_log_debug ( "SCHED_RR worked." );
638 /* Try to talk to RealtimeKit */
640 if (!( bus
= dbus_bus_get ( DBUS_BUS_SYSTEM
, & error
))) {
641 pa_log ( "Failed to connect to system bus: %s \n " , error
. message
);
642 dbus_error_free (& error
);
647 /* We need to disable exit on disconnect because otherwise
648 * dbus_shutdown will kill us. See
649 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
650 dbus_connection_set_exit_on_disconnect ( bus
, FALSE
);
652 r
= rtkit_make_realtime ( bus
, 0 , rtprio
);
653 dbus_connection_unref ( bus
);
656 pa_log_debug ( "RealtimeKit worked." );
668 /* Make the current thread a realtime thread, and acquire the highest
669 * rtprio we can get that is less or equal the specified parameter. If
670 * the thread is already realtime, don't do anything. */
671 int pa_make_realtime ( int rtprio
) {
673 #ifdef _POSIX_PRIORITY_SCHEDULING
676 if ( set_scheduler ( rtprio
) >= 0 ) {
677 pa_log_info ( "Successfully enabled SCHED_RR scheduling for thread, with priority %i." , rtprio
);
681 for ( p
= rtprio
- 1 ; p
>= 1 ; p
--)
682 if ( set_scheduler ( p
) >= 0 ) {
683 pa_log_info ( "Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i." , p
, rtprio
);
687 pa_log_info ( "Failed to acquire real-time scheduling: %s" , pa_cstrerror ( errno
));
696 static int set_nice ( int nice_level
) {
702 dbus_error_init (& error
);
705 if ( setpriority ( PRIO_PROCESS
, 0 , nice_level
) >= 0 ) {
706 pa_log_debug ( "setpriority() worked." );
711 /* Try to talk to RealtimeKit */
713 if (!( bus
= dbus_bus_get ( DBUS_BUS_SYSTEM
, & error
))) {
714 pa_log ( "Failed to connect to system bus: %s \n " , error
. message
);
715 dbus_error_free (& error
);
720 /* We need to disable exit on disconnect because otherwise
721 * dbus_shutdown will kill us. See
722 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
723 dbus_connection_set_exit_on_disconnect ( bus
, FALSE
);
725 r
= rtkit_make_high_priority ( bus
, 0 , nice_level
);
726 dbus_connection_unref ( bus
);
729 pa_log_debug ( "RealtimeKit worked." );
739 /* Raise the priority of the current process as much as possible that
740 * is <= the specified nice level..*/
741 int pa_raise_priority ( int nice_level
) {
743 #ifdef HAVE_SYS_RESOURCE_H
746 if ( set_nice ( nice_level
) >= 0 ) {
747 pa_log_info ( "Successfully gained nice level %i." , nice_level
);
751 for ( n
= nice_level
+ 1 ; n
< 0 ; n
++)
752 if ( set_nice ( n
) >= 0 ) {
753 pa_log_info ( "Successfully acquired nice level %i, which is lower than the requested %i." , n
, nice_level
);
757 pa_log_info ( "Failed to acquire high-priority scheduling: %s" , pa_cstrerror ( errno
));
762 if ( nice_level
< 0 ) {
763 if (! SetPriorityClass ( GetCurrentProcess (), HIGH_PRIORITY_CLASS
)) {
764 pa_log_warn ( "SetPriorityClass() failed: 0x%08X" , GetLastError ());
769 pa_log_info ( "Successfully gained high priority class." );
776 /* Reset the priority to normal, inverting the changes made by
777 * pa_raise_priority() and pa_make_realtime()*/
778 void pa_reset_priority ( void ) {
779 #ifdef HAVE_SYS_RESOURCE_H
780 struct sched_param sp
;
782 setpriority ( PRIO_PROCESS
, 0 , 0 );
785 pthread_setschedparam ( pthread_self (), SCHED_OTHER
, & sp
);
789 SetPriorityClass ( GetCurrentProcess (), NORMAL_PRIORITY_CLASS
);
793 int pa_match ( const char * expr
, const char * v
) {
798 if ( regcomp (& re
, expr
, REG_NOSUB
| REG_EXTENDED
) != 0 ) {
803 if (( k
= regexec (& re
, v
, 0 , NULL
, 0 )) == 0 )
805 else if ( k
== REG_NOMATCH
)
818 /* Try to parse a boolean string value.*/
819 int pa_parse_boolean ( const char * v
) {
823 /* First we check language independant */
824 if (! strcmp ( v
, "1" ) || v
[ 0 ] == 'y' || v
[ 0 ] == 'Y' || v
[ 0 ] == 't' || v
[ 0 ] == 'T' || ! strcasecmp ( v
, "on" ))
826 else if (! strcmp ( v
, "0" ) || v
[ 0 ] == 'n' || v
[ 0 ] == 'N' || v
[ 0 ] == 'f' || v
[ 0 ] == 'F' || ! strcasecmp ( v
, "off" ))
829 /* And then we check language dependant */
830 if (( expr
= nl_langinfo ( YESEXPR
)))
832 if ( pa_match ( expr
, v
) > 0 )
835 if (( expr
= nl_langinfo ( NOEXPR
)))
837 if ( pa_match ( expr
, v
) > 0 )
844 /* Split the specified string wherever one of the strings in delimiter
845 * occurs. Each time it is called returns a newly allocated string
846 * with pa_xmalloc(). The variable state points to, should be
847 * initiallized to NULL before the first call. */
848 char * pa_split ( const char * c
, const char * delimiter
, const char ** state
) {
849 const char * current
= * state
? * state
: c
;
855 l
= strcspn ( current
, delimiter
);
861 return pa_xstrndup ( current
, l
);
864 /* Split a string into words. Otherwise similar to pa_split(). */
865 char * pa_split_spaces ( const char * c
, const char ** state
) {
866 const char * current
= * state
? * state
: c
;
869 if (!* current
|| * c
== 0 )
872 current
+= strspn ( current
, WHITESPACE
);
873 l
= strcspn ( current
, WHITESPACE
);
877 return pa_xstrndup ( current
, l
);
880 PA_STATIC_TLS_DECLARE ( signame
, pa_xfree
);
882 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
883 const char * pa_sig2str ( int sig
) {
896 char buf
[ SIG2STR_MAX
];
898 if ( sig2str ( sig
, buf
) == 0 ) {
899 pa_xfree ( PA_STATIC_TLS_GET ( signame
));
900 t
= pa_sprintf_malloc ( "SIG%s" , buf
);
901 PA_STATIC_TLS_SET ( signame
, t
);
909 case SIGHUP
: return "SIGHUP" ;
911 case SIGINT
: return "SIGINT" ;
913 case SIGQUIT
: return "SIGQUIT" ;
915 case SIGILL
: return "SIGULL" ;
917 case SIGTRAP
: return "SIGTRAP" ;
919 case SIGABRT
: return "SIGABRT" ;
921 case SIGBUS
: return "SIGBUS" ;
923 case SIGFPE
: return "SIGFPE" ;
925 case SIGKILL
: return "SIGKILL" ;
928 case SIGUSR1
: return "SIGUSR1" ;
930 case SIGSEGV
: return "SIGSEGV" ;
932 case SIGUSR2
: return "SIGUSR2" ;
935 case SIGPIPE
: return "SIGPIPE" ;
938 case SIGALRM
: return "SIGALRM" ;
940 case SIGTERM
: return "SIGTERM" ;
942 case SIGSTKFLT
: return "SIGSTKFLT" ;
945 case SIGCHLD
: return "SIGCHLD" ;
948 case SIGCONT
: return "SIGCONT" ;
951 case SIGSTOP
: return "SIGSTOP" ;
954 case SIGTSTP
: return "SIGTSTP" ;
957 case SIGTTIN
: return "SIGTTIN" ;
960 case SIGTTOU
: return "SIGTTOU" ;
963 case SIGURG
: return "SIGURG" ;
966 case SIGXCPU
: return "SIGXCPU" ;
969 case SIGXFSZ
: return "SIGXFSZ" ;
972 case SIGVTALRM
: return "SIGVTALRM" ;
975 case SIGPROF
: return "SIGPROF" ;
978 case SIGWINCH
: return "SIGWINCH" ;
981 case SIGIO
: return "SIGIO" ;
984 case SIGPWR
: return "SIGPWR" ;
987 case SIGSYS
: return "SIGSYS" ;
992 if ( sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
993 pa_xfree ( PA_STATIC_TLS_GET ( signame
));
994 t
= pa_sprintf_malloc ( "SIGRTMIN+%i" , sig
- SIGRTMIN
);
995 PA_STATIC_TLS_SET ( signame
, t
);
1004 pa_xfree ( PA_STATIC_TLS_GET ( signame
));
1005 t
= pa_sprintf_malloc ( "SIG%i" , sig
);
1006 PA_STATIC_TLS_SET ( signame
, t
);
1012 /* Check whether the specified GID and the group name match */
1013 static int is_group ( gid_t gid
, const char * name
) {
1014 struct group
* group
= NULL
;
1018 if (!( group
= pa_getgrgid_malloc ( gid
)))
1023 pa_log ( "pa_getgrgid_malloc(%u): %s" , gid
, pa_cstrerror ( errno
));
1028 r
= strcmp ( name
, group
-> gr_name
) == 0 ;
1031 pa_getgrgid_free ( group
);
1036 /* Check the current user is member of the specified group */
1037 int pa_own_uid_in_group ( const char * name
, gid_t
* gid
) {
1038 GETGROUPS_T
* gids
, tgid
;
1039 long n
= sysconf ( _SC_NGROUPS_MAX
);
1044 gids
= pa_xmalloc ( sizeof ( GETGROUPS_T
) * ( size_t ) n
);
1046 if (( n
= getgroups (( int ) n
, gids
)) < 0 ) {
1047 pa_log ( "getgroups(): %s" , pa_cstrerror ( errno
));
1051 for ( i
= 0 ; i
< n
; i
++) {
1053 if (( k
= is_group ( gids
[ i
], name
)) < 0 )
1062 if (( k
= is_group ( tgid
= getgid (), name
)) < 0 )
1078 /* Check whether the specifc user id is a member of the specified group */
1079 int pa_uid_in_group ( uid_t uid
, const char * name
) {
1080 struct group
* group
= NULL
;
1085 if (!( group
= pa_getgrnam_malloc ( name
)))
1093 for ( i
= group
-> gr_mem
; * i
; i
++) {
1094 struct passwd
* pw
= NULL
;
1097 if (!( pw
= pa_getpwnam_malloc (* i
)))
1100 if ( pw
-> pw_uid
== uid
)
1103 pa_getpwnam_free ( pw
);
1110 pa_getgrnam_free ( group
);
1115 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
1116 gid_t
pa_get_gid_of_group ( const char * name
) {
1117 gid_t ret
= ( gid_t
) - 1 ;
1118 struct group
* gr
= NULL
;
1121 if (!( gr
= pa_getgrnam_malloc ( name
)))
1131 pa_getgrnam_free ( gr
);
1135 int pa_check_in_group ( gid_t g
) {
1136 gid_t gids
[ NGROUPS_MAX
];
1139 if (( r
= getgroups ( NGROUPS_MAX
, gids
)) < 0 )
1149 #else /* HAVE_GRP_H */
1151 int pa_own_uid_in_group ( const char * name
, gid_t
* gid
) {
1157 int pa_uid_in_group ( uid_t uid
, const char * name
) {
1162 gid_t
pa_get_gid_of_group ( const char * name
) {
1167 int pa_check_in_group ( gid_t g
) {
1174 /* Lock or unlock a file entirely.
1175 (advisory on UNIX, mandatory on Windows) */
1176 int pa_lock_fd ( int fd
, int b
) {
1178 struct flock f_lock
;
1180 /* Try a R/W lock first */
1182 f_lock
. l_type
= ( short ) ( b
? F_WRLCK
: F_UNLCK
);
1183 f_lock
. l_whence
= SEEK_SET
;
1187 if ( fcntl ( fd
, F_SETLKW
, & f_lock
) >= 0 )
1190 /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
1191 if ( b
&& errno
== EBADF
) {
1192 f_lock
. l_type
= F_RDLCK
;
1193 if ( fcntl ( fd
, F_SETLKW
, & f_lock
) >= 0 )
1197 pa_log ( "%slock: %s" , ! b
? "un" : "" , pa_cstrerror ( errno
));
1201 HANDLE h
= ( HANDLE
) _get_osfhandle ( fd
);
1203 if ( b
&& LockFile ( h
, 0 , 0 , 0xFFFFFFFF , 0xFFFFFFFF ))
1205 if (! b
&& UnlockFile ( h
, 0 , 0 , 0xFFFFFFFF , 0xFFFFFFFF ))
1208 pa_log ( "%slock failed: 0x%08X" , ! b
? "un" : "" , GetLastError ());
1210 /* FIXME: Needs to set errno! */
1216 /* Remove trailing newlines from a string */
1217 char * pa_strip_nl ( char * s
) {
1220 s
[ strcspn ( s
, NEWLINE
)] = 0 ;
1224 char * pa_strip ( char * s
) {
1227 /* Drops trailing whitespace. Modifies the string in
1228 * place. Returns pointer to first non-space character */
1230 s
+= strspn ( s
, WHITESPACE
);
1232 for ( e
= s
; * e
; e
++)
1233 if (! strchr ( WHITESPACE
, * e
))
1244 /* Create a temporary lock file and lock it. */
1245 int pa_lock_lockfile ( const char * fn
) {
1252 if (( fd
= pa_open_cloexec ( fn
, O_CREAT
| O_RDWR
1256 , S_IRUSR
| S_IWUSR
)) < 0 ) {
1257 pa_log_warn ( "Failed to create lock file '%s': %s" , fn
, pa_cstrerror ( errno
));
1261 if ( pa_lock_fd ( fd
, 1 ) < 0 ) {
1262 pa_log_warn ( "Failed to lock file '%s'." , fn
);
1266 if ( fstat ( fd
, & st
) < 0 ) {
1267 pa_log_warn ( "Failed to fstat() file '%s': %s" , fn
, pa_cstrerror ( errno
));
1271 /* Check whether the file has been removed meanwhile. When yes,
1272 * restart this loop, otherwise, we're done */
1273 if ( st
. st_nlink
>= 1 )
1276 if ( pa_lock_fd ( fd
, 0 ) < 0 ) {
1277 pa_log_warn ( "Failed to unlock file '%s'." , fn
);
1281 if ( pa_close ( fd
) < 0 ) {
1282 pa_log_warn ( "Failed to close file '%s': %s" , fn
, pa_cstrerror ( errno
));
1293 int saved_errno
= errno
;
1295 errno
= saved_errno
;
1301 /* Unlock a temporary lcok file */
1302 int pa_unlock_lockfile ( const char * fn
, int fd
) {
1307 if ( unlink ( fn
) < 0 ) {
1308 pa_log_warn ( "Unable to remove lock file '%s': %s" , fn
, pa_cstrerror ( errno
));
1313 if ( pa_lock_fd ( fd
, 0 ) < 0 ) {
1314 pa_log_warn ( "Failed to unlock file '%s'." , fn
);
1318 if ( pa_close ( fd
) < 0 ) {
1319 pa_log_warn ( "Failed to close '%s': %s" , fn
, pa_cstrerror ( errno
));
1326 static char * get_pulse_home ( void ) {
1331 if (!( h
= pa_get_home_dir_malloc ())) {
1332 pa_log_error ( "Failed to get home directory." );
1336 if ( stat ( h
, & st
) < 0 ) {
1337 pa_log_error ( "Failed to stat home directory %s: %s" , h
, pa_cstrerror ( errno
));
1341 if ( st
. st_uid
!= getuid ()) {
1342 pa_log_error ( "Home directory %s not ours." , h
);
1347 ret
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
".pulse" , h
);
1355 char * pa_get_state_dir ( void ) {
1358 /* The state directory shall contain dynamic data that should be
1359 * kept across reboots, and is private to this user */
1361 if (!( d
= pa_xstrdup ( getenv ( "PULSE_STATE_PATH" ))))
1362 if (!( d
= get_pulse_home ()))
1365 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1366 * dir then this will break. */
1368 if ( pa_make_secure_dir ( d
, 0700U , ( uid_t
) - 1 , ( gid_t
) - 1 ) < 0 ) {
1369 pa_log_error ( "Failed to create secure directory: %s" , pa_cstrerror ( errno
));
1377 char * pa_get_home_dir_malloc ( void ) {
1379 size_t allocated
= 128 ;
1382 homedir
= pa_xmalloc ( allocated
);
1384 if (! pa_get_home_dir ( homedir
, allocated
)) {
1389 if ( strlen ( homedir
) < allocated
- 1 )
1399 char * pa_get_binary_name_malloc ( void ) {
1401 size_t allocated
= 128 ;
1404 t
= pa_xmalloc ( allocated
);
1406 if (! pa_get_binary_name ( t
, allocated
)) {
1411 if ( strlen ( t
) < allocated
- 1 )
1421 static char * make_random_dir ( mode_t m
) {
1422 static const char table
[] =
1423 "abcdefghijklmnopqrstuvwxyz"
1424 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1430 fn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"pulse-XXXXXXXXXXXX" , pa_get_temp_dir ());
1431 pathlen
= strlen ( fn
);
1439 for ( i
= pathlen
- 12 ; i
< pathlen
; i
++)
1440 fn
[ i
] = table
[ rand () % ( sizeof ( table
)- 1 )];
1442 u
= umask ((~ m
) & 0777 );
1445 saved_errno
= errno
;
1447 errno
= saved_errno
;
1452 if ( errno
!= EEXIST
) {
1453 pa_log_error ( "Failed to create random directory %s: %s" , fn
, pa_cstrerror ( errno
));
1460 static int make_random_dir_and_link ( mode_t m
, const char * k
) {
1463 if (!( p
= make_random_dir ( m
)))
1466 if ( symlink ( p
, k
) < 0 ) {
1467 int saved_errno
= errno
;
1469 if ( errno
!= EEXIST
)
1470 pa_log_error ( "Failed to symlink %s to %s: %s" , k
, p
, pa_cstrerror ( errno
));
1475 errno
= saved_errno
;
1483 char * pa_get_runtime_dir ( void ) {
1484 char * d
, * k
= NULL
, * p
= NULL
, * t
= NULL
, * mid
;
1488 /* The runtime directory shall contain dynamic data that needs NOT
1489 * to be kept accross reboots and is usuallly private to the user,
1490 * except in system mode, where it might be accessible by other
1491 * users, too. Since we need POSIX locking and UNIX sockets in
1492 * this directory, we link it to a random subdir in /tmp, if it
1493 * was not explicitly configured. */
1495 m
= pa_in_system_mode () ? 0755U : 0700U ;
1497 if (( d
= getenv ( "PULSE_RUNTIME_PATH" ))) {
1499 if ( pa_make_secure_dir ( d
, m
, ( uid_t
) - 1 , ( gid_t
) - 1 ) < 0 ) {
1500 pa_log_error ( "Failed to create secure directory: %s" , pa_cstrerror ( errno
));
1504 return pa_xstrdup ( d
);
1507 if (!( d
= get_pulse_home ()))
1510 if ( pa_make_secure_dir ( d
, m
, ( uid_t
) - 1 , ( gid_t
) - 1 ) < 0 ) {
1511 pa_log_error ( "Failed to create secure directory: %s" , pa_cstrerror ( errno
));
1516 if (!( mid
= pa_machine_id ())) {
1521 k
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s-runtime" , d
, mid
);
1526 /* OK, first let's check if the "runtime" symlink is already
1529 if (!( p
= pa_readlink ( k
))) {
1531 if ( errno
!= ENOENT
) {
1532 pa_log_error ( "Failed to stat runtime directory %s: %s" , k
, pa_cstrerror ( errno
));
1536 /* Hmm, so the runtime directory didn't exist yet, so let's
1537 * create one in /tmp and symlink that to it */
1539 if ( make_random_dir_and_link ( 0700 , k
) < 0 ) {
1541 /* Mhmm, maybe another process was quicker than us,
1542 * let's check if that was valid */
1543 if ( errno
== EEXIST
)
1552 /* Make sure that this actually makes sense */
1553 if (! pa_is_path_absolute ( p
)) {
1554 pa_log_error ( "Path %s in link %s is not absolute." , p
, k
);
1559 /* Hmm, so this symlink is still around, make sure nobody fools
1562 if ( lstat ( p
, & st
) < 0 ) {
1564 if ( errno
!= ENOENT
) {
1565 pa_log_error ( "Failed to stat runtime directory %s: %s" , p
, pa_cstrerror ( errno
));
1571 if ( S_ISDIR ( st
. st_mode
) &&
1572 ( st
. st_uid
== getuid ()) &&
1573 (( st
. st_mode
& 0777 ) == 0700 )) {
1579 pa_log_info ( "Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory." );
1585 /* Hmm, so the link points to some nonexisting or invalid
1586 * dir. Let's replace it by a new link. We first create a
1587 * temporary link and then rename that to allow concurrent
1588 * execution of this function. */
1590 t
= pa_sprintf_malloc ( "%s.tmp" , k
);
1592 if ( make_random_dir_and_link ( 0700 , t
) < 0 ) {
1594 if ( errno
!= EEXIST
) {
1595 pa_log_error ( "Failed to symlink %s: %s" , t
, pa_cstrerror ( errno
));
1602 /* Hmm, someone lese was quicker then us. Let's give
1603 * him some time to finish, and retry. */
1608 /* OK, we succeeded in creating the temporary symlink, so
1609 * let's rename it */
1610 if ( rename ( t
, k
) < 0 ) {
1611 pa_log_error ( "Failed to rename %s to %s: %s" , t
, k
, pa_cstrerror ( errno
));
1627 /* Try to open a configuration file. If "env" is specified, open the
1628 * value of the specified environment variable. Otherwise look for a
1629 * file "local" in the home directory or a file "global" in global
1630 * file system. If "result" is non-NULL, a pointer to a newly
1631 * allocated buffer containing the used configuration file is
1633 FILE * pa_open_config_file ( const char * global
, const char * local
, const char * env
, char ** result
) {
1638 if (! getenv ( PULSE_ROOTENV
))
1642 if ( env
&& ( fn
= getenv ( env
))) {
1646 if (! ExpandEnvironmentStrings ( fn
, buf
, PATH_MAX
))
1647 /* FIXME: Needs to set errno! */
1652 if (( f
= pa_fopen_cloexec ( fn
, "r" ))) {
1654 * result
= pa_xstrdup ( fn
);
1659 pa_log_warn ( "Failed to open configuration file '%s': %s" , fn
, pa_cstrerror ( errno
));
1669 if (( e
= getenv ( "PULSE_CONFIG_PATH" )))
1670 fn
= lfn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , e
, local
);
1671 else if (( h
= pa_get_home_dir_malloc ())) {
1672 fn
= lfn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s" , h
, local
);
1678 if (! ExpandEnvironmentStrings ( lfn
, buf
, PATH_MAX
)) {
1679 /* FIXME: Needs to set errno! */
1686 if (( f
= pa_fopen_cloexec ( fn
, "r" ))) {
1688 * result
= pa_xstrdup ( fn
);
1694 if ( errno
!= ENOENT
) {
1695 pa_log_warn ( "Failed to open configuration file '%s': %s" , fn
, pa_cstrerror ( errno
));
1707 if (! ExpandEnvironmentStrings ( global
, buf
, PATH_MAX
))
1708 /* FIXME: Needs to set errno! */
1713 if (( f
= pa_fopen_cloexec ( global
, "r" ))) {
1716 * result
= pa_xstrdup ( global
);
1726 char * pa_find_config_file ( const char * global
, const char * local
, const char * env
) {
1731 if (! getenv ( PULSE_ROOTENV
))
1735 if ( env
&& ( fn
= getenv ( env
))) {
1738 if (! ExpandEnvironmentStrings ( fn
, buf
, PATH_MAX
))
1739 /* FIXME: Needs to set errno! */
1744 if ( access ( fn
, R_OK
) == 0 )
1745 return pa_xstrdup ( fn
);
1747 pa_log_warn ( "Failed to access configuration file '%s': %s" , fn
, pa_cstrerror ( errno
));
1756 if (( e
= getenv ( "PULSE_CONFIG_PATH" )))
1757 fn
= lfn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , e
, local
);
1758 else if (( h
= pa_get_home_dir_malloc ())) {
1759 fn
= lfn
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s" , h
, local
);
1765 if (! ExpandEnvironmentStrings ( lfn
, buf
, PATH_MAX
)) {
1766 /* FIXME: Needs to set errno! */
1773 if ( access ( fn
, R_OK
) == 0 ) {
1774 char * r
= pa_xstrdup ( fn
);
1779 if ( errno
!= ENOENT
) {
1780 pa_log_warn ( "Failed to access configuration file '%s': %s" , fn
, pa_cstrerror ( errno
));
1790 if (! ExpandEnvironmentStrings ( global
, buf
, PATH_MAX
))
1791 /* FIXME: Needs to set errno! */
1796 if ( access ( global
, R_OK
) == 0 )
1797 return pa_xstrdup ( global
);
1805 /* Format the specified data as a hexademical string */
1806 char * pa_hexstr ( const uint8_t * d
, size_t dlength
, char * s
, size_t slength
) {
1807 size_t i
= 0 , j
= 0 ;
1808 const char hex
[] = "0123456789abcdef" ;
1812 pa_assert ( slength
> 0 );
1814 while ( i
< dlength
&& j
+ 3 <= slength
) {
1815 s
[ j
++] = hex
[* d
>> 4 ];
1816 s
[ j
++] = hex
[* d
& 0xF ];
1822 s
[ j
< slength
? j
: slength
] = 0 ;
1826 /* Convert a hexadecimal digit to a number or -1 if invalid */
1827 static int hexc ( char c
) {
1828 if ( c
>= '0' && c
<= '9' )
1831 if ( c
>= 'A' && c
<= 'F' )
1832 return c
- 'A' + 10 ;
1834 if ( c
>= 'a' && c
<= 'f' )
1835 return c
- 'a' + 10 ;
1841 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1842 size_t pa_parsehex ( const char * p
, uint8_t * d
, size_t dlength
) {
1848 while ( j
< dlength
&& * p
) {
1851 if (( b
= hexc (*( p
++))) < 0 )
1854 d
[ j
] = ( uint8_t ) ( b
<< 4 );
1859 if (( b
= hexc (*( p
++))) < 0 )
1862 d
[ j
] |= ( uint8_t ) b
;
1869 /* Returns nonzero when *s starts with *pfx */
1870 pa_bool_t
pa_startswith ( const char * s
, const char * pfx
) {
1878 return strlen ( s
) >= l
&& strncmp ( s
, pfx
, l
) == 0 ;
1881 /* Returns nonzero when *s ends with *sfx */
1882 pa_bool_t
pa_endswith ( const char * s
, const char * sfx
) {
1891 return l1
>= l2
&& strcmp ( s
+ l1
- l2
, sfx
) == 0 ;
1894 pa_bool_t
pa_is_path_absolute ( const char * fn
) {
1900 return strlen ( fn
) >= 3 && isalpha ( fn
[ 0 ]) && fn
[ 1 ] == ':' && fn
[ 2 ] == ' \\ ' ;
1904 char * pa_make_path_absolute ( const char * p
) {
1910 if ( pa_is_path_absolute ( p
))
1911 return pa_xstrdup ( p
);
1913 if (!( cwd
= pa_getcwd ()))
1914 return pa_xstrdup ( p
);
1916 r
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , cwd
, p
);
1921 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
1922 * if fn is non-null and starts with / return fn
1923 * otherwise append fn to the run time path and return it */
1924 static char * get_path ( const char * fn
, pa_bool_t prependmid
, pa_bool_t rt
) {
1927 rtp
= rt
? pa_get_runtime_dir () : pa_get_state_dir ();
1932 if ( pa_is_path_absolute ( fn
))
1933 return pa_xstrdup ( fn
);
1941 if (!( mid
= pa_machine_id ())) {
1946 r
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s-%s" , rtp
, mid
, fn
);
1949 r
= pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , rtp
, fn
);
1957 char * pa_runtime_path ( const char * fn
) {
1958 return get_path ( fn
, FALSE
, TRUE
);
1961 char * pa_state_path ( const char * fn
, pa_bool_t appendmid
) {
1962 return get_path ( fn
, appendmid
, FALSE
);
1965 /* Convert the string s to a signed integer in *ret_i */
1966 int pa_atoi ( const char * s
, int32_t * ret_i
) {
1974 l
= strtol ( s
, & x
, 0 );
1976 if (! x
|| * x
|| errno
) {
1982 if (( int32_t ) l
!= l
) {
1987 * ret_i
= ( int32_t ) l
;
1992 /* Convert the string s to an unsigned integer in *ret_u */
1993 int pa_atou ( const char * s
, uint32_t * ret_u
) {
2001 l
= strtoul ( s
, & x
, 0 );
2003 if (! x
|| * x
|| errno
) {
2009 if (( uint32_t ) l
!= l
) {
2014 * ret_u
= ( uint32_t ) l
;
2019 #ifdef HAVE_STRTOF_L
2020 static locale_t c_locale
= NULL
;
2022 static void c_locale_destroy ( void ) {
2023 freelocale ( c_locale
);
2027 int pa_atod ( const char * s
, double * ret_d
) {
2034 /* This should be locale independent */
2036 #ifdef HAVE_STRTOF_L
2040 if (( c_locale
= newlocale ( LC_ALL_MASK
, "C" , NULL
)))
2041 atexit ( c_locale_destroy
);
2047 f
= strtod_l ( s
, & x
, c_locale
);
2055 if (! x
|| * x
|| errno
) {
2066 /* Same as snprintf, but guarantees NUL-termination on every platform */
2067 size_t pa_snprintf ( char * str
, size_t size
, const char * format
, ...) {
2072 pa_assert ( size
> 0 );
2075 va_start ( ap
, format
);
2076 ret
= pa_vsnprintf ( str
, size
, format
, ap
);
2082 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2083 size_t pa_vsnprintf ( char * str
, size_t size
, const char * format
, va_list ap
) {
2087 pa_assert ( size
> 0 );
2090 ret
= vsnprintf ( str
, size
, format
, ap
);
2097 if (( size_t ) ret
> size
- 1 )
2100 return ( size_t ) ret
;
2103 /* Truncate the specified string, but guarantee that the string
2104 * returned still validates as UTF8 */
2105 char * pa_truncate_utf8 ( char * c
, size_t l
) {
2107 pa_assert ( pa_utf8_valid ( c
));
2114 while ( l
> 0 && ! pa_utf8_valid ( c
))
2120 char * pa_getcwd ( void ) {
2124 char * p
= pa_xmalloc ( l
);
2128 if ( errno
!= ERANGE
)
2136 void * pa_will_need ( const void * p
, size_t l
) {
2137 #ifdef RLIMIT_MEMLOCK
2148 a
= PA_PAGE_ALIGN_PTR ( p
);
2149 size
= ( size_t ) (( const uint8_t *) p
+ l
- ( const uint8_t *) a
);
2151 #ifdef HAVE_POSIX_MADVISE
2152 if (( r
= posix_madvise (( void *) a
, size
, POSIX_MADV_WILLNEED
)) == 0 ) {
2153 pa_log_debug ( "posix_madvise() worked fine!" );
2158 /* Most likely the memory was not mmap()ed from a file and thus
2159 * madvise() didn't work, so let's misuse mlock() do page this
2160 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2161 * inviting, the man page of mlock() tells us: "All pages that
2162 * contain a part of the specified address range are guaranteed to
2163 * be resident in RAM when the call returns successfully." */
2165 #ifdef RLIMIT_MEMLOCK
2166 pa_assert_se ( getrlimit ( RLIMIT_MEMLOCK
, & rlim
) == 0 );
2168 if ( rlim
. rlim_cur
< PA_PAGE_SIZE
) {
2169 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
));
2174 bs
= PA_PAGE_ALIGN (( size_t ) rlim
. rlim_cur
);
2176 bs
= PA_PAGE_SIZE
* 4 ;
2179 pa_log_debug ( "posix_madvise() failed (or doesn't exist), trying mlock(): %s" , pa_cstrerror ( r
));
2182 while ( size
> 0 && bs
> 0 ) {
2187 if ( mlock ( a
, bs
) < 0 ) {
2188 bs
= PA_PAGE_ALIGN ( bs
/ 2 );
2192 pa_assert_se ( munlock ( a
, bs
) == 0 );
2194 a
= ( const uint8_t *) a
+ bs
;
2200 pa_log_debug ( "mlock() failed too (or doesn't exist), giving up: %s" , pa_cstrerror ( errno
));
2202 pa_log_debug ( "mlock() worked fine!" );
2207 void pa_close_pipe ( int fds
[ 2 ]) {
2211 pa_assert_se ( pa_close ( fds
[ 0 ]) == 0 );
2214 pa_assert_se ( pa_close ( fds
[ 1 ]) == 0 );
2216 fds
[ 0 ] = fds
[ 1 ] = - 1 ;
2219 char * pa_readlink ( const char * p
) {
2228 if (( n
= readlink ( p
, c
, l
- 1 )) < 0 ) {
2233 if (( size_t ) n
< l
- 1 ) {
2243 int pa_close_all ( int except_fd
, ...) {
2248 va_start ( ap
, except_fd
);
2251 for ( n
= 1 ; va_arg ( ap
, int ) >= 0 ; n
++)
2256 p
= pa_xnew ( int , n
+ 1 );
2258 va_start ( ap
, except_fd
);
2261 if ( except_fd
>= 0 ) {
2265 while (( fd
= va_arg ( ap
, int )) >= 0 )
2272 r
= pa_close_allv ( p
);
2278 int pa_close_allv ( const int except_fds
[]) {
2286 if (( d
= opendir ( "/proc/self/fd" ))) {
2290 while (( de
= readdir ( d
))) {
2296 if ( de
-> d_name
[ 0 ] == '.' )
2300 l
= strtol ( de
-> d_name
, & e
, 10 );
2301 if ( errno
!= 0 || ! e
|| * e
) {
2309 if (( long ) fd
!= l
) {
2322 for ( i
= 0 ; except_fds
[ i
] >= 0 ; i
++)
2323 if ( except_fds
[ i
] == fd
) {
2331 if ( pa_close ( fd
) < 0 ) {
2332 saved_errno
= errno
;
2334 errno
= saved_errno
;
2346 if ( getrlimit ( RLIMIT_NOFILE
, & rl
) >= 0 )
2347 maxfd
= ( int ) rl
. rlim_max
;
2349 maxfd
= sysconf ( _SC_OPEN_MAX
);
2351 for ( fd
= 3 ; fd
< maxfd
; fd
++) {
2356 for ( i
= 0 ; except_fds
[ i
] >= 0 ; i
++)
2357 if ( except_fds
[ i
] == fd
) {
2365 if ( pa_close ( fd
) < 0 && errno
!= EBADF
)
2372 int pa_unblock_sigs ( int except
, ...) {
2377 va_start ( ap
, except
);
2380 for ( n
= 1 ; va_arg ( ap
, int ) >= 0 ; n
++)
2385 p
= pa_xnew ( int , n
+ 1 );
2387 va_start ( ap
, except
);
2394 while (( sig
= va_arg ( ap
, int )) >= 0 )
2401 r
= pa_unblock_sigsv ( p
);
2407 int pa_unblock_sigsv ( const int except
[]) {
2411 if ( sigemptyset (& ss
) < 0 )
2414 for ( i
= 0 ; except
[ i
] > 0 ; i
++)
2415 if ( sigaddset (& ss
, except
[ i
]) < 0 )
2418 return sigprocmask ( SIG_SETMASK
, & ss
, NULL
);
2421 int pa_reset_sigs ( int except
, ...) {
2426 va_start ( ap
, except
);
2429 for ( n
= 1 ; va_arg ( ap
, int ) >= 0 ; n
++)
2434 p
= pa_xnew ( int , n
+ 1 );
2436 va_start ( ap
, except
);
2443 while (( sig
= va_arg ( ap
, int )) >= 0 )
2450 r
= pa_reset_sigsv ( p
);
2456 int pa_reset_sigsv ( const int except
[]) {
2459 for ( sig
= 1 ; sig
< NSIG
; sig
++) {
2460 pa_bool_t reset
= TRUE
;
2471 for ( i
= 0 ; except
[ i
] > 0 ; i
++) {
2472 if ( sig
== except
[ i
]) {
2481 struct sigaction sa
;
2483 memset (& sa
, 0 , sizeof ( sa
));
2484 sa
. sa_handler
= SIG_DFL
;
2486 /* On Linux the first two RT signals are reserved by
2487 * glibc, and sigaction() will return EINVAL for them. */
2488 if (( sigaction ( sig
, & sa
, NULL
) < 0 ))
2489 if ( errno
!= EINVAL
)
2497 void pa_set_env ( const char * key
, const char * value
) {
2501 /* This is not thread-safe */
2503 setenv ( key
, value
, 1 );
2506 void pa_set_env_and_record ( const char * key
, const char * value
) {
2510 /* This is not thread-safe */
2512 pa_set_env ( key
, value
);
2513 recorded_env
= pa_strlist_prepend ( recorded_env
, key
);
2516 void pa_unset_env_recorded ( void ) {
2518 /* This is not thread-safe */
2523 recorded_env
= pa_strlist_pop ( recorded_env
, & s
);
2533 pa_bool_t
pa_in_system_mode ( void ) {
2536 if (!( e
= getenv ( "PULSE_SYSTEM" )))
2542 char * pa_get_user_name_malloc ( void ) {
2546 #ifdef _SC_LOGIN_NAME_MAX
2547 k
= ( ssize_t
) sysconf ( _SC_LOGIN_NAME_MAX
);
2553 u
= pa_xnew ( char , k
+ 1 );
2555 if (!( pa_get_user_name ( u
, k
))) {
2563 char * pa_get_host_name_malloc ( void ) {
2572 if (! pa_get_host_name ( c
, l
)) {
2574 if ( errno
!= EINVAL
&& errno
!= ENAMETOOLONG
)
2577 } else if ( strlen ( c
) < l
- 1 ) {
2585 u
= pa_utf8_filter ( c
);
2590 /* Hmm, the hostname is as long the space we offered the
2591 * function, we cannot know if it fully fit in, so let's play
2592 * safe and retry. */
2601 char * pa_machine_id ( void ) {
2605 /* The returned value is supposed be some kind of ascii identifier
2606 * that is unique and stable across reboots. */
2608 /* First we try the D-Bus UUID, which is the best option we have,
2609 * since it fits perfectly our needs and is not as volatile as the
2610 * hostname which might be set from dhcp. */
2612 if (( f
= pa_fopen_cloexec ( PA_MACHINE_ID
, "r" ))) {
2613 char ln
[ 34 ] = "" , * r
;
2615 r
= fgets ( ln
, sizeof ( ln
)- 1 , f
);
2621 return pa_utf8_filter ( ln
);
2624 if (( h
= pa_get_host_name_malloc ()))
2627 /* If no hostname was set we use the POSIX hostid. It's usually
2628 * the IPv4 address. Might not be that stable. */
2629 return pa_sprintf_malloc ( "%08lx" , ( unsigned long ) gethostid
);
2632 char * pa_session_id ( void ) {
2635 if (!( e
= getenv ( "XDG_SESSION_COOKIE" )))
2638 return pa_utf8_filter ( e
);
2641 char * pa_uname_string ( void ) {
2644 pa_assert_se ( uname (& u
) >= 0 );
2646 return pa_sprintf_malloc ( "%s %s %s %s" , u
. sysname
, u
. machine
, u
. release
, u
. version
);
2649 #ifdef HAVE_VALGRIND_MEMCHECK_H
2650 pa_bool_t
pa_in_valgrind ( void ) {
2653 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
2654 * here instead of really checking whether we run in valgrind or
2658 b
= getenv ( "VALGRIND" ) ? 2 : 1 ;
2664 unsigned pa_gcd ( unsigned a
, unsigned b
) {
2675 void pa_reduce ( unsigned * num
, unsigned * den
) {
2677 unsigned gcd
= pa_gcd (* num
, * den
);
2685 pa_assert ( pa_gcd (* num
, * den
) == 1 );
2688 unsigned pa_ncpus ( void ) {
2691 #ifdef _SC_NPROCESSORS_CONF
2692 ncpus
= sysconf ( _SC_NPROCESSORS_CONF
);
2697 return ncpus
<= 0 ? 1 : ( unsigned ) ncpus
;
2700 char * pa_replace ( const char * s
, const char * a
, const char * b
) {
2709 sb
= pa_strbuf_new ();
2714 if (!( p
= strstr ( s
, a
)))
2717 pa_strbuf_putsn ( sb
, s
, p
- s
);
2718 pa_strbuf_puts ( sb
, b
);
2722 pa_strbuf_puts ( sb
, s
);
2724 return pa_strbuf_tostring_free ( sb
);
2727 char * pa_escape ( const char * p
, const char * chars
) {
2730 pa_strbuf
* buf
= pa_strbuf_new ();
2732 for ( s
= p
; * s
; ++ s
) {
2734 pa_strbuf_putc ( buf
, ' \\ ' );
2736 for ( c
= chars
; * c
; ++ c
) {
2738 pa_strbuf_putc ( buf
, ' \\ ' );
2743 pa_strbuf_putc ( buf
, * s
);
2746 return pa_strbuf_tostring_free ( buf
);
2749 char * pa_unescape ( char * p
) {
2751 pa_bool_t escaped
= FALSE
;
2753 for ( s
= p
, d
= p
; * s
; s
++) {
2754 if (! escaped
&& * s
== ' \\ ' ) {
2768 char * pa_realpath ( const char * path
) {
2772 /* We want only abolsute paths */
2773 if ( path
[ 0 ] != '/' ) {
2778 #if defined(__GLIBC__) || defined(__APPLE__)
2782 if (!( r
= realpath ( path
, NULL
)))
2785 /* We copy this here in case our pa_xmalloc() is not
2786 * implemented on top of libc malloc() */
2790 #elif defined(PATH_MAX)
2793 path_buf
= pa_xmalloc ( PATH_MAX
);
2795 if (!( t
= realpath ( path
, path_buf
))) {
2801 #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."
2807 void pa_disable_sigpipe ( void ) {
2810 struct sigaction sa
;
2814 if ( sigaction ( SIGPIPE
, NULL
, & sa
) < 0 ) {
2815 pa_log ( "sigaction(): %s" , pa_cstrerror ( errno
));
2819 sa
. sa_handler
= SIG_IGN
;
2821 if ( sigaction ( SIGPIPE
, & sa
, NULL
) < 0 ) {
2822 pa_log ( "sigaction(): %s" , pa_cstrerror ( errno
));
2828 void pa_xfreev ( void ** a
) {
2834 for ( p
= a
; * p
; p
++)
2840 char ** pa_split_spaces_strv ( const char * s
) {
2842 unsigned i
= 0 , n
= 8 ;
2843 const char * state
= NULL
;
2845 t
= pa_xnew ( char *, n
);
2846 while (( e
= pa_split_spaces ( s
, & state
))) {
2851 t
= pa_xrenew ( char *, t
, n
);
2864 char * pa_maybe_prefix_path ( const char * path
, const char * prefix
) {
2867 if ( pa_is_path_absolute ( path
))
2868 return pa_xstrdup ( path
);
2870 return pa_sprintf_malloc ( "%s" PA_PATH_SEP
"%s" , prefix
, path
);
2873 size_t pa_pipe_buf ( int fd
) {
2878 if (( n
= fpathconf ( fd
, _PC_PIPE_BUF
)) >= 0 )
2889 void pa_reset_personality ( void ) {
2892 if ( personality ( PER_LINUX
) < 0 )
2893 pa_log_warn ( "Uh, personality() failed: %s" , pa_cstrerror ( errno
));
2898 #if defined(__linux__) && !defined(__OPTIMIZE__)
2900 pa_bool_t
pa_run_from_build_tree ( void ) {
2902 pa_bool_t b
= FALSE
;
2904 /* We abuse __OPTIMIZE__ as a check whether we are a debug build
2907 if (( rp
= pa_readlink ( "/proc/self/exe" ))) {
2908 b
= pa_startswith ( rp
, PA_BUILDDIR
);
2917 const char * pa_get_temp_dir ( void ) {
2920 if (( t
= getenv ( "TMPDIR" )) &&
2921 pa_is_path_absolute ( t
))
2924 if (( t
= getenv ( "TMP" )) &&
2925 pa_is_path_absolute ( t
))
2928 if (( t
= getenv ( "TEMP" )) &&
2929 pa_is_path_absolute ( t
))
2932 if (( t
= getenv ( "TEMPDIR" )) &&
2933 pa_is_path_absolute ( t
))
2939 int pa_open_cloexec ( const char * fn
, int flags
, mode_t mode
) {
2947 if (( fd
= open ( fn
, flags
| O_CLOEXEC
, mode
)) >= 0 )
2950 if ( errno
!= EINVAL
)
2954 if (( fd
= open ( fn
, flags
, mode
)) < 0 )
2958 /* Some implementations might simply ignore O_CLOEXEC if it is not
2959 * understood, make sure FD_CLOEXEC is enabled anyway */
2961 pa_make_fd_cloexec ( fd
);
2965 int pa_socket_cloexec ( int domain
, int type
, int protocol
) {
2969 if (( fd
= socket ( domain
, type
| SOCK_CLOEXEC
, protocol
)) >= 0 )
2972 if ( errno
!= EINVAL
)
2976 if (( fd
= socket ( domain
, type
, protocol
)) < 0 )
2980 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
2981 * not understood, make sure FD_CLOEXEC is enabled anyway */
2983 pa_make_fd_cloexec ( fd
);
2987 int pa_pipe_cloexec ( int pipefd
[ 2 ]) {
2991 if (( r
= pipe2 ( pipefd
, O_CLOEXEC
)) >= 0 )
2994 if ( errno
!= EINVAL
&& errno
!= ENOSYS
)
2999 if (( r
= pipe ( pipefd
)) < 0 )
3003 pa_make_fd_cloexec ( pipefd
[ 0 ]);
3004 pa_make_fd_cloexec ( pipefd
[ 1 ]);
3009 int pa_accept_cloexec ( int sockfd
, struct sockaddr
* addr
, socklen_t
* addrlen
) {
3013 if (( fd
= accept4 ( sockfd
, addr
, addrlen
, SOCK_CLOEXEC
)) >= 0 )
3016 if ( errno
!= EINVAL
&& errno
!= ENOSYS
)
3021 if (( fd
= accept ( sockfd
, addr
, addrlen
)) < 0 )
3025 pa_make_fd_cloexec ( fd
);
3029 FILE * pa_fopen_cloexec ( const char * path
, const char * mode
) {
3033 m
= pa_sprintf_malloc ( "%se" , mode
);
3036 if (( f
= fopen ( path
, m
))) {
3043 if ( errno
!= EINVAL
)
3046 if (!( f
= fopen ( path
, mode
)))
3050 pa_make_fd_cloexec ( fileno ( f
));
3054 void pa_nullify_stdfds ( void ) {
3057 pa_close ( STDIN_FILENO
);
3058 pa_close ( STDOUT_FILENO
);
3059 pa_close ( STDERR_FILENO
);
3061 pa_assert_se ( open ( "/dev/null" , O_RDONLY
) == STDIN_FILENO
);
3062 pa_assert_se ( open ( "/dev/null" , O_WRONLY
) == STDOUT_FILENO
);
3063 pa_assert_se ( open ( "/dev/null" , O_WRONLY
) == STDERR_FILENO
);
3070 char * pa_read_line_from_file ( const char * fn
) {
3072 char ln
[ 256 ] = "" , * r
;
3074 if (!( f
= pa_fopen_cloexec ( fn
, "r" )))
3077 r
= fgets ( ln
, sizeof ( ln
)- 1 , f
);
3086 return pa_xstrdup ( ln
);
3089 pa_bool_t
pa_running_in_vm ( void ) {
3091 #if defined(__i386__) || defined(__x86_64__)
3093 /* Both CPUID and DMI are x86 specific interfaces... */
3095 uint32_t eax
= 0x40000000 ;
3102 const char * const dmi_vendors
[] = {
3103 "/sys/class/dmi/id/sys_vendor" ,
3104 "/sys/class/dmi/id/board_vendor" ,
3105 "/sys/class/dmi/id/bios_vendor"
3110 for ( i
= 0 ; i
< PA_ELEMENTSOF ( dmi_vendors
); i
++) {
3113 if (( s
= pa_read_line_from_file ( dmi_vendors
[ i
]))) {
3115 if ( pa_startswith ( s
, "QEMU" ) ||
3116 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3117 pa_startswith ( s
, "VMware" ) ||
3118 pa_startswith ( s
, "VMW" ) ||
3119 pa_startswith ( s
, "Microsoft Corporation" ) ||
3120 pa_startswith ( s
, "innotek GmbH" ) ||
3121 pa_startswith ( s
, "Xen" )) {
3133 /* http://lwn.net/Articles/301888/ */
3136 __asm__
__volatile__ (
3137 /* ebx/rbx is being used for PIC! */
3138 " push %%" PA_REG_b
" \n\t "
3140 " mov %%ebx, %1 \n\t "
3141 " pop %%" PA_REG_b
" \n\t "
3143 : "=a" ( eax
), "=r" ( sig
. sig32
[ 0 ]), "=c" ( sig
. sig32
[ 1 ]), "=d" ( sig
. sig32
[ 2 ])
3147 if ( pa_streq ( sig
. text
, "XenVMMXenVMM" ) ||
3148 pa_streq ( sig
. text
, "KVMKVMKVM" ) ||
3149 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3150 pa_streq ( sig
. text
, "VMwareVMware" ) ||
3151 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3152 pa_streq ( sig
. text
, "Microsoft Hv" ))