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
38 #include <sys/types.h>
42 #ifdef HAVE_LANGINFO_H
47 #include <sys/utsname.h>
50 #if defined(HAVE_REGEX_H)
52 #elif defined(HAVE_PCREPOSIX_H)
53 #include <pcreposix.h>
63 #if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
64 #define SCHED_RESET_ON_FORK 0x40000000
68 #ifdef HAVE_SYS_RESOURCE_H
69 #include <sys/resource.h>
72 #ifdef HAVE_SYS_CAPABILITY_H
73 #include <sys/capability.h>
76 #ifdef HAVE_SYS_MMAN_H
104 #ifdef HAVE_LIBSAMPLERATE
105 #include <samplerate.h>
110 #include <mach/mach_init.h>
111 #include <mach/thread_act.h>
112 #include <mach/thread_policy.h>
113 #include <sys/sysctl.h>
120 #if defined(__linux__) && !defined(__ANDROID__)
121 #include <sys/personality.h>
124 #include <pulse/xmalloc.h>
125 #include <pulse/util.h>
126 #include <pulse/utf8.h>
128 #include <pulsecore/core-error.h>
129 #include <pulsecore/socket.h>
130 #include <pulsecore/log.h>
131 #include <pulsecore/macro.h>
132 #include <pulsecore/thread.h>
133 #include <pulsecore/strbuf.h>
134 #include <pulsecore/usergroup.h>
135 #include <pulsecore/strlist.h>
136 #include <pulsecore/cpu-x86.h>
137 #include <pulsecore/pipe.h>
139 #include "core-util.h"
141 /* Not all platforms have this */
143 #define MSG_NOSIGNAL 0
146 #define NEWLINE "\r\n"
147 #define WHITESPACE "\n\r \t"
149 static pa_strlist
*recorded_env
= NULL
;
152 static fd_set nonblocking_fds
;
157 /* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
158 char *pa_win32_get_toplevel(HANDLE handle
) {
159 static char *toplevel
= NULL
;
162 char library_path
[MAX_PATH
];
165 if (!GetModuleFileName(handle
, library_path
, MAX_PATH
))
168 toplevel
= pa_xstrdup(library_path
);
170 p
= strrchr(toplevel
, PA_PATH_SEP_CHAR
);
174 p
= strrchr(toplevel
, PA_PATH_SEP_CHAR
);
175 if (p
&& pa_streq(p
+ 1, "bin"))
184 static void set_nonblock(int fd
, bool nonblock
) {
190 pa_assert_se((v
= fcntl(fd
, F_GETFL
)) >= 0);
195 nv
= v
& ~O_NONBLOCK
;
198 pa_assert_se(fcntl(fd
, F_SETFL
, v
|O_NONBLOCK
) >= 0);
200 #elif defined(OS_IS_WIN32)
208 if (ioctlsocket(fd
, FIONBIO
, &arg
) < 0) {
209 pa_assert_se(WSAGetLastError() == WSAENOTSOCK
);
210 pa_log_warn("Only sockets can be made non-blocking!");
214 /* There is no method to query status, so we remember all fds */
216 FD_SET(fd
, &nonblocking_fds
);
218 FD_CLR(fd
, &nonblocking_fds
);
220 pa_log_warn("Non-blocking I/O not supported.!");
225 /** Make a file descriptor nonblock. Doesn't do any error checking */
226 void pa_make_fd_nonblock(int fd
) {
227 set_nonblock(fd
, true);
230 /** Make a file descriptor blocking. Doesn't do any error checking */
231 void pa_make_fd_block(int fd
) {
232 set_nonblock(fd
, false);
235 /** Query if a file descriptor is non-blocking */
236 bool pa_is_fd_nonblock(int fd
) {
242 pa_assert_se((v
= fcntl(fd
, F_GETFL
)) >= 0);
244 return !!(v
& O_NONBLOCK
);
246 #elif defined(OS_IS_WIN32)
247 return !!FD_ISSET(fd
, &nonblocking_fds
);
254 /* Set the FD_CLOEXEC flag for a fd */
255 void pa_make_fd_cloexec(int fd
) {
261 pa_assert_se((v
= fcntl(fd
, F_GETFD
, 0)) >= 0);
263 if (!(v
& FD_CLOEXEC
))
264 pa_assert_se(fcntl(fd
, F_SETFD
, v
|FD_CLOEXEC
) >= 0);
269 /** Creates a directory securely. Will create parent directories recursively if
270 * required. This will not update permissions on parent directories if they
271 * already exist, however. */
272 int pa_make_secure_dir(const char* dir
, mode_t m
, uid_t uid
, gid_t gid
, bool update_perms
) {
285 u
= umask((~m
) & 0777);
291 if (r
< 0 && errno
== ENOENT
&& retry
) {
292 /* If a parent directory in the path doesn't exist, try to create that
293 * first, then try again. */
294 pa_make_secure_parent_dir(dir
, m
, uid
, gid
, false);
299 if (r
< 0 && errno
!= EEXIST
)
302 #if defined(HAVE_FSTAT) && !defined(OS_IS_WIN32)
318 if (fstat(fd
, &st
) < 0) {
319 pa_assert_se(pa_close(fd
) >= 0);
323 if (!S_ISDIR(st
.st_mode
)) {
324 pa_assert_se(pa_close(fd
) >= 0);
330 pa_assert_se(pa_close(fd
) >= 0);
335 if (uid
== (uid_t
) -1)
337 if (gid
== (gid_t
) -1)
339 if (((st
.st_uid
!= uid
) || (st
.st_gid
!= gid
)) && fchown(fd
, uid
, gid
) < 0) {
340 pa_assert_se(pa_close(fd
) >= 0);
346 if (fchmod(fd
, m
) < 0) {
347 pa_assert_se(pa_close(fd
) >= 0);
352 pa_assert_se(pa_close(fd
) >= 0);
355 pa_log_warn("Secure directory creation not supported on this platform.");
368 /* Return a newly allocated sting containing the parent directory of the specified file */
369 char *pa_parent_dir(const char *fn
) {
370 char *slash
, *dir
= pa_xstrdup(fn
);
372 if ((slash
= (char*) pa_path_get_filename(dir
)) == dir
) {
382 /* Creates a the parent directory of the specified path securely */
383 int pa_make_secure_parent_dir(const char *fn
, mode_t m
, uid_t uid
, gid_t gid
, bool update_perms
) {
387 if (!(dir
= pa_parent_dir(fn
)))
390 if (pa_make_secure_dir(dir
, m
, uid
, gid
, update_perms
) < 0)
400 /** Platform independent read function. Necessary since not all
401 * systems treat all file descriptors equal. If type is
402 * non-NULL it is used to cache the type of the fd. This is
403 * useful for making sure that only a single syscall is executed per
404 * function call. The variable pointed to should be initialized to 0
406 ssize_t
pa_read(int fd
, void *buf
, size_t count
, int *type
) {
410 if (!type
|| *type
== 0) {
413 if ((r
= recv(fd
, buf
, count
, 0)) >= 0)
416 if (WSAGetLastError() != WSAENOTSOCK
) {
417 errno
= WSAGetLastError();
430 if ((r
= read(fd
, buf
, count
)) < 0)
438 /** Similar to pa_read(), but handles writes */
439 ssize_t
pa_write(int fd
, const void *buf
, size_t count
, int *type
) {
441 if (!type
|| *type
== 0) {
445 if ((r
= send(fd
, buf
, count
, MSG_NOSIGNAL
)) < 0) {
457 if (WSAGetLastError() != WSAENOTSOCK
) {
458 errno
= WSAGetLastError();
462 if (errno
!= ENOTSOCK
)
473 if ((r
= write(fd
, buf
, count
)) < 0)
481 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
482 * unless EOF is reached or an error occurred */
483 ssize_t
pa_loop_read(int fd
, void*data
, size_t size
, int *type
) {
499 if ((r
= pa_read(fd
, data
, size
, type
)) < 0)
506 data
= (uint8_t*) data
+ r
;
513 /** Similar to pa_loop_read(), but wraps write() */
514 ssize_t
pa_loop_write(int fd
, const void*data
, size_t size
, int *type
) {
530 if ((r
= pa_write(fd
, data
, size
, type
)) < 0)
537 data
= (const uint8_t*) data
+ r
;
544 /** Platform independent close function. Necessary since not all
545 * systems treat all file descriptors equal. */
546 int pa_close(int fd
) {
551 FD_CLR(fd
, &nonblocking_fds
);
553 if ((ret
= closesocket(fd
)) == 0)
556 if (WSAGetLastError() != WSAENOTSOCK
) {
557 errno
= WSAGetLastError();
565 if ((r
= close(fd
)) < 0)
573 /* Print a warning messages in case that the given signal is not
574 * blocked or trapped */
575 void pa_check_signal_is_blocked(int sig
) {
576 #ifdef HAVE_SIGACTION
580 /* If POSIX threads are supported use thread-aware
581 * pthread_sigmask() function, to check if the signal is
582 * blocked. Otherwise fall back to sigprocmask() */
585 if (pthread_sigmask(SIG_SETMASK
, NULL
, &set
) < 0) {
587 if (sigprocmask(SIG_SETMASK
, NULL
, &set
) < 0) {
588 pa_log("sigprocmask(): %s", pa_cstrerror(errno
));
595 if (sigismember(&set
, sig
))
598 /* Check whether the signal is trapped */
600 if (sigaction(sig
, NULL
, &sa
) < 0) {
601 pa_log("sigaction(): %s", pa_cstrerror(errno
));
605 if (sa
.sa_handler
!= SIG_DFL
)
608 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig
));
609 #else /* HAVE_SIGACTION */
610 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig
));
614 /* The following function is based on an example from the GNU libc
615 * documentation. This function is similar to GNU's asprintf(). */
616 char *pa_sprintf_malloc(const char *format
, ...) {
626 c
= pa_xrealloc(c
, size
);
628 va_start(ap
, format
);
629 r
= vsnprintf(c
, size
, format
, ap
);
634 if (r
> -1 && (size_t) r
< size
)
637 if (r
> -1) /* glibc 2.1 */
644 /* Same as the previous function, but use a va_list instead of an
646 char *pa_vsprintf_malloc(const char *format
, va_list ap
) {
656 c
= pa_xrealloc(c
, size
);
659 r
= vsnprintf(c
, size
, format
, aq
);
664 if (r
> -1 && (size_t) r
< size
)
667 if (r
> -1) /* glibc 2.1 */
674 /* Similar to OpenBSD's strlcpy() function */
675 char *pa_strlcpy(char *b
, const char *s
, size_t l
) {
693 #ifdef _POSIX_PRIORITY_SCHEDULING
694 static int set_scheduler(int rtprio
) {
696 struct sched_param sp
;
706 dbus_error_init(&error
);
710 sp
.sched_priority
= rtprio
;
712 #ifdef SCHED_RESET_ON_FORK
713 if (pthread_setschedparam(pthread_self(), SCHED_RR
|SCHED_RESET_ON_FORK
, &sp
) == 0) {
714 pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
719 if (pthread_setschedparam(pthread_self(), SCHED_RR
, &sp
) == 0) {
720 pa_log_debug("SCHED_RR worked.");
723 #endif /* HAVE_SCHED_H */
726 /* Try to talk to RealtimeKit */
728 if (!(bus
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
))) {
729 pa_log("Failed to connect to system bus: %s\n", error
.message
);
730 dbus_error_free(&error
);
735 /* We need to disable exit on disconnect because otherwise
736 * dbus_shutdown will kill us. See
737 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
738 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
740 rttime
= rtkit_get_rttime_usec_max(bus
);
743 r
= getrlimit(RLIMIT_RTTIME
, &rl
);
745 if (r
>= 0 && (long long) rl
.rlim_max
> rttime
) {
746 pa_log_info("Clamping rlimit-rttime to %lld for RealtimeKit\n", rttime
);
747 rl
.rlim_cur
= rl
.rlim_max
= rttime
;
748 r
= setrlimit(RLIMIT_RTTIME
, &rl
);
751 pa_log("setrlimit() failed: %s", pa_cstrerror(errno
));
754 r
= rtkit_make_realtime(bus
, 0, rtprio
);
755 dbus_connection_close(bus
);
756 dbus_connection_unref(bus
);
759 pa_log_debug("RealtimeKit worked.");
765 dbus_connection_close(bus
);
766 dbus_connection_unref(bus
);
778 /* Make the current thread a realtime thread, and acquire the highest
779 * rtprio we can get that is less or equal the specified parameter. If
780 * the thread is already realtime, don't do anything. */
781 int pa_make_realtime(int rtprio
) {
783 #if defined(OS_IS_DARWIN)
784 struct thread_time_constraint_policy ttcpolicy
;
786 size_t size
= sizeof(freq
);
789 ret
= sysctlbyname("hw.cpufrequency", &freq
, &size
, NULL
, 0);
791 pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
795 pa_log_debug("sysctl for hw.cpufrequency: %llu", freq
);
797 /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
798 ttcpolicy
.period
= freq
/ 160;
799 ttcpolicy
.computation
= freq
/ 3300;
800 ttcpolicy
.constraint
= freq
/ 2200;
801 ttcpolicy
.preemptible
= 1;
803 ret
= thread_policy_set(mach_thread_self(),
804 THREAD_TIME_CONSTRAINT_POLICY
,
805 (thread_policy_t
) &ttcpolicy
,
806 THREAD_TIME_CONSTRAINT_POLICY_COUNT
);
808 pa_log_info("Unable to set real-time thread priority (%08x).", ret
);
812 pa_log_info("Successfully acquired real-time thread priority.");
815 #elif defined(_POSIX_PRIORITY_SCHEDULING)
818 if (set_scheduler(rtprio
) >= 0) {
819 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio
);
823 for (p
= rtprio
-1; p
>= 1; p
--)
824 if (set_scheduler(p
) >= 0) {
825 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p
, rtprio
);
828 #elif defined(OS_IS_WIN32)
829 /* Windows only allows realtime scheduling to be set on a per process basis.
830 * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
831 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL
)) {
832 pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
836 pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
841 pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno
));
845 #ifdef HAVE_SYS_RESOURCE_H
846 static int set_nice(int nice_level
) {
852 dbus_error_init(&error
);
855 #ifdef HAVE_SYS_RESOURCE_H
856 if (setpriority(PRIO_PROCESS
, 0, nice_level
) >= 0) {
857 pa_log_debug("setpriority() worked.");
863 /* Try to talk to RealtimeKit */
865 if (!(bus
= dbus_bus_get(DBUS_BUS_SYSTEM
, &error
))) {
866 pa_log("Failed to connect to system bus: %s\n", error
.message
);
867 dbus_error_free(&error
);
872 /* We need to disable exit on disconnect because otherwise
873 * dbus_shutdown will kill us. See
874 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
875 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
877 r
= rtkit_make_high_priority(bus
, 0, nice_level
);
878 dbus_connection_unref(bus
);
881 pa_log_debug("RealtimeKit worked.");
892 /* Raise the priority of the current process as much as possible that
893 * is <= the specified nice level..*/
894 int pa_raise_priority(int nice_level
) {
896 #ifdef HAVE_SYS_RESOURCE_H
899 if (set_nice(nice_level
) >= 0) {
900 pa_log_info("Successfully gained nice level %i.", nice_level
);
904 for (n
= nice_level
+1; n
< 0; n
++)
905 if (set_nice(n
) >= 0) {
906 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n
, nice_level
);
910 pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno
));
915 if (nice_level
< 0) {
916 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS
)) {
917 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
922 pa_log_info("Successfully gained high priority class.");
929 /* Reset the priority to normal, inverting the changes made by
930 * pa_raise_priority() and pa_make_realtime()*/
931 void pa_reset_priority(void) {
932 #ifdef HAVE_SYS_RESOURCE_H
933 struct sched_param sp
;
935 setpriority(PRIO_PROCESS
, 0, 0);
938 pthread_setschedparam(pthread_self(), SCHED_OTHER
, &sp
);
942 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS
);
946 int pa_match(const char *expr
, const char *v
) {
947 #if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
952 if (regcomp(&re
, expr
, REG_NOSUB
|REG_EXTENDED
) != 0) {
957 if ((k
= regexec(&re
, v
, 0, NULL
, 0)) == 0)
959 else if (k
== REG_NOMATCH
)
976 /* Try to parse a boolean string value.*/
977 int pa_parse_boolean(const char *v
) {
980 /* First we check language independent */
981 if (pa_streq(v
, "1") || !strcasecmp(v
, "y") || !strcasecmp(v
, "t")
982 || !strcasecmp(v
, "yes") || !strcasecmp(v
, "true") || !strcasecmp(v
, "on"))
984 else if (pa_streq(v
, "0") || !strcasecmp(v
, "n") || !strcasecmp(v
, "f")
985 || !strcasecmp(v
, "no") || !strcasecmp(v
, "false") || !strcasecmp(v
, "off"))
988 #ifdef HAVE_LANGINFO_H
991 /* And then we check language dependent */
992 if ((expr
= nl_langinfo(YESEXPR
)))
994 if (pa_match(expr
, v
) > 0)
997 if ((expr
= nl_langinfo(NOEXPR
)))
999 if (pa_match(expr
, v
) > 0)
1008 /* Try to parse a volume string to pa_volume_t. The allowed formats are:
1009 * db, % and unsigned integer */
1010 int pa_parse_volume(const char *v
, pa_volume_t
*volume
) {
1024 memcpy(str
, v
, len
+ 1);
1026 if (str
[len
- 1] == '%') {
1027 str
[len
- 1] = '\0';
1028 if (pa_atou(str
, &i
) == 0) {
1029 *volume
= PA_CLAMP_VOLUME((uint64_t) PA_VOLUME_NORM
* i
/ 100);
1032 } else if (len
> 2 && (str
[len
- 1] == 'b' || str
[len
- 1] == 'B') &&
1033 (str
[len
- 2] == 'd' || str
[len
- 2] == 'D')) {
1034 str
[len
- 2] = '\0';
1035 if (pa_atod(str
, &d
) == 0) {
1036 *volume
= pa_sw_volume_from_dB(d
);
1040 if (pa_atou(v
, &i
) == 0) {
1041 *volume
= PA_CLAMP_VOLUME(i
);
1050 /* Split the specified string wherever one of the strings in delimiter
1051 * occurs. Each time it is called returns a newly allocated string
1052 * with pa_xmalloc(). The variable state points to, should be
1053 * initialized to NULL before the first call. */
1054 char *pa_split(const char *c
, const char *delimiter
, const char**state
) {
1055 const char *current
= *state
? *state
: c
;
1061 l
= strcspn(current
, delimiter
);
1067 return pa_xstrndup(current
, l
);
1070 /* Split the specified string wherever one of the strings in delimiter
1071 * occurs. Each time it is called returns a pointer to the substring within the
1072 * string and the length in 'n'. Note that the resultant string cannot be used
1073 * as-is without the length parameter, since it is merely pointing to a point
1074 * within the original string. The variable state points to, should be
1075 * initialized to NULL before the first call. */
1076 const char *pa_split_in_place(const char *c
, const char *delimiter
, int *n
, const char**state
) {
1077 const char *current
= *state
? *state
: c
;
1083 l
= strcspn(current
, delimiter
);
1093 /* Split a string into words. Otherwise similar to pa_split(). */
1094 char *pa_split_spaces(const char *c
, const char **state
) {
1095 const char *current
= *state
? *state
: c
;
1098 if (!*current
|| *c
== 0)
1101 current
+= strspn(current
, WHITESPACE
);
1102 l
= strcspn(current
, WHITESPACE
);
1106 return pa_xstrndup(current
, l
);
1109 PA_STATIC_TLS_DECLARE(signame
, pa_xfree
);
1111 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
1112 const char *pa_sig2str(int sig
) {
1125 char buf
[SIG2STR_MAX
];
1127 if (sig2str(sig
, buf
) == 0) {
1128 pa_xfree(PA_STATIC_TLS_GET(signame
));
1129 t
= pa_sprintf_malloc("SIG%s", buf
);
1130 PA_STATIC_TLS_SET(signame
, t
);
1138 case SIGHUP
: return "SIGHUP";
1140 case SIGINT
: return "SIGINT";
1142 case SIGQUIT
: return "SIGQUIT";
1144 case SIGILL
: return "SIGULL";
1146 case SIGTRAP
: return "SIGTRAP";
1148 case SIGABRT
: return "SIGABRT";
1150 case SIGBUS
: return "SIGBUS";
1152 case SIGFPE
: return "SIGFPE";
1154 case SIGKILL
: return "SIGKILL";
1157 case SIGUSR1
: return "SIGUSR1";
1159 case SIGSEGV
: return "SIGSEGV";
1161 case SIGUSR2
: return "SIGUSR2";
1164 case SIGPIPE
: return "SIGPIPE";
1167 case SIGALRM
: return "SIGALRM";
1169 case SIGTERM
: return "SIGTERM";
1171 case SIGSTKFLT
: return "SIGSTKFLT";
1174 case SIGCHLD
: return "SIGCHLD";
1177 case SIGCONT
: return "SIGCONT";
1180 case SIGSTOP
: return "SIGSTOP";
1183 case SIGTSTP
: return "SIGTSTP";
1186 case SIGTTIN
: return "SIGTTIN";
1189 case SIGTTOU
: return "SIGTTOU";
1192 case SIGURG
: return "SIGURG";
1195 case SIGXCPU
: return "SIGXCPU";
1198 case SIGXFSZ
: return "SIGXFSZ";
1201 case SIGVTALRM
: return "SIGVTALRM";
1204 case SIGPROF
: return "SIGPROF";
1207 case SIGWINCH
: return "SIGWINCH";
1210 case SIGIO
: return "SIGIO";
1213 case SIGPWR
: return "SIGPWR";
1216 case SIGSYS
: return "SIGSYS";
1221 if (sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
1222 pa_xfree(PA_STATIC_TLS_GET(signame
));
1223 t
= pa_sprintf_malloc("SIGRTMIN+%i", sig
- SIGRTMIN
);
1224 PA_STATIC_TLS_SET(signame
, t
);
1233 pa_xfree(PA_STATIC_TLS_GET(signame
));
1234 t
= pa_sprintf_malloc("SIG%i", sig
);
1235 PA_STATIC_TLS_SET(signame
, t
);
1241 /* Check whether the specified GID and the group name match */
1242 static int is_group(gid_t gid
, const char *name
) {
1243 struct group
*group
= NULL
;
1247 if (!(group
= pa_getgrgid_malloc(gid
))) {
1251 pa_log("pa_getgrgid_malloc(%u): %s", gid
, pa_cstrerror(errno
));
1256 r
= pa_streq(name
, group
->gr_name
);
1259 pa_getgrgid_free(group
);
1264 /* Check the current user is member of the specified group */
1265 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1266 GETGROUPS_T
*gids
, tgid
;
1267 long n
= sysconf(_SC_NGROUPS_MAX
);
1272 gids
= pa_xmalloc(sizeof(GETGROUPS_T
) * (size_t) n
);
1274 if ((n
= getgroups((int) n
, gids
)) < 0) {
1275 pa_log("getgroups(): %s", pa_cstrerror(errno
));
1279 for (i
= 0; i
< n
; i
++) {
1281 if ((k
= is_group(gids
[i
], name
)) < 0)
1290 if ((k
= is_group(tgid
= getgid(), name
)) < 0)
1306 /* Check whether the specific user id is a member of the specified group */
1307 int pa_uid_in_group(uid_t uid
, const char *name
) {
1308 struct group
*group
= NULL
;
1313 if (!(group
= pa_getgrnam_malloc(name
))) {
1320 for (i
= group
->gr_mem
; *i
; i
++) {
1321 struct passwd
*pw
= NULL
;
1324 if (!(pw
= pa_getpwnam_malloc(*i
)))
1327 if (pw
->pw_uid
== uid
)
1330 pa_getpwnam_free(pw
);
1337 pa_getgrnam_free(group
);
1342 /* Get the GID of a given group, return (gid_t) -1 on failure. */
1343 gid_t
pa_get_gid_of_group(const char *name
) {
1344 gid_t ret
= (gid_t
) -1;
1345 struct group
*gr
= NULL
;
1348 if (!(gr
= pa_getgrnam_malloc(name
))) {
1357 pa_getgrnam_free(gr
);
1361 int pa_check_in_group(gid_t g
) {
1362 gid_t gids
[NGROUPS_MAX
];
1365 if ((r
= getgroups(NGROUPS_MAX
, gids
)) < 0)
1375 #else /* HAVE_GRP_H */
1377 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1383 int pa_uid_in_group(uid_t uid
, const char *name
) {
1388 gid_t
pa_get_gid_of_group(const char *name
) {
1393 int pa_check_in_group(gid_t g
) {
1400 /* Lock or unlock a file entirely.
1401 (advisory on UNIX, mandatory on Windows) */
1402 int pa_lock_fd(int fd
, int b
) {
1404 struct flock f_lock
;
1406 /* Try a R/W lock first */
1408 f_lock
.l_type
= (short) (b
? F_WRLCK
: F_UNLCK
);
1409 f_lock
.l_whence
= SEEK_SET
;
1413 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1416 /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
1417 if (b
&& errno
== EBADF
) {
1418 f_lock
.l_type
= F_RDLCK
;
1419 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1423 pa_log("%slock: %s", !b
? "un" : "", pa_cstrerror(errno
));
1427 HANDLE h
= (HANDLE
) _get_osfhandle(fd
);
1429 if (b
&& LockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1431 if (!b
&& UnlockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1434 pa_log("%slock failed: 0x%08X", !b
? "un" : "", GetLastError());
1436 /* FIXME: Needs to set errno! */
1442 /* Remove trailing newlines from a string */
1443 char* pa_strip_nl(char *s
) {
1446 s
[strcspn(s
, NEWLINE
)] = 0;
1450 char *pa_strip(char *s
) {
1453 /* Drops trailing whitespace. Modifies the string in
1454 * place. Returns pointer to first non-space character */
1456 s
+= strspn(s
, WHITESPACE
);
1458 for (e
= s
; *e
; e
++)
1459 if (!strchr(WHITESPACE
, *e
))
1470 /* Create a temporary lock file and lock it. */
1471 int pa_lock_lockfile(const char *fn
) {
1478 if ((fd
= pa_open_cloexec(fn
, O_CREAT
|O_RDWR
1482 , S_IRUSR
|S_IWUSR
)) < 0) {
1483 pa_log_warn("Failed to create lock file '%s': %s", fn
, pa_cstrerror(errno
));
1487 if (pa_lock_fd(fd
, 1) < 0) {
1488 pa_log_warn("Failed to lock file '%s'.", fn
);
1492 if (fstat(fd
, &st
) < 0) {
1493 pa_log_warn("Failed to fstat() file '%s': %s", fn
, pa_cstrerror(errno
));
1497 /* Check whether the file has been removed meanwhile. When yes,
1498 * restart this loop, otherwise, we're done */
1499 if (st
.st_nlink
>= 1)
1502 if (pa_lock_fd(fd
, 0) < 0) {
1503 pa_log_warn("Failed to unlock file '%s'.", fn
);
1507 if (pa_close(fd
) < 0) {
1508 pa_log_warn("Failed to close file '%s': %s", fn
, pa_cstrerror(errno
));
1519 int saved_errno
= errno
;
1521 errno
= saved_errno
;
1527 /* Unlock a temporary lock file */
1528 int pa_unlock_lockfile(const char *fn
, int fd
) {
1533 if (unlink(fn
) < 0) {
1534 pa_log_warn("Unable to remove lock file '%s': %s", fn
, pa_cstrerror(errno
));
1539 if (pa_lock_fd(fd
, 0) < 0) {
1540 pa_log_warn("Failed to unlock file '%s'.", fn
);
1544 if (pa_close(fd
) < 0) {
1545 pa_log_warn("Failed to close '%s': %s", fn
, pa_cstrerror(errno
));
1552 static char *get_config_home(char *home
) {
1555 t
= getenv("XDG_CONFIG_HOME");
1557 return pa_xstrdup(t
);
1559 return pa_sprintf_malloc("%s" PA_PATH_SEP
".config", home
);
1562 static int check_ours(const char *p
) {
1567 if (stat(p
, &st
) < 0)
1571 if (st
.st_uid
!= getuid())
1578 static char *get_pulse_home(void) {
1579 char *h
, *ret
, *config_home
;
1582 h
= pa_get_home_dir_malloc();
1584 pa_log_error("Failed to get home directory.");
1589 if (t
< 0 && t
!= -ENOENT
) {
1590 pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t
));
1595 /* If the old directory exists, use it. */
1596 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse", h
);
1597 if (access(ret
, F_OK
) >= 0) {
1603 /* Otherwise go for the XDG compliant directory. */
1604 config_home
= get_config_home(h
);
1606 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", config_home
);
1612 char *pa_get_state_dir(void) {
1615 /* The state directory shall contain dynamic data that should be
1616 * kept across reboots, and is private to this user */
1618 if (!(d
= pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1619 if (!(d
= get_pulse_home()))
1622 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1623 * dir then this will break. */
1625 if (pa_make_secure_dir(d
, 0700U, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1626 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1634 char *pa_get_home_dir_malloc(void) {
1636 size_t allocated
= 128;
1639 homedir
= pa_xmalloc(allocated
);
1641 if (!pa_get_home_dir(homedir
, allocated
)) {
1646 if (strlen(homedir
) < allocated
- 1)
1656 char *pa_get_binary_name_malloc(void) {
1658 size_t allocated
= 128;
1661 t
= pa_xmalloc(allocated
);
1663 if (!pa_get_binary_name(t
, allocated
)) {
1668 if (strlen(t
) < allocated
- 1)
1678 static char* make_random_dir(mode_t m
) {
1679 static const char table
[] =
1680 "abcdefghijklmnopqrstuvwxyz"
1681 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1687 fn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1688 pathlen
= strlen(fn
);
1696 for (i
= pathlen
- 12; i
< pathlen
; i
++)
1697 fn
[i
] = table
[rand() % (sizeof(table
)-1)];
1699 u
= umask((~m
) & 0777);
1706 saved_errno
= errno
;
1708 errno
= saved_errno
;
1713 if (errno
!= EEXIST
) {
1714 pa_log_error("Failed to create random directory %s: %s", fn
, pa_cstrerror(errno
));
1721 static int make_random_dir_and_link(mode_t m
, const char *k
) {
1724 if (!(p
= make_random_dir(m
)))
1728 if (symlink(p
, k
) < 0) {
1729 int saved_errno
= errno
;
1731 if (errno
!= EEXIST
)
1732 pa_log_error("Failed to symlink %s to %s: %s", k
, p
, pa_cstrerror(errno
));
1737 errno
= saved_errno
;
1749 char *pa_get_runtime_dir(void) {
1750 char *d
, *k
= NULL
, *p
= NULL
, *t
= NULL
, *mid
;
1753 /* The runtime directory shall contain dynamic data that needs NOT
1754 * to be kept across reboots and is usually private to the user,
1755 * except in system mode, where it might be accessible by other
1756 * users, too. Since we need POSIX locking and UNIX sockets in
1757 * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
1758 * set create a directory in $HOME and link it to a random subdir
1759 * in /tmp, if it was not explicitly configured. */
1761 m
= pa_in_system_mode() ? 0755U : 0700U;
1763 /* Use the explicitly configured value if it is set */
1764 d
= getenv("PULSE_RUNTIME_PATH");
1767 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1768 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1772 return pa_xstrdup(d
);
1775 /* Use the XDG standard for the runtime directory. */
1776 d
= getenv("XDG_RUNTIME_DIR");
1778 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", d
);
1780 if (pa_make_secure_dir(k
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1781 pa_log_error("Failed to create secure directory (%s): %s", k
, pa_cstrerror(errno
));
1788 /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
1789 d
= get_pulse_home();
1793 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1794 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1799 mid
= pa_machine_id();
1805 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-runtime", d
, mid
);
1810 /* OK, first let's check if the "runtime" symlink already exists */
1815 if (errno
!= ENOENT
) {
1816 pa_log_error("Failed to stat runtime directory %s: %s", k
, pa_cstrerror(errno
));
1821 /* Hmm, so the runtime directory didn't exist yet, so let's
1822 * create one in /tmp and symlink that to it */
1824 if (make_random_dir_and_link(0700, k
) < 0) {
1826 /* Mhmm, maybe another process was quicker than us,
1827 * let's check if that was valid */
1828 if (errno
== EEXIST
)
1834 /* No symlink possible, so let's just create the runtime directly
1835 * Do not check again if it exists since it cannot be a symlink */
1836 if (mkdir(k
) < 0 && errno
!= EEXIST
)
1843 /* Make sure that this actually makes sense */
1844 if (!pa_is_path_absolute(p
)) {
1845 pa_log_error("Path %s in link %s is not absolute.", p
, k
);
1850 /* Hmm, so this symlink is still around, make sure nobody fools us */
1854 if (lstat(p
, &st
) < 0) {
1856 if (errno
!= ENOENT
) {
1857 pa_log_error("Failed to stat runtime directory %s: %s", p
, pa_cstrerror(errno
));
1863 if (S_ISDIR(st
.st_mode
) &&
1864 (st
.st_uid
== getuid()) &&
1865 ((st
.st_mode
& 0777) == 0700)) {
1871 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1879 /* Hmm, so the link points to some nonexisting or invalid
1880 * dir. Let's replace it by a new link. We first create a
1881 * temporary link and then rename that to allow concurrent
1882 * execution of this function. */
1884 t
= pa_sprintf_malloc("%s.tmp", k
);
1886 if (make_random_dir_and_link(0700, t
) < 0) {
1888 if (errno
!= EEXIST
) {
1889 pa_log_error("Failed to symlink %s: %s", t
, pa_cstrerror(errno
));
1896 /* Hmm, someone else was quicker then us. Let's give
1897 * him some time to finish, and retry. */
1902 /* OK, we succeeded in creating the temporary symlink, so
1903 * let's rename it */
1904 if (rename(t
, k
) < 0) {
1905 pa_log_error("Failed to rename %s to %s: %s", t
, k
, pa_cstrerror(errno
));
1921 /* Try to open a configuration file. If "env" is specified, open the
1922 * value of the specified environment variable. Otherwise look for a
1923 * file "local" in the home directory or a file "global" in global
1924 * file system. If "result" is non-NULL, a pointer to a newly
1925 * allocated buffer containing the used configuration file is
1927 FILE *pa_open_config_file(const char *global
, const char *local
, const char *env
, char **result
) {
1931 if (env
&& (fn
= getenv(env
))) {
1932 if ((f
= pa_fopen_cloexec(fn
, "r"))) {
1934 *result
= pa_xstrdup(fn
);
1939 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1948 if ((e
= getenv("PULSE_CONFIG_PATH"))) {
1949 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1950 f
= pa_fopen_cloexec(fn
, "r");
1951 } else if ((h
= pa_get_home_dir_malloc())) {
1952 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1953 f
= pa_fopen_cloexec(fn
, "r");
1956 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".config/pulse" PA_PATH_SEP
"%s", h
, local
);
1957 f
= pa_fopen_cloexec(fn
, "r");
1965 *result
= pa_xstrdup(fn
);
1971 if (errno
!= ENOENT
) {
1972 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1984 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
1985 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
1986 pa_win32_get_toplevel(NULL
),
1987 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
1990 gfn
= pa_xstrdup(global
);
1992 if ((f
= pa_fopen_cloexec(gfn
, "r"))) {
2007 char *pa_find_config_file(const char *global
, const char *local
, const char *env
) {
2010 if (env
&& (fn
= getenv(env
))) {
2011 if (access(fn
, R_OK
) == 0)
2012 return pa_xstrdup(fn
);
2014 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2023 if ((e
= getenv("PULSE_CONFIG_PATH")))
2024 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
2025 else if ((h
= pa_get_home_dir_malloc())) {
2026 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
2031 if (access(fn
, R_OK
) == 0) {
2032 char *r
= pa_xstrdup(fn
);
2037 if (errno
!= ENOENT
) {
2038 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2050 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
2051 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
2052 pa_win32_get_toplevel(NULL
),
2053 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
2056 gfn
= pa_xstrdup(global
);
2058 if (access(gfn
, R_OK
) == 0)
2068 /* Format the specified data as a hexademical string */
2069 char *pa_hexstr(const uint8_t* d
, size_t dlength
, char *s
, size_t slength
) {
2070 size_t i
= 0, j
= 0;
2071 const char hex
[] = "0123456789abcdef";
2075 pa_assert(slength
> 0);
2077 while (j
+2 < slength
&& i
< dlength
) {
2078 s
[j
++] = hex
[*d
>> 4];
2079 s
[j
++] = hex
[*d
& 0xF];
2085 s
[j
< slength
? j
: slength
] = 0;
2089 /* Convert a hexadecimal digit to a number or -1 if invalid */
2090 static int hexc(char c
) {
2091 if (c
>= '0' && c
<= '9')
2094 if (c
>= 'A' && c
<= 'F')
2095 return c
- 'A' + 10;
2097 if (c
>= 'a' && c
<= 'f')
2098 return c
- 'a' + 10;
2104 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
2105 size_t pa_parsehex(const char *p
, uint8_t *d
, size_t dlength
) {
2111 while (j
< dlength
&& *p
) {
2114 if ((b
= hexc(*(p
++))) < 0)
2117 d
[j
] = (uint8_t) (b
<< 4);
2122 if ((b
= hexc(*(p
++))) < 0)
2125 d
[j
] |= (uint8_t) b
;
2132 /* Returns nonzero when *s starts with *pfx */
2133 bool pa_startswith(const char *s
, const char *pfx
) {
2141 return strlen(s
) >= l
&& strncmp(s
, pfx
, l
) == 0;
2144 /* Returns nonzero when *s ends with *sfx */
2145 bool pa_endswith(const char *s
, const char *sfx
) {
2154 return l1
>= l2
&& pa_streq(s
+ l1
- l2
, sfx
);
2157 bool pa_is_path_absolute(const char *fn
) {
2163 return strlen(fn
) >= 3 && isalpha(fn
[0]) && fn
[1] == ':' && fn
[2] == '\\';
2167 char *pa_make_path_absolute(const char *p
) {
2173 if (pa_is_path_absolute(p
))
2174 return pa_xstrdup(p
);
2176 if (!(cwd
= pa_getcwd()))
2177 return pa_xstrdup(p
);
2179 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", cwd
, p
);
2184 /* If fn is NULL, return the PulseAudio runtime or state dir (depending on the
2185 * rt parameter). If fn is non-NULL and starts with /, return fn. Otherwise,
2186 * append fn to the runtime/state dir and return it. */
2187 static char *get_path(const char *fn
, bool prependmid
, bool rt
) {
2190 rtp
= rt
? pa_get_runtime_dir() : pa_get_state_dir();
2193 char *r
, *canonical_rtp
;
2195 if (pa_is_path_absolute(fn
)) {
2197 return pa_xstrdup(fn
);
2203 /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
2204 if ((canonical_rtp
= pa_realpath(rtp
))) {
2205 if (strlen(rtp
) >= strlen(canonical_rtp
))
2208 pa_xfree(canonical_rtp
);
2209 canonical_rtp
= rtp
;
2212 canonical_rtp
= rtp
;
2217 if (!(mid
= pa_machine_id())) {
2218 pa_xfree(canonical_rtp
);
2222 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-%s", canonical_rtp
, mid
, fn
);
2225 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", canonical_rtp
, fn
);
2227 pa_xfree(canonical_rtp
);
2233 char *pa_runtime_path(const char *fn
) {
2234 return get_path(fn
, false, true);
2237 char *pa_state_path(const char *fn
, bool appendmid
) {
2238 return get_path(fn
, appendmid
, false);
2241 /* Convert the string s to a signed integer in *ret_i */
2242 int pa_atoi(const char *s
, int32_t *ret_i
) {
2248 if (pa_atol(s
, &l
) < 0)
2251 if ((int32_t) l
!= l
) {
2256 *ret_i
= (int32_t) l
;
2261 /* Convert the string s to an unsigned integer in *ret_u */
2262 int pa_atou(const char *s
, uint32_t *ret_u
) {
2270 l
= strtoul(s
, &x
, 0);
2272 if (!x
|| *x
|| errno
) {
2278 if ((uint32_t) l
!= l
) {
2283 *ret_u
= (uint32_t) l
;
2288 /* Convert the string s to a signed long integer in *ret_l. */
2289 int pa_atol(const char *s
, long *ret_l
) {
2297 l
= strtol(s
, &x
, 0);
2299 if (!x
|| *x
|| errno
) {
2310 #ifdef HAVE_STRTOF_L
2311 static locale_t c_locale
= NULL
;
2313 static void c_locale_destroy(void) {
2314 freelocale(c_locale
);
2318 int pa_atod(const char *s
, double *ret_d
) {
2325 /* This should be locale independent */
2327 #ifdef HAVE_STRTOF_L
2331 if ((c_locale
= newlocale(LC_ALL_MASK
, "C", NULL
)))
2332 atexit(c_locale_destroy
);
2338 f
= strtod_l(s
, &x
, c_locale
);
2346 if (!x
|| *x
|| errno
) {
2357 /* Same as snprintf, but guarantees NUL-termination on every platform */
2358 size_t pa_snprintf(char *str
, size_t size
, const char *format
, ...) {
2363 pa_assert(size
> 0);
2366 va_start(ap
, format
);
2367 ret
= pa_vsnprintf(str
, size
, format
, ap
);
2373 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2374 size_t pa_vsnprintf(char *str
, size_t size
, const char *format
, va_list ap
) {
2378 pa_assert(size
> 0);
2381 ret
= vsnprintf(str
, size
, format
, ap
);
2388 if ((size_t) ret
> size
-1)
2391 return (size_t) ret
;
2394 /* Truncate the specified string, but guarantee that the string
2395 * returned still validates as UTF8 */
2396 char *pa_truncate_utf8(char *c
, size_t l
) {
2398 pa_assert(pa_utf8_valid(c
));
2405 while (l
> 0 && !pa_utf8_valid(c
))
2411 char *pa_getcwd(void) {
2415 char *p
= pa_xmalloc(l
);
2419 if (errno
!= ERANGE
)
2427 void *pa_will_need(const void *p
, size_t l
) {
2428 #ifdef RLIMIT_MEMLOCK
2439 a
= PA_PAGE_ALIGN_PTR(p
);
2440 size
= (size_t) ((const uint8_t*) p
+ l
- (const uint8_t*) a
);
2442 #ifdef HAVE_POSIX_MADVISE
2443 if ((r
= posix_madvise((void*) a
, size
, POSIX_MADV_WILLNEED
)) == 0) {
2444 pa_log_debug("posix_madvise() worked fine!");
2449 /* Most likely the memory was not mmap()ed from a file and thus
2450 * madvise() didn't work, so let's misuse mlock() do page this
2451 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2452 * inviting, the man page of mlock() tells us: "All pages that
2453 * contain a part of the specified address range are guaranteed to
2454 * be resident in RAM when the call returns successfully." */
2456 #ifdef RLIMIT_MEMLOCK
2457 pa_assert_se(getrlimit(RLIMIT_MEMLOCK
, &rlim
) == 0);
2459 if (rlim
.rlim_cur
< PA_PAGE_SIZE
) {
2460 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
));
2465 bs
= PA_PAGE_ALIGN((size_t) rlim
.rlim_cur
);
2467 bs
= PA_PAGE_SIZE
*4;
2470 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r
));
2473 while (size
> 0 && bs
> 0) {
2478 if (mlock(a
, bs
) < 0) {
2479 bs
= PA_PAGE_ALIGN(bs
/ 2);
2483 pa_assert_se(munlock(a
, bs
) == 0);
2485 a
= (const uint8_t*) a
+ bs
;
2491 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno
));
2493 pa_log_debug("mlock() worked fine!");
2498 void pa_close_pipe(int fds
[2]) {
2502 pa_assert_se(pa_close(fds
[0]) == 0);
2505 pa_assert_se(pa_close(fds
[1]) == 0);
2507 fds
[0] = fds
[1] = -1;
2510 char *pa_readlink(const char *p
) {
2511 #ifdef HAVE_READLINK
2520 if ((n
= readlink(p
, c
, l
-1)) < 0) {
2525 if ((size_t) n
< l
-1) {
2538 int pa_close_all(int except_fd
, ...) {
2543 va_start(ap
, except_fd
);
2546 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2551 p
= pa_xnew(int, n
+1);
2553 va_start(ap
, except_fd
);
2556 if (except_fd
>= 0) {
2560 while ((fd
= va_arg(ap
, int)) >= 0)
2567 r
= pa_close_allv(p
);
2573 int pa_close_allv(const int except_fds
[]) {
2582 if ((d
= opendir("/proc/self/fd"))) {
2586 while ((de
= readdir(d
))) {
2592 if (de
->d_name
[0] == '.')
2596 l
= strtol(de
->d_name
, &e
, 10);
2597 if (errno
!= 0 || !e
|| *e
) {
2605 if ((long) fd
!= l
) {
2618 for (i
= 0; except_fds
[i
] >= 0; i
++)
2619 if (except_fds
[i
] == fd
) {
2627 if (pa_close(fd
) < 0) {
2628 saved_errno
= errno
;
2630 errno
= saved_errno
;
2642 if (getrlimit(RLIMIT_NOFILE
, &rl
) >= 0)
2643 maxfd
= (int) rl
.rlim_max
;
2645 maxfd
= sysconf(_SC_OPEN_MAX
);
2647 for (fd
= 3; fd
< maxfd
; fd
++) {
2652 for (i
= 0; except_fds
[i
] >= 0; i
++)
2653 if (except_fds
[i
] == fd
) {
2661 if (pa_close(fd
) < 0 && errno
!= EBADF
)
2664 #endif /* !OS_IS_WIN32 */
2669 int pa_unblock_sigs(int except
, ...) {
2674 va_start(ap
, except
);
2677 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2682 p
= pa_xnew(int, n
+1);
2684 va_start(ap
, except
);
2691 while ((sig
= va_arg(ap
, int)) >= 0)
2698 r
= pa_unblock_sigsv(p
);
2704 int pa_unblock_sigsv(const int except
[]) {
2709 if (sigemptyset(&ss
) < 0)
2712 for (i
= 0; except
[i
] > 0; i
++)
2713 if (sigaddset(&ss
, except
[i
]) < 0)
2716 return sigprocmask(SIG_SETMASK
, &ss
, NULL
);
2722 int pa_reset_sigs(int except
, ...) {
2727 va_start(ap
, except
);
2730 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2735 p
= pa_xnew(int, n
+1);
2737 va_start(ap
, except
);
2744 while ((sig
= va_arg(ap
, int)) >= 0)
2751 r
= pa_reset_sigsv(p
);
2757 int pa_reset_sigsv(const int except
[]) {
2761 for (sig
= 1; sig
< NSIG
; sig
++) {
2773 for (i
= 0; except
[i
] > 0; i
++) {
2774 if (sig
== except
[i
]) {
2783 struct sigaction sa
;
2785 memset(&sa
, 0, sizeof(sa
));
2786 sa
.sa_handler
= SIG_DFL
;
2788 /* On Linux the first two RT signals are reserved by
2789 * glibc, and sigaction() will return EINVAL for them. */
2790 if ((sigaction(sig
, &sa
, NULL
) < 0))
2791 if (errno
!= EINVAL
)
2800 void pa_set_env(const char *key
, const char *value
) {
2804 /* This is not thread-safe */
2807 SetEnvironmentVariable(key
, value
);
2809 setenv(key
, value
, 1);
2813 void pa_set_env_and_record(const char *key
, const char *value
) {
2817 /* This is not thread-safe */
2819 pa_set_env(key
, value
);
2820 recorded_env
= pa_strlist_prepend(recorded_env
, key
);
2823 void pa_unset_env_recorded(void) {
2825 /* This is not thread-safe */
2830 recorded_env
= pa_strlist_pop(recorded_env
, &s
);
2836 SetEnvironmentVariable(s
, NULL
);
2844 bool pa_in_system_mode(void) {
2847 if (!(e
= getenv("PULSE_SYSTEM")))
2853 /* Checks a whitespace-separated list of words in haystack for needle */
2854 bool pa_str_in_list_spaces(const char *haystack
, const char *needle
) {
2856 const char *state
= NULL
;
2858 if (!haystack
|| !needle
)
2861 while ((s
= pa_split_spaces(haystack
, &state
))) {
2862 if (pa_streq(needle
, s
)) {
2873 char *pa_get_user_name_malloc(void) {
2877 #ifdef _SC_LOGIN_NAME_MAX
2878 k
= (ssize_t
) sysconf(_SC_LOGIN_NAME_MAX
);
2884 u
= pa_xnew(char, k
+1);
2886 if (!(pa_get_user_name(u
, k
))) {
2894 char *pa_get_host_name_malloc(void) {
2903 if (!pa_get_host_name(c
, l
)) {
2905 if (errno
!= EINVAL
&& errno
!= ENAMETOOLONG
)
2908 } else if (strlen(c
) < l
-1) {
2916 u
= pa_utf8_filter(c
);
2921 /* Hmm, the hostname is as long the space we offered the
2922 * function, we cannot know if it fully fit in, so let's play
2923 * safe and retry. */
2932 char *pa_machine_id(void) {
2936 /* The returned value is supposed be some kind of ascii identifier
2937 * that is unique and stable across reboots. */
2939 /* First we try the /etc/machine-id, which is the best option we
2940 * have, since it fits perfectly our needs and is not as volatile
2941 * as the hostname which might be set from dhcp. */
2943 if ((f
= pa_fopen_cloexec(PA_MACHINE_ID
, "r")) ||
2944 (f
= pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK
, "r"))) {
2945 char ln
[34] = "", *r
;
2947 r
= fgets(ln
, sizeof(ln
)-1, f
);
2953 return pa_utf8_filter(ln
);
2956 if ((h
= pa_get_host_name_malloc()))
2959 #if !defined(OS_IS_WIN32) && !defined(__ANDROID__)
2960 /* If no hostname was set we use the POSIX hostid. It's usually
2961 * the IPv4 address. Might not be that stable. */
2962 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
2968 char *pa_session_id(void) {
2971 e
= getenv("XDG_SESSION_ID");
2975 return pa_utf8_filter(e
);
2978 char *pa_uname_string(void) {
2982 pa_assert_se(uname(&u
) >= 0);
2984 return pa_sprintf_malloc("%s %s %s %s", u
.sysname
, u
.machine
, u
.release
, u
.version
);
2990 i
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
2991 pa_assert_se(GetVersionEx(&i
));
2993 return pa_sprintf_malloc("Windows %d.%d (%d) %s", i
.dwMajorVersion
, i
.dwMinorVersion
, i
.dwBuildNumber
, i
.szCSDVersion
);
2997 #ifdef HAVE_VALGRIND_MEMCHECK_H
2998 bool pa_in_valgrind(void) {
3001 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
3002 * here instead of really checking whether we run in valgrind or
3006 b
= getenv("VALGRIND") ? 2 : 1;
3012 unsigned pa_gcd(unsigned a
, unsigned b
) {
3023 void pa_reduce(unsigned *num
, unsigned *den
) {
3025 unsigned gcd
= pa_gcd(*num
, *den
);
3033 pa_assert(pa_gcd(*num
, *den
) == 1);
3036 unsigned pa_ncpus(void) {
3039 #ifdef _SC_NPROCESSORS_CONF
3040 ncpus
= sysconf(_SC_NPROCESSORS_CONF
);
3045 return ncpus
<= 0 ? 1 : (unsigned) ncpus
;
3048 char *pa_replace(const char*s
, const char*a
, const char *b
) {
3057 sb
= pa_strbuf_new();
3062 if (!(p
= strstr(s
, a
)))
3065 pa_strbuf_putsn(sb
, s
, p
-s
);
3066 pa_strbuf_puts(sb
, b
);
3070 pa_strbuf_puts(sb
, s
);
3072 return pa_strbuf_tostring_free(sb
);
3075 char *pa_escape(const char *p
, const char *chars
) {
3078 pa_strbuf
*buf
= pa_strbuf_new();
3080 for (s
= p
; *s
; ++s
) {
3082 pa_strbuf_putc(buf
, '\\');
3084 for (c
= chars
; *c
; ++c
) {
3086 pa_strbuf_putc(buf
, '\\');
3091 pa_strbuf_putc(buf
, *s
);
3094 return pa_strbuf_tostring_free(buf
);
3097 char *pa_unescape(char *p
) {
3099 bool escaped
= false;
3101 for (s
= p
, d
= p
; *s
; s
++) {
3102 if (!escaped
&& *s
== '\\') {
3116 char *pa_realpath(const char *path
) {
3120 /* We want only absolute paths */
3121 if (path
[0] != '/') {
3126 #if defined(__GLIBC__)
3130 if (!(r
= realpath(path
, NULL
)))
3133 /* We copy this here in case our pa_xmalloc() is not
3134 * implemented on top of libc malloc() */
3138 #elif defined(PATH_MAX)
3141 path_buf
= pa_xmalloc(PATH_MAX
);
3143 #if defined(OS_IS_WIN32)
3144 if (!(t
= _fullpath(path_buf
, path
, _MAX_PATH
))) {
3149 if (!(t
= realpath(path
, path_buf
))) {
3156 #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."
3162 void pa_disable_sigpipe(void) {
3165 struct sigaction sa
;
3169 if (sigaction(SIGPIPE
, NULL
, &sa
) < 0) {
3170 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3174 sa
.sa_handler
= SIG_IGN
;
3176 if (sigaction(SIGPIPE
, &sa
, NULL
) < 0) {
3177 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3183 void pa_xfreev(void**a
) {
3189 for (p
= a
; *p
; p
++)
3195 char **pa_split_spaces_strv(const char *s
) {
3197 unsigned i
= 0, n
= 8;
3198 const char *state
= NULL
;
3200 t
= pa_xnew(char*, n
);
3201 while ((e
= pa_split_spaces(s
, &state
))) {
3206 t
= pa_xrenew(char*, t
, n
);
3219 char* pa_maybe_prefix_path(const char *path
, const char *prefix
) {
3222 if (pa_is_path_absolute(path
))
3223 return pa_xstrdup(path
);
3225 return pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", prefix
, path
);
3228 size_t pa_pipe_buf(int fd
) {
3233 if ((n
= fpathconf(fd
, _PC_PIPE_BUF
)) >= 0)
3244 void pa_reset_personality(void) {
3246 #if defined(__linux__) && !defined(__ANDROID__)
3247 if (personality(PER_LINUX
) < 0)
3248 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno
));
3253 bool pa_run_from_build_tree(void) {
3255 static bool b
= false;
3258 if ((rp
= pa_readlink("/proc/self/exe"))) {
3259 b
= pa_startswith(rp
, PA_BUILDDIR
);
3267 const char *pa_get_temp_dir(void) {
3270 if ((t
= getenv("TMPDIR")) &&
3271 pa_is_path_absolute(t
))
3274 if ((t
= getenv("TMP")) &&
3275 pa_is_path_absolute(t
))
3278 if ((t
= getenv("TEMP")) &&
3279 pa_is_path_absolute(t
))
3282 if ((t
= getenv("TEMPDIR")) &&
3283 pa_is_path_absolute(t
))
3289 int pa_open_cloexec(const char *fn
, int flags
, mode_t mode
) {
3297 if ((fd
= open(fn
, flags
|O_CLOEXEC
, mode
)) >= 0)
3300 if (errno
!= EINVAL
)
3304 if ((fd
= open(fn
, flags
, mode
)) < 0)
3308 /* Some implementations might simply ignore O_CLOEXEC if it is not
3309 * understood, make sure FD_CLOEXEC is enabled anyway */
3311 pa_make_fd_cloexec(fd
);
3315 int pa_socket_cloexec(int domain
, int type
, int protocol
) {
3319 if ((fd
= socket(domain
, type
| SOCK_CLOEXEC
, protocol
)) >= 0)
3322 if (errno
!= EINVAL
)
3326 if ((fd
= socket(domain
, type
, protocol
)) < 0)
3330 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3331 * not understood, make sure FD_CLOEXEC is enabled anyway */
3333 pa_make_fd_cloexec(fd
);
3337 int pa_pipe_cloexec(int pipefd
[2]) {
3341 if ((r
= pipe2(pipefd
, O_CLOEXEC
)) >= 0)
3344 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3349 if ((r
= pipe(pipefd
)) < 0)
3353 pa_make_fd_cloexec(pipefd
[0]);
3354 pa_make_fd_cloexec(pipefd
[1]);
3359 int pa_accept_cloexec(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
) {
3363 if ((fd
= accept4(sockfd
, addr
, addrlen
, SOCK_CLOEXEC
)) >= 0)
3366 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3371 if ((fd
= accept(sockfd
, addr
, addrlen
)) < 0)
3375 pa_make_fd_cloexec(fd
);
3379 FILE* pa_fopen_cloexec(const char *path
, const char *mode
) {
3383 m
= pa_sprintf_malloc("%se", mode
);
3386 if ((f
= fopen(path
, m
))) {
3393 if (errno
!= EINVAL
)
3396 if (!(f
= fopen(path
, mode
)))
3400 pa_make_fd_cloexec(fileno(f
));
3404 void pa_nullify_stdfds(void) {
3407 pa_close(STDIN_FILENO
);
3408 pa_close(STDOUT_FILENO
);
3409 pa_close(STDERR_FILENO
);
3411 pa_assert_se(open("/dev/null", O_RDONLY
) == STDIN_FILENO
);
3412 pa_assert_se(open("/dev/null", O_WRONLY
) == STDOUT_FILENO
);
3413 pa_assert_se(open("/dev/null", O_WRONLY
) == STDERR_FILENO
);
3420 char *pa_read_line_from_file(const char *fn
) {
3422 char ln
[256] = "", *r
;
3424 if (!(f
= pa_fopen_cloexec(fn
, "r")))
3427 r
= fgets(ln
, sizeof(ln
)-1, f
);
3436 return pa_xstrdup(ln
);
3439 bool pa_running_in_vm(void) {
3441 #if defined(__i386__) || defined(__x86_64__)
3443 /* Both CPUID and DMI are x86 specific interfaces... */
3445 uint32_t eax
= 0x40000000;
3452 const char *const dmi_vendors
[] = {
3453 "/sys/class/dmi/id/sys_vendor",
3454 "/sys/class/dmi/id/board_vendor",
3455 "/sys/class/dmi/id/bios_vendor"
3460 for (i
= 0; i
< PA_ELEMENTSOF(dmi_vendors
); i
++) {
3463 if ((s
= pa_read_line_from_file(dmi_vendors
[i
]))) {
3465 if (pa_startswith(s
, "QEMU") ||
3466 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3467 pa_startswith(s
, "VMware") ||
3468 pa_startswith(s
, "VMW") ||
3469 pa_startswith(s
, "Microsoft Corporation") ||
3470 pa_startswith(s
, "innotek GmbH") ||
3471 pa_startswith(s
, "Xen")) {
3483 /* http://lwn.net/Articles/301888/ */
3486 __asm__
__volatile__ (
3487 /* ebx/rbx is being used for PIC! */
3488 " push %%"PA_REG_b
" \n\t"
3490 " mov %%ebx, %1 \n\t"
3491 " pop %%"PA_REG_b
" \n\t"
3493 : "=a" (eax
), "=r" (sig
.sig32
[0]), "=c" (sig
.sig32
[1]), "=d" (sig
.sig32
[2])
3497 if (pa_streq(sig
.text
, "XenVMMXenVMM") ||
3498 pa_streq(sig
.text
, "KVMKVMKVM") ||
3499 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3500 pa_streq(sig
.text
, "VMwareVMware") ||
3501 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3502 pa_streq(sig
.text
, "Microsoft Hv"))