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);
333 if (uid
== (uid_t
) -1)
335 if (gid
== (gid_t
) -1)
337 if (fchown(fd
, uid
, gid
) < 0)
342 (void) fchmod(fd
, m
);
345 pa_assert_se(pa_close(fd
) >= 0);
350 if (lstat(dir
, &st
) < 0)
352 if (stat(dir
, &st
) < 0)
357 if (!S_ISDIR(st
.st_mode
) ||
358 (st
.st_uid
!= uid
) ||
359 (st
.st_gid
!= gid
) ||
360 ((st
.st_mode
& 0777) != m
)) {
365 pa_log_warn("Secure directory creation not supported on Win32.");
378 /* Return a newly allocated sting containing the parent directory of the specified file */
379 char *pa_parent_dir(const char *fn
) {
380 char *slash
, *dir
= pa_xstrdup(fn
);
382 if ((slash
= (char*) pa_path_get_filename(dir
)) == dir
) {
392 /* Creates a the parent directory of the specified path securely */
393 int pa_make_secure_parent_dir(const char *fn
, mode_t m
, uid_t uid
, gid_t gid
, bool update_perms
) {
397 if (!(dir
= pa_parent_dir(fn
)))
400 if (pa_make_secure_dir(dir
, m
, uid
, gid
, update_perms
) < 0)
410 /** Platform independent read function. Necessary since not all
411 * systems treat all file descriptors equal. If type is
412 * non-NULL it is used to cache the type of the fd. This is
413 * useful for making sure that only a single syscall is executed per
414 * function call. The variable pointed to should be initialized to 0
416 ssize_t
pa_read(int fd
, void *buf
, size_t count
, int *type
) {
420 if (!type
|| *type
== 0) {
423 if ((r
= recv(fd
, buf
, count
, 0)) >= 0)
426 if (WSAGetLastError() != WSAENOTSOCK
) {
427 errno
= WSAGetLastError();
440 if ((r
= read(fd
, buf
, count
)) < 0)
448 /** Similar to pa_read(), but handles writes */
449 ssize_t
pa_write(int fd
, const void *buf
, size_t count
, int *type
) {
451 if (!type
|| *type
== 0) {
455 if ((r
= send(fd
, buf
, count
, MSG_NOSIGNAL
)) < 0) {
467 if (WSAGetLastError() != WSAENOTSOCK
) {
468 errno
= WSAGetLastError();
472 if (errno
!= ENOTSOCK
)
483 if ((r
= write(fd
, buf
, count
)) < 0)
491 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
492 * unless EOF is reached or an error occurred */
493 ssize_t
pa_loop_read(int fd
, void*data
, size_t size
, int *type
) {
509 if ((r
= pa_read(fd
, data
, size
, type
)) < 0)
516 data
= (uint8_t*) data
+ r
;
523 /** Similar to pa_loop_read(), but wraps write() */
524 ssize_t
pa_loop_write(int fd
, const void*data
, size_t size
, int *type
) {
540 if ((r
= pa_write(fd
, data
, size
, type
)) < 0)
547 data
= (const uint8_t*) data
+ r
;
554 /** Platform independent close function. Necessary since not all
555 * systems treat all file descriptors equal. */
556 int pa_close(int fd
) {
561 FD_CLR(fd
, &nonblocking_fds
);
563 if ((ret
= closesocket(fd
)) == 0)
566 if (WSAGetLastError() != WSAENOTSOCK
) {
567 errno
= WSAGetLastError();
575 if ((r
= close(fd
)) < 0)
583 /* Print a warning messages in case that the given signal is not
584 * blocked or trapped */
585 void pa_check_signal_is_blocked(int sig
) {
586 #ifdef HAVE_SIGACTION
590 /* If POSIX threads are supported use thread-aware
591 * pthread_sigmask() function, to check if the signal is
592 * blocked. Otherwise fall back to sigprocmask() */
595 if (pthread_sigmask(SIG_SETMASK
, NULL
, &set
) < 0) {
597 if (sigprocmask(SIG_SETMASK
, NULL
, &set
) < 0) {
598 pa_log("sigprocmask(): %s", pa_cstrerror(errno
));
605 if (sigismember(&set
, sig
))
608 /* Check whether the signal is trapped */
610 if (sigaction(sig
, NULL
, &sa
) < 0) {
611 pa_log("sigaction(): %s", pa_cstrerror(errno
));
615 if (sa
.sa_handler
!= SIG_DFL
)
618 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig
));
619 #else /* HAVE_SIGACTION */
620 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig
));
624 /* The following function is based on an example from the GNU libc
625 * documentation. This function is similar to GNU's asprintf(). */
626 char *pa_sprintf_malloc(const char *format
, ...) {
636 c
= pa_xrealloc(c
, size
);
638 va_start(ap
, format
);
639 r
= vsnprintf(c
, size
, format
, ap
);
644 if (r
> -1 && (size_t) r
< size
)
647 if (r
> -1) /* glibc 2.1 */
654 /* Same as the previous function, but use a va_list instead of an
656 char *pa_vsprintf_malloc(const char *format
, va_list ap
) {
666 c
= pa_xrealloc(c
, size
);
669 r
= vsnprintf(c
, size
, format
, aq
);
674 if (r
> -1 && (size_t) r
< size
)
677 if (r
> -1) /* glibc 2.1 */
684 /* Similar to OpenBSD's strlcpy() function */
685 char *pa_strlcpy(char *b
, const char *s
, size_t l
) {
703 #ifdef _POSIX_PRIORITY_SCHEDULING
704 static int set_scheduler(int rtprio
) {
706 struct sched_param sp
;
716 dbus_error_init(&error
);
720 sp
.sched_priority
= rtprio
;
722 #ifdef SCHED_RESET_ON_FORK
723 if (pthread_setschedparam(pthread_self(), SCHED_RR
|SCHED_RESET_ON_FORK
, &sp
) == 0) {
724 pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
729 if (pthread_setschedparam(pthread_self(), SCHED_RR
, &sp
) == 0) {
730 pa_log_debug("SCHED_RR worked.");
733 #endif /* HAVE_SCHED_H */
736 /* Try to talk to RealtimeKit */
738 if (!(bus
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
))) {
739 pa_log("Failed to connect to system bus: %s\n", error
.message
);
740 dbus_error_free(&error
);
745 /* We need to disable exit on disconnect because otherwise
746 * dbus_shutdown will kill us. See
747 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
748 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
750 rttime
= rtkit_get_rttime_usec_max(bus
);
753 r
= getrlimit(RLIMIT_RTTIME
, &rl
);
755 if (r
>= 0 && (long long) rl
.rlim_max
> rttime
) {
756 pa_log_info("Clamping rlimit-rttime to %lld for RealtimeKit\n", rttime
);
757 rl
.rlim_cur
= rl
.rlim_max
= rttime
;
758 r
= setrlimit(RLIMIT_RTTIME
, &rl
);
761 pa_log("setrlimit() failed: %s", pa_cstrerror(errno
));
764 r
= rtkit_make_realtime(bus
, 0, rtprio
);
765 dbus_connection_close(bus
);
766 dbus_connection_unref(bus
);
769 pa_log_debug("RealtimeKit worked.");
775 dbus_connection_close(bus
);
776 dbus_connection_unref(bus
);
788 /* Make the current thread a realtime thread, and acquire the highest
789 * rtprio we can get that is less or equal the specified parameter. If
790 * the thread is already realtime, don't do anything. */
791 int pa_make_realtime(int rtprio
) {
793 #if defined(OS_IS_DARWIN)
794 struct thread_time_constraint_policy ttcpolicy
;
796 size_t size
= sizeof(freq
);
799 ret
= sysctlbyname("hw.cpufrequency", &freq
, &size
, NULL
, 0);
801 pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
805 pa_log_debug("sysctl for hw.cpufrequency: %llu", freq
);
807 /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
808 ttcpolicy
.period
= freq
/ 160;
809 ttcpolicy
.computation
= freq
/ 3300;
810 ttcpolicy
.constraint
= freq
/ 2200;
811 ttcpolicy
.preemptible
= 1;
813 ret
= thread_policy_set(mach_thread_self(),
814 THREAD_TIME_CONSTRAINT_POLICY
,
815 (thread_policy_t
) &ttcpolicy
,
816 THREAD_TIME_CONSTRAINT_POLICY_COUNT
);
818 pa_log_info("Unable to set real-time thread priority (%08x).", ret
);
822 pa_log_info("Successfully acquired real-time thread priority.");
825 #elif defined(_POSIX_PRIORITY_SCHEDULING)
828 if (set_scheduler(rtprio
) >= 0) {
829 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio
);
833 for (p
= rtprio
-1; p
>= 1; p
--)
834 if (set_scheduler(p
) >= 0) {
835 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p
, rtprio
);
838 #elif defined(OS_IS_WIN32)
839 /* Windows only allows realtime scheduling to be set on a per process basis.
840 * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
841 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL
)) {
842 pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
846 pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
851 pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno
));
855 #ifdef HAVE_SYS_RESOURCE_H
856 static int set_nice(int nice_level
) {
862 dbus_error_init(&error
);
865 #ifdef HAVE_SYS_RESOURCE_H
866 if (setpriority(PRIO_PROCESS
, 0, nice_level
) >= 0) {
867 pa_log_debug("setpriority() worked.");
873 /* Try to talk to RealtimeKit */
875 if (!(bus
= dbus_bus_get(DBUS_BUS_SYSTEM
, &error
))) {
876 pa_log("Failed to connect to system bus: %s\n", error
.message
);
877 dbus_error_free(&error
);
882 /* We need to disable exit on disconnect because otherwise
883 * dbus_shutdown will kill us. See
884 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
885 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
887 r
= rtkit_make_high_priority(bus
, 0, nice_level
);
888 dbus_connection_unref(bus
);
891 pa_log_debug("RealtimeKit worked.");
902 /* Raise the priority of the current process as much as possible that
903 * is <= the specified nice level..*/
904 int pa_raise_priority(int nice_level
) {
906 #ifdef HAVE_SYS_RESOURCE_H
909 if (set_nice(nice_level
) >= 0) {
910 pa_log_info("Successfully gained nice level %i.", nice_level
);
914 for (n
= nice_level
+1; n
< 0; n
++)
915 if (set_nice(n
) >= 0) {
916 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n
, nice_level
);
920 pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno
));
925 if (nice_level
< 0) {
926 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS
)) {
927 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
932 pa_log_info("Successfully gained high priority class.");
939 /* Reset the priority to normal, inverting the changes made by
940 * pa_raise_priority() and pa_make_realtime()*/
941 void pa_reset_priority(void) {
942 #ifdef HAVE_SYS_RESOURCE_H
943 struct sched_param sp
;
945 setpriority(PRIO_PROCESS
, 0, 0);
948 pthread_setschedparam(pthread_self(), SCHED_OTHER
, &sp
);
952 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS
);
956 int pa_match(const char *expr
, const char *v
) {
957 #if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
962 if (regcomp(&re
, expr
, REG_NOSUB
|REG_EXTENDED
) != 0) {
967 if ((k
= regexec(&re
, v
, 0, NULL
, 0)) == 0)
969 else if (k
== REG_NOMATCH
)
986 /* Try to parse a boolean string value.*/
987 int pa_parse_boolean(const char *v
) {
990 /* First we check language independent */
991 if (pa_streq(v
, "1") || !strcasecmp(v
, "y") || !strcasecmp(v
, "t")
992 || !strcasecmp(v
, "yes") || !strcasecmp(v
, "true") || !strcasecmp(v
, "on"))
994 else if (pa_streq(v
, "0") || !strcasecmp(v
, "n") || !strcasecmp(v
, "f")
995 || !strcasecmp(v
, "no") || !strcasecmp(v
, "false") || !strcasecmp(v
, "off"))
998 #ifdef HAVE_LANGINFO_H
1001 /* And then we check language dependent */
1002 if ((expr
= nl_langinfo(YESEXPR
)))
1004 if (pa_match(expr
, v
) > 0)
1007 if ((expr
= nl_langinfo(NOEXPR
)))
1009 if (pa_match(expr
, v
) > 0)
1018 /* Try to parse a volume string to pa_volume_t. The allowed formats are:
1019 * db, % and unsigned integer */
1020 int pa_parse_volume(const char *v
, pa_volume_t
*volume
) {
1034 memcpy(str
, v
, len
+ 1);
1036 if (str
[len
- 1] == '%') {
1037 str
[len
- 1] = '\0';
1038 if (pa_atou(str
, &i
) == 0) {
1039 *volume
= PA_CLAMP_VOLUME((uint64_t) PA_VOLUME_NORM
* i
/ 100);
1042 } else if (len
> 2 && (str
[len
- 1] == 'b' || str
[len
- 1] == 'B') &&
1043 (str
[len
- 2] == 'd' || str
[len
- 2] == 'D')) {
1044 str
[len
- 2] = '\0';
1045 if (pa_atod(str
, &d
) == 0) {
1046 *volume
= pa_sw_volume_from_dB(d
);
1050 if (pa_atou(v
, &i
) == 0) {
1051 *volume
= PA_CLAMP_VOLUME(i
);
1060 /* Split the specified string wherever one of the strings in delimiter
1061 * occurs. Each time it is called returns a newly allocated string
1062 * with pa_xmalloc(). The variable state points to, should be
1063 * initialized to NULL before the first call. */
1064 char *pa_split(const char *c
, const char *delimiter
, const char**state
) {
1065 const char *current
= *state
? *state
: c
;
1071 l
= strcspn(current
, delimiter
);
1077 return pa_xstrndup(current
, l
);
1080 /* Split the specified string wherever one of the strings in delimiter
1081 * occurs. Each time it is called returns a pointer to the substring within the
1082 * string and the length in 'n'. Note that the resultant string cannot be used
1083 * as-is without the length parameter, since it is merely pointing to a point
1084 * within the original string. The variable state points to, should be
1085 * initialized to NULL before the first call. */
1086 const char *pa_split_in_place(const char *c
, const char *delimiter
, int *n
, const char**state
) {
1087 const char *current
= *state
? *state
: c
;
1093 l
= strcspn(current
, delimiter
);
1103 /* Split a string into words. Otherwise similar to pa_split(). */
1104 char *pa_split_spaces(const char *c
, const char **state
) {
1105 const char *current
= *state
? *state
: c
;
1108 if (!*current
|| *c
== 0)
1111 current
+= strspn(current
, WHITESPACE
);
1112 l
= strcspn(current
, WHITESPACE
);
1116 return pa_xstrndup(current
, l
);
1119 PA_STATIC_TLS_DECLARE(signame
, pa_xfree
);
1121 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
1122 const char *pa_sig2str(int sig
) {
1135 char buf
[SIG2STR_MAX
];
1137 if (sig2str(sig
, buf
) == 0) {
1138 pa_xfree(PA_STATIC_TLS_GET(signame
));
1139 t
= pa_sprintf_malloc("SIG%s", buf
);
1140 PA_STATIC_TLS_SET(signame
, t
);
1148 case SIGHUP
: return "SIGHUP";
1150 case SIGINT
: return "SIGINT";
1152 case SIGQUIT
: return "SIGQUIT";
1154 case SIGILL
: return "SIGULL";
1156 case SIGTRAP
: return "SIGTRAP";
1158 case SIGABRT
: return "SIGABRT";
1160 case SIGBUS
: return "SIGBUS";
1162 case SIGFPE
: return "SIGFPE";
1164 case SIGKILL
: return "SIGKILL";
1167 case SIGUSR1
: return "SIGUSR1";
1169 case SIGSEGV
: return "SIGSEGV";
1171 case SIGUSR2
: return "SIGUSR2";
1174 case SIGPIPE
: return "SIGPIPE";
1177 case SIGALRM
: return "SIGALRM";
1179 case SIGTERM
: return "SIGTERM";
1181 case SIGSTKFLT
: return "SIGSTKFLT";
1184 case SIGCHLD
: return "SIGCHLD";
1187 case SIGCONT
: return "SIGCONT";
1190 case SIGSTOP
: return "SIGSTOP";
1193 case SIGTSTP
: return "SIGTSTP";
1196 case SIGTTIN
: return "SIGTTIN";
1199 case SIGTTOU
: return "SIGTTOU";
1202 case SIGURG
: return "SIGURG";
1205 case SIGXCPU
: return "SIGXCPU";
1208 case SIGXFSZ
: return "SIGXFSZ";
1211 case SIGVTALRM
: return "SIGVTALRM";
1214 case SIGPROF
: return "SIGPROF";
1217 case SIGWINCH
: return "SIGWINCH";
1220 case SIGIO
: return "SIGIO";
1223 case SIGPWR
: return "SIGPWR";
1226 case SIGSYS
: return "SIGSYS";
1231 if (sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
1232 pa_xfree(PA_STATIC_TLS_GET(signame
));
1233 t
= pa_sprintf_malloc("SIGRTMIN+%i", sig
- SIGRTMIN
);
1234 PA_STATIC_TLS_SET(signame
, t
);
1243 pa_xfree(PA_STATIC_TLS_GET(signame
));
1244 t
= pa_sprintf_malloc("SIG%i", sig
);
1245 PA_STATIC_TLS_SET(signame
, t
);
1251 /* Check whether the specified GID and the group name match */
1252 static int is_group(gid_t gid
, const char *name
) {
1253 struct group
*group
= NULL
;
1257 if (!(group
= pa_getgrgid_malloc(gid
))) {
1261 pa_log("pa_getgrgid_malloc(%u): %s", gid
, pa_cstrerror(errno
));
1266 r
= pa_streq(name
, group
->gr_name
);
1269 pa_getgrgid_free(group
);
1274 /* Check the current user is member of the specified group */
1275 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1276 GETGROUPS_T
*gids
, tgid
;
1277 long n
= sysconf(_SC_NGROUPS_MAX
);
1282 gids
= pa_xmalloc(sizeof(GETGROUPS_T
) * (size_t) n
);
1284 if ((n
= getgroups((int) n
, gids
)) < 0) {
1285 pa_log("getgroups(): %s", pa_cstrerror(errno
));
1289 for (i
= 0; i
< n
; i
++) {
1291 if ((k
= is_group(gids
[i
], name
)) < 0)
1300 if ((k
= is_group(tgid
= getgid(), name
)) < 0)
1316 /* Check whether the specific user id is a member of the specified group */
1317 int pa_uid_in_group(uid_t uid
, const char *name
) {
1318 struct group
*group
= NULL
;
1323 if (!(group
= pa_getgrnam_malloc(name
))) {
1330 for (i
= group
->gr_mem
; *i
; i
++) {
1331 struct passwd
*pw
= NULL
;
1334 if (!(pw
= pa_getpwnam_malloc(*i
)))
1337 if (pw
->pw_uid
== uid
)
1340 pa_getpwnam_free(pw
);
1347 pa_getgrnam_free(group
);
1352 /* Get the GID of a given group, return (gid_t) -1 on failure. */
1353 gid_t
pa_get_gid_of_group(const char *name
) {
1354 gid_t ret
= (gid_t
) -1;
1355 struct group
*gr
= NULL
;
1358 if (!(gr
= pa_getgrnam_malloc(name
))) {
1367 pa_getgrnam_free(gr
);
1371 int pa_check_in_group(gid_t g
) {
1372 gid_t gids
[NGROUPS_MAX
];
1375 if ((r
= getgroups(NGROUPS_MAX
, gids
)) < 0)
1385 #else /* HAVE_GRP_H */
1387 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1393 int pa_uid_in_group(uid_t uid
, const char *name
) {
1398 gid_t
pa_get_gid_of_group(const char *name
) {
1403 int pa_check_in_group(gid_t g
) {
1410 /* Lock or unlock a file entirely.
1411 (advisory on UNIX, mandatory on Windows) */
1412 int pa_lock_fd(int fd
, int b
) {
1414 struct flock f_lock
;
1416 /* Try a R/W lock first */
1418 f_lock
.l_type
= (short) (b
? F_WRLCK
: F_UNLCK
);
1419 f_lock
.l_whence
= SEEK_SET
;
1423 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1426 /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
1427 if (b
&& errno
== EBADF
) {
1428 f_lock
.l_type
= F_RDLCK
;
1429 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1433 pa_log("%slock: %s", !b
? "un" : "", pa_cstrerror(errno
));
1437 HANDLE h
= (HANDLE
) _get_osfhandle(fd
);
1439 if (b
&& LockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1441 if (!b
&& UnlockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1444 pa_log("%slock failed: 0x%08X", !b
? "un" : "", GetLastError());
1446 /* FIXME: Needs to set errno! */
1452 /* Remove trailing newlines from a string */
1453 char* pa_strip_nl(char *s
) {
1456 s
[strcspn(s
, NEWLINE
)] = 0;
1460 char *pa_strip(char *s
) {
1463 /* Drops trailing whitespace. Modifies the string in
1464 * place. Returns pointer to first non-space character */
1466 s
+= strspn(s
, WHITESPACE
);
1468 for (e
= s
; *e
; e
++)
1469 if (!strchr(WHITESPACE
, *e
))
1480 /* Create a temporary lock file and lock it. */
1481 int pa_lock_lockfile(const char *fn
) {
1488 if ((fd
= pa_open_cloexec(fn
, O_CREAT
|O_RDWR
1492 , S_IRUSR
|S_IWUSR
)) < 0) {
1493 pa_log_warn("Failed to create lock file '%s': %s", fn
, pa_cstrerror(errno
));
1497 if (pa_lock_fd(fd
, 1) < 0) {
1498 pa_log_warn("Failed to lock file '%s'.", fn
);
1502 if (fstat(fd
, &st
) < 0) {
1503 pa_log_warn("Failed to fstat() file '%s': %s", fn
, pa_cstrerror(errno
));
1507 /* Check whether the file has been removed meanwhile. When yes,
1508 * restart this loop, otherwise, we're done */
1509 if (st
.st_nlink
>= 1)
1512 if (pa_lock_fd(fd
, 0) < 0) {
1513 pa_log_warn("Failed to unlock file '%s'.", fn
);
1517 if (pa_close(fd
) < 0) {
1518 pa_log_warn("Failed to close file '%s': %s", fn
, pa_cstrerror(errno
));
1529 int saved_errno
= errno
;
1531 errno
= saved_errno
;
1537 /* Unlock a temporary lock file */
1538 int pa_unlock_lockfile(const char *fn
, int fd
) {
1543 if (unlink(fn
) < 0) {
1544 pa_log_warn("Unable to remove lock file '%s': %s", fn
, pa_cstrerror(errno
));
1549 if (pa_lock_fd(fd
, 0) < 0) {
1550 pa_log_warn("Failed to unlock file '%s'.", fn
);
1554 if (pa_close(fd
) < 0) {
1555 pa_log_warn("Failed to close '%s': %s", fn
, pa_cstrerror(errno
));
1562 static char *get_config_home(char *home
) {
1565 t
= getenv("XDG_CONFIG_HOME");
1567 return pa_xstrdup(t
);
1569 return pa_sprintf_malloc("%s" PA_PATH_SEP
".config", home
);
1572 static int check_ours(const char *p
) {
1577 if (stat(p
, &st
) < 0)
1581 if (st
.st_uid
!= getuid())
1588 static char *get_pulse_home(void) {
1589 char *h
, *ret
, *config_home
;
1592 h
= pa_get_home_dir_malloc();
1594 pa_log_error("Failed to get home directory.");
1599 if (t
< 0 && t
!= -ENOENT
) {
1600 pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t
));
1605 /* If the old directory exists, use it. */
1606 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse", h
);
1607 if (access(ret
, F_OK
) >= 0) {
1613 /* Otherwise go for the XDG compliant directory. */
1614 config_home
= get_config_home(h
);
1616 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", config_home
);
1622 char *pa_get_state_dir(void) {
1625 /* The state directory shall contain dynamic data that should be
1626 * kept across reboots, and is private to this user */
1628 if (!(d
= pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1629 if (!(d
= get_pulse_home()))
1632 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1633 * dir then this will break. */
1635 if (pa_make_secure_dir(d
, 0700U, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1636 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1644 char *pa_get_home_dir_malloc(void) {
1646 size_t allocated
= 128;
1649 homedir
= pa_xmalloc(allocated
);
1651 if (!pa_get_home_dir(homedir
, allocated
)) {
1656 if (strlen(homedir
) < allocated
- 1)
1666 char *pa_get_binary_name_malloc(void) {
1668 size_t allocated
= 128;
1671 t
= pa_xmalloc(allocated
);
1673 if (!pa_get_binary_name(t
, allocated
)) {
1678 if (strlen(t
) < allocated
- 1)
1688 static char* make_random_dir(mode_t m
) {
1689 static const char table
[] =
1690 "abcdefghijklmnopqrstuvwxyz"
1691 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1697 fn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1698 pathlen
= strlen(fn
);
1706 for (i
= pathlen
- 12; i
< pathlen
; i
++)
1707 fn
[i
] = table
[rand() % (sizeof(table
)-1)];
1709 u
= umask((~m
) & 0777);
1716 saved_errno
= errno
;
1718 errno
= saved_errno
;
1723 if (errno
!= EEXIST
) {
1724 pa_log_error("Failed to create random directory %s: %s", fn
, pa_cstrerror(errno
));
1731 static int make_random_dir_and_link(mode_t m
, const char *k
) {
1734 if (!(p
= make_random_dir(m
)))
1738 if (symlink(p
, k
) < 0) {
1739 int saved_errno
= errno
;
1741 if (errno
!= EEXIST
)
1742 pa_log_error("Failed to symlink %s to %s: %s", k
, p
, pa_cstrerror(errno
));
1747 errno
= saved_errno
;
1759 char *pa_get_runtime_dir(void) {
1760 char *d
, *k
= NULL
, *p
= NULL
, *t
= NULL
, *mid
;
1763 /* The runtime directory shall contain dynamic data that needs NOT
1764 * to be kept across reboots and is usually private to the user,
1765 * except in system mode, where it might be accessible by other
1766 * users, too. Since we need POSIX locking and UNIX sockets in
1767 * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
1768 * set create a directory in $HOME and link it to a random subdir
1769 * in /tmp, if it was not explicitly configured. */
1771 m
= pa_in_system_mode() ? 0755U : 0700U;
1773 /* Use the explicitly configured value if it is set */
1774 d
= getenv("PULSE_RUNTIME_PATH");
1777 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1778 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1782 return pa_xstrdup(d
);
1785 /* Use the XDG standard for the runtime directory. */
1786 d
= getenv("XDG_RUNTIME_DIR");
1788 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", d
);
1790 if (pa_make_secure_dir(k
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1791 pa_log_error("Failed to create secure directory (%s): %s", k
, pa_cstrerror(errno
));
1798 /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
1799 d
= get_pulse_home();
1803 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1804 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1809 mid
= pa_machine_id();
1815 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-runtime", d
, mid
);
1820 /* OK, first let's check if the "runtime" symlink already exists */
1825 if (errno
!= ENOENT
) {
1826 pa_log_error("Failed to stat runtime directory %s: %s", k
, pa_cstrerror(errno
));
1831 /* Hmm, so the runtime directory didn't exist yet, so let's
1832 * create one in /tmp and symlink that to it */
1834 if (make_random_dir_and_link(0700, k
) < 0) {
1836 /* Mhmm, maybe another process was quicker than us,
1837 * let's check if that was valid */
1838 if (errno
== EEXIST
)
1844 /* No symlink possible, so let's just create the runtime directly
1845 * Do not check again if it exists since it cannot be a symlink */
1846 if (mkdir(k
) < 0 && errno
!= EEXIST
)
1853 /* Make sure that this actually makes sense */
1854 if (!pa_is_path_absolute(p
)) {
1855 pa_log_error("Path %s in link %s is not absolute.", p
, k
);
1860 /* Hmm, so this symlink is still around, make sure nobody fools us */
1864 if (lstat(p
, &st
) < 0) {
1866 if (errno
!= ENOENT
) {
1867 pa_log_error("Failed to stat runtime directory %s: %s", p
, pa_cstrerror(errno
));
1873 if (S_ISDIR(st
.st_mode
) &&
1874 (st
.st_uid
== getuid()) &&
1875 ((st
.st_mode
& 0777) == 0700)) {
1881 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1889 /* Hmm, so the link points to some nonexisting or invalid
1890 * dir. Let's replace it by a new link. We first create a
1891 * temporary link and then rename that to allow concurrent
1892 * execution of this function. */
1894 t
= pa_sprintf_malloc("%s.tmp", k
);
1896 if (make_random_dir_and_link(0700, t
) < 0) {
1898 if (errno
!= EEXIST
) {
1899 pa_log_error("Failed to symlink %s: %s", t
, pa_cstrerror(errno
));
1906 /* Hmm, someone else was quicker then us. Let's give
1907 * him some time to finish, and retry. */
1912 /* OK, we succeeded in creating the temporary symlink, so
1913 * let's rename it */
1914 if (rename(t
, k
) < 0) {
1915 pa_log_error("Failed to rename %s to %s: %s", t
, k
, pa_cstrerror(errno
));
1931 /* Try to open a configuration file. If "env" is specified, open the
1932 * value of the specified environment variable. Otherwise look for a
1933 * file "local" in the home directory or a file "global" in global
1934 * file system. If "result" is non-NULL, a pointer to a newly
1935 * allocated buffer containing the used configuration file is
1937 FILE *pa_open_config_file(const char *global
, const char *local
, const char *env
, char **result
) {
1941 if (env
&& (fn
= getenv(env
))) {
1942 if ((f
= pa_fopen_cloexec(fn
, "r"))) {
1944 *result
= pa_xstrdup(fn
);
1949 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1958 if ((e
= getenv("PULSE_CONFIG_PATH"))) {
1959 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1960 f
= pa_fopen_cloexec(fn
, "r");
1961 } else if ((h
= pa_get_home_dir_malloc())) {
1962 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1963 f
= pa_fopen_cloexec(fn
, "r");
1966 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".config/pulse" PA_PATH_SEP
"%s", h
, local
);
1967 f
= pa_fopen_cloexec(fn
, "r");
1975 *result
= pa_xstrdup(fn
);
1981 if (errno
!= ENOENT
) {
1982 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1994 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
1995 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
1996 pa_win32_get_toplevel(NULL
),
1997 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
2000 gfn
= pa_xstrdup(global
);
2002 if ((f
= pa_fopen_cloexec(gfn
, "r"))) {
2017 char *pa_find_config_file(const char *global
, const char *local
, const char *env
) {
2020 if (env
&& (fn
= getenv(env
))) {
2021 if (access(fn
, R_OK
) == 0)
2022 return pa_xstrdup(fn
);
2024 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2033 if ((e
= getenv("PULSE_CONFIG_PATH")))
2034 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
2035 else if ((h
= pa_get_home_dir_malloc())) {
2036 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
2041 if (access(fn
, R_OK
) == 0) {
2042 char *r
= pa_xstrdup(fn
);
2047 if (errno
!= ENOENT
) {
2048 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2060 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
2061 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
2062 pa_win32_get_toplevel(NULL
),
2063 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
2066 gfn
= pa_xstrdup(global
);
2068 if (access(gfn
, R_OK
) == 0)
2078 /* Format the specified data as a hexademical string */
2079 char *pa_hexstr(const uint8_t* d
, size_t dlength
, char *s
, size_t slength
) {
2080 size_t i
= 0, j
= 0;
2081 const char hex
[] = "0123456789abcdef";
2085 pa_assert(slength
> 0);
2087 while (j
+2 < slength
&& i
< dlength
) {
2088 s
[j
++] = hex
[*d
>> 4];
2089 s
[j
++] = hex
[*d
& 0xF];
2095 s
[j
< slength
? j
: slength
] = 0;
2099 /* Convert a hexadecimal digit to a number or -1 if invalid */
2100 static int hexc(char c
) {
2101 if (c
>= '0' && c
<= '9')
2104 if (c
>= 'A' && c
<= 'F')
2105 return c
- 'A' + 10;
2107 if (c
>= 'a' && c
<= 'f')
2108 return c
- 'a' + 10;
2114 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
2115 size_t pa_parsehex(const char *p
, uint8_t *d
, size_t dlength
) {
2121 while (j
< dlength
&& *p
) {
2124 if ((b
= hexc(*(p
++))) < 0)
2127 d
[j
] = (uint8_t) (b
<< 4);
2132 if ((b
= hexc(*(p
++))) < 0)
2135 d
[j
] |= (uint8_t) b
;
2142 /* Returns nonzero when *s starts with *pfx */
2143 bool pa_startswith(const char *s
, const char *pfx
) {
2151 return strlen(s
) >= l
&& strncmp(s
, pfx
, l
) == 0;
2154 /* Returns nonzero when *s ends with *sfx */
2155 bool pa_endswith(const char *s
, const char *sfx
) {
2164 return l1
>= l2
&& pa_streq(s
+ l1
- l2
, sfx
);
2167 bool pa_is_path_absolute(const char *fn
) {
2173 return strlen(fn
) >= 3 && isalpha(fn
[0]) && fn
[1] == ':' && fn
[2] == '\\';
2177 char *pa_make_path_absolute(const char *p
) {
2183 if (pa_is_path_absolute(p
))
2184 return pa_xstrdup(p
);
2186 if (!(cwd
= pa_getcwd()))
2187 return pa_xstrdup(p
);
2189 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", cwd
, p
);
2194 /* If fn is NULL, return the PulseAudio runtime or state dir (depending on the
2195 * rt parameter). If fn is non-NULL and starts with /, return fn. Otherwise,
2196 * append fn to the runtime/state dir and return it. */
2197 static char *get_path(const char *fn
, bool prependmid
, bool rt
) {
2200 rtp
= rt
? pa_get_runtime_dir() : pa_get_state_dir();
2203 char *r
, *canonical_rtp
;
2205 if (pa_is_path_absolute(fn
)) {
2207 return pa_xstrdup(fn
);
2213 /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
2214 if ((canonical_rtp
= pa_realpath(rtp
))) {
2215 if (strlen(rtp
) >= strlen(canonical_rtp
))
2218 pa_xfree(canonical_rtp
);
2219 canonical_rtp
= rtp
;
2222 canonical_rtp
= rtp
;
2227 if (!(mid
= pa_machine_id())) {
2228 pa_xfree(canonical_rtp
);
2232 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-%s", canonical_rtp
, mid
, fn
);
2235 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", canonical_rtp
, fn
);
2237 pa_xfree(canonical_rtp
);
2243 char *pa_runtime_path(const char *fn
) {
2244 return get_path(fn
, false, true);
2247 char *pa_state_path(const char *fn
, bool appendmid
) {
2248 return get_path(fn
, appendmid
, false);
2251 /* Convert the string s to a signed integer in *ret_i */
2252 int pa_atoi(const char *s
, int32_t *ret_i
) {
2258 if (pa_atol(s
, &l
) < 0)
2261 if ((int32_t) l
!= l
) {
2266 *ret_i
= (int32_t) l
;
2271 /* Convert the string s to an unsigned integer in *ret_u */
2272 int pa_atou(const char *s
, uint32_t *ret_u
) {
2280 l
= strtoul(s
, &x
, 0);
2282 if (!x
|| *x
|| errno
) {
2288 if ((uint32_t) l
!= l
) {
2293 *ret_u
= (uint32_t) l
;
2298 /* Convert the string s to a signed long integer in *ret_l. */
2299 int pa_atol(const char *s
, long *ret_l
) {
2307 l
= strtol(s
, &x
, 0);
2309 if (!x
|| *x
|| errno
) {
2320 #ifdef HAVE_STRTOF_L
2321 static locale_t c_locale
= NULL
;
2323 static void c_locale_destroy(void) {
2324 freelocale(c_locale
);
2328 int pa_atod(const char *s
, double *ret_d
) {
2335 /* This should be locale independent */
2337 #ifdef HAVE_STRTOF_L
2341 if ((c_locale
= newlocale(LC_ALL_MASK
, "C", NULL
)))
2342 atexit(c_locale_destroy
);
2348 f
= strtod_l(s
, &x
, c_locale
);
2356 if (!x
|| *x
|| errno
) {
2367 /* Same as snprintf, but guarantees NUL-termination on every platform */
2368 size_t pa_snprintf(char *str
, size_t size
, const char *format
, ...) {
2373 pa_assert(size
> 0);
2376 va_start(ap
, format
);
2377 ret
= pa_vsnprintf(str
, size
, format
, ap
);
2383 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2384 size_t pa_vsnprintf(char *str
, size_t size
, const char *format
, va_list ap
) {
2388 pa_assert(size
> 0);
2391 ret
= vsnprintf(str
, size
, format
, ap
);
2398 if ((size_t) ret
> size
-1)
2401 return (size_t) ret
;
2404 /* Truncate the specified string, but guarantee that the string
2405 * returned still validates as UTF8 */
2406 char *pa_truncate_utf8(char *c
, size_t l
) {
2408 pa_assert(pa_utf8_valid(c
));
2415 while (l
> 0 && !pa_utf8_valid(c
))
2421 char *pa_getcwd(void) {
2425 char *p
= pa_xmalloc(l
);
2429 if (errno
!= ERANGE
)
2437 void *pa_will_need(const void *p
, size_t l
) {
2438 #ifdef RLIMIT_MEMLOCK
2449 a
= PA_PAGE_ALIGN_PTR(p
);
2450 size
= (size_t) ((const uint8_t*) p
+ l
- (const uint8_t*) a
);
2452 #ifdef HAVE_POSIX_MADVISE
2453 if ((r
= posix_madvise((void*) a
, size
, POSIX_MADV_WILLNEED
)) == 0) {
2454 pa_log_debug("posix_madvise() worked fine!");
2459 /* Most likely the memory was not mmap()ed from a file and thus
2460 * madvise() didn't work, so let's misuse mlock() do page this
2461 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2462 * inviting, the man page of mlock() tells us: "All pages that
2463 * contain a part of the specified address range are guaranteed to
2464 * be resident in RAM when the call returns successfully." */
2466 #ifdef RLIMIT_MEMLOCK
2467 pa_assert_se(getrlimit(RLIMIT_MEMLOCK
, &rlim
) == 0);
2469 if (rlim
.rlim_cur
< PA_PAGE_SIZE
) {
2470 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
));
2475 bs
= PA_PAGE_ALIGN((size_t) rlim
.rlim_cur
);
2477 bs
= PA_PAGE_SIZE
*4;
2480 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r
));
2483 while (size
> 0 && bs
> 0) {
2488 if (mlock(a
, bs
) < 0) {
2489 bs
= PA_PAGE_ALIGN(bs
/ 2);
2493 pa_assert_se(munlock(a
, bs
) == 0);
2495 a
= (const uint8_t*) a
+ bs
;
2501 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno
));
2503 pa_log_debug("mlock() worked fine!");
2508 void pa_close_pipe(int fds
[2]) {
2512 pa_assert_se(pa_close(fds
[0]) == 0);
2515 pa_assert_se(pa_close(fds
[1]) == 0);
2517 fds
[0] = fds
[1] = -1;
2520 char *pa_readlink(const char *p
) {
2521 #ifdef HAVE_READLINK
2530 if ((n
= readlink(p
, c
, l
-1)) < 0) {
2535 if ((size_t) n
< l
-1) {
2548 int pa_close_all(int except_fd
, ...) {
2553 va_start(ap
, except_fd
);
2556 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2561 p
= pa_xnew(int, n
+1);
2563 va_start(ap
, except_fd
);
2566 if (except_fd
>= 0) {
2570 while ((fd
= va_arg(ap
, int)) >= 0)
2577 r
= pa_close_allv(p
);
2583 int pa_close_allv(const int except_fds
[]) {
2592 if ((d
= opendir("/proc/self/fd"))) {
2596 while ((de
= readdir(d
))) {
2602 if (de
->d_name
[0] == '.')
2606 l
= strtol(de
->d_name
, &e
, 10);
2607 if (errno
!= 0 || !e
|| *e
) {
2615 if ((long) fd
!= l
) {
2628 for (i
= 0; except_fds
[i
] >= 0; i
++)
2629 if (except_fds
[i
] == fd
) {
2637 if (pa_close(fd
) < 0) {
2638 saved_errno
= errno
;
2640 errno
= saved_errno
;
2652 if (getrlimit(RLIMIT_NOFILE
, &rl
) >= 0)
2653 maxfd
= (int) rl
.rlim_max
;
2655 maxfd
= sysconf(_SC_OPEN_MAX
);
2657 for (fd
= 3; fd
< maxfd
; fd
++) {
2662 for (i
= 0; except_fds
[i
] >= 0; i
++)
2663 if (except_fds
[i
] == fd
) {
2671 if (pa_close(fd
) < 0 && errno
!= EBADF
)
2674 #endif /* !OS_IS_WIN32 */
2679 int pa_unblock_sigs(int except
, ...) {
2684 va_start(ap
, except
);
2687 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2692 p
= pa_xnew(int, n
+1);
2694 va_start(ap
, except
);
2701 while ((sig
= va_arg(ap
, int)) >= 0)
2708 r
= pa_unblock_sigsv(p
);
2714 int pa_unblock_sigsv(const int except
[]) {
2719 if (sigemptyset(&ss
) < 0)
2722 for (i
= 0; except
[i
] > 0; i
++)
2723 if (sigaddset(&ss
, except
[i
]) < 0)
2726 return sigprocmask(SIG_SETMASK
, &ss
, NULL
);
2732 int pa_reset_sigs(int except
, ...) {
2737 va_start(ap
, except
);
2740 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2745 p
= pa_xnew(int, n
+1);
2747 va_start(ap
, except
);
2754 while ((sig
= va_arg(ap
, int)) >= 0)
2761 r
= pa_reset_sigsv(p
);
2767 int pa_reset_sigsv(const int except
[]) {
2771 for (sig
= 1; sig
< NSIG
; sig
++) {
2783 for (i
= 0; except
[i
] > 0; i
++) {
2784 if (sig
== except
[i
]) {
2793 struct sigaction sa
;
2795 memset(&sa
, 0, sizeof(sa
));
2796 sa
.sa_handler
= SIG_DFL
;
2798 /* On Linux the first two RT signals are reserved by
2799 * glibc, and sigaction() will return EINVAL for them. */
2800 if ((sigaction(sig
, &sa
, NULL
) < 0))
2801 if (errno
!= EINVAL
)
2810 void pa_set_env(const char *key
, const char *value
) {
2814 /* This is not thread-safe */
2817 SetEnvironmentVariable(key
, value
);
2819 setenv(key
, value
, 1);
2823 void pa_set_env_and_record(const char *key
, const char *value
) {
2827 /* This is not thread-safe */
2829 pa_set_env(key
, value
);
2830 recorded_env
= pa_strlist_prepend(recorded_env
, key
);
2833 void pa_unset_env_recorded(void) {
2835 /* This is not thread-safe */
2840 recorded_env
= pa_strlist_pop(recorded_env
, &s
);
2846 SetEnvironmentVariable(s
, NULL
);
2854 bool pa_in_system_mode(void) {
2857 if (!(e
= getenv("PULSE_SYSTEM")))
2863 /* Checks a whitespace-separated list of words in haystack for needle */
2864 bool pa_str_in_list_spaces(const char *haystack
, const char *needle
) {
2866 const char *state
= NULL
;
2868 if (!haystack
|| !needle
)
2871 while ((s
= pa_split_spaces(haystack
, &state
))) {
2872 if (pa_streq(needle
, s
)) {
2883 char *pa_get_user_name_malloc(void) {
2887 #ifdef _SC_LOGIN_NAME_MAX
2888 k
= (ssize_t
) sysconf(_SC_LOGIN_NAME_MAX
);
2894 u
= pa_xnew(char, k
+1);
2896 if (!(pa_get_user_name(u
, k
))) {
2904 char *pa_get_host_name_malloc(void) {
2913 if (!pa_get_host_name(c
, l
)) {
2915 if (errno
!= EINVAL
&& errno
!= ENAMETOOLONG
)
2918 } else if (strlen(c
) < l
-1) {
2926 u
= pa_utf8_filter(c
);
2931 /* Hmm, the hostname is as long the space we offered the
2932 * function, we cannot know if it fully fit in, so let's play
2933 * safe and retry. */
2942 char *pa_machine_id(void) {
2946 /* The returned value is supposed be some kind of ascii identifier
2947 * that is unique and stable across reboots. */
2949 /* First we try the /etc/machine-id, which is the best option we
2950 * have, since it fits perfectly our needs and is not as volatile
2951 * as the hostname which might be set from dhcp. */
2953 if ((f
= pa_fopen_cloexec(PA_MACHINE_ID
, "r")) ||
2954 (f
= pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK
, "r"))) {
2955 char ln
[34] = "", *r
;
2957 r
= fgets(ln
, sizeof(ln
)-1, f
);
2963 return pa_utf8_filter(ln
);
2966 if ((h
= pa_get_host_name_malloc()))
2969 #if !defined(OS_IS_WIN32) && !defined(__ANDROID__)
2970 /* If no hostname was set we use the POSIX hostid. It's usually
2971 * the IPv4 address. Might not be that stable. */
2972 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
2978 char *pa_session_id(void) {
2981 e
= getenv("XDG_SESSION_ID");
2985 return pa_utf8_filter(e
);
2988 char *pa_uname_string(void) {
2992 pa_assert_se(uname(&u
) >= 0);
2994 return pa_sprintf_malloc("%s %s %s %s", u
.sysname
, u
.machine
, u
.release
, u
.version
);
3000 i
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
3001 pa_assert_se(GetVersionEx(&i
));
3003 return pa_sprintf_malloc("Windows %d.%d (%d) %s", i
.dwMajorVersion
, i
.dwMinorVersion
, i
.dwBuildNumber
, i
.szCSDVersion
);
3007 #ifdef HAVE_VALGRIND_MEMCHECK_H
3008 bool pa_in_valgrind(void) {
3011 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
3012 * here instead of really checking whether we run in valgrind or
3016 b
= getenv("VALGRIND") ? 2 : 1;
3022 unsigned pa_gcd(unsigned a
, unsigned b
) {
3033 void pa_reduce(unsigned *num
, unsigned *den
) {
3035 unsigned gcd
= pa_gcd(*num
, *den
);
3043 pa_assert(pa_gcd(*num
, *den
) == 1);
3046 unsigned pa_ncpus(void) {
3049 #ifdef _SC_NPROCESSORS_CONF
3050 ncpus
= sysconf(_SC_NPROCESSORS_CONF
);
3055 return ncpus
<= 0 ? 1 : (unsigned) ncpus
;
3058 char *pa_replace(const char*s
, const char*a
, const char *b
) {
3067 sb
= pa_strbuf_new();
3072 if (!(p
= strstr(s
, a
)))
3075 pa_strbuf_putsn(sb
, s
, p
-s
);
3076 pa_strbuf_puts(sb
, b
);
3080 pa_strbuf_puts(sb
, s
);
3082 return pa_strbuf_tostring_free(sb
);
3085 char *pa_escape(const char *p
, const char *chars
) {
3088 pa_strbuf
*buf
= pa_strbuf_new();
3090 for (s
= p
; *s
; ++s
) {
3092 pa_strbuf_putc(buf
, '\\');
3094 for (c
= chars
; *c
; ++c
) {
3096 pa_strbuf_putc(buf
, '\\');
3101 pa_strbuf_putc(buf
, *s
);
3104 return pa_strbuf_tostring_free(buf
);
3107 char *pa_unescape(char *p
) {
3109 bool escaped
= false;
3111 for (s
= p
, d
= p
; *s
; s
++) {
3112 if (!escaped
&& *s
== '\\') {
3126 char *pa_realpath(const char *path
) {
3130 /* We want only absolute paths */
3131 if (path
[0] != '/') {
3136 #if defined(__GLIBC__)
3140 if (!(r
= realpath(path
, NULL
)))
3143 /* We copy this here in case our pa_xmalloc() is not
3144 * implemented on top of libc malloc() */
3148 #elif defined(PATH_MAX)
3151 path_buf
= pa_xmalloc(PATH_MAX
);
3153 #if defined(OS_IS_WIN32)
3154 if (!(t
= _fullpath(path_buf
, path
, _MAX_PATH
))) {
3159 if (!(t
= realpath(path
, path_buf
))) {
3166 #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."
3172 void pa_disable_sigpipe(void) {
3175 struct sigaction sa
;
3179 if (sigaction(SIGPIPE
, NULL
, &sa
) < 0) {
3180 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3184 sa
.sa_handler
= SIG_IGN
;
3186 if (sigaction(SIGPIPE
, &sa
, NULL
) < 0) {
3187 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3193 void pa_xfreev(void**a
) {
3199 for (p
= a
; *p
; p
++)
3205 char **pa_split_spaces_strv(const char *s
) {
3207 unsigned i
= 0, n
= 8;
3208 const char *state
= NULL
;
3210 t
= pa_xnew(char*, n
);
3211 while ((e
= pa_split_spaces(s
, &state
))) {
3216 t
= pa_xrenew(char*, t
, n
);
3229 char* pa_maybe_prefix_path(const char *path
, const char *prefix
) {
3232 if (pa_is_path_absolute(path
))
3233 return pa_xstrdup(path
);
3235 return pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", prefix
, path
);
3238 size_t pa_pipe_buf(int fd
) {
3243 if ((n
= fpathconf(fd
, _PC_PIPE_BUF
)) >= 0)
3254 void pa_reset_personality(void) {
3256 #if defined(__linux__) && !defined(__ANDROID__)
3257 if (personality(PER_LINUX
) < 0)
3258 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno
));
3263 bool pa_run_from_build_tree(void) {
3265 static bool b
= false;
3268 if ((rp
= pa_readlink("/proc/self/exe"))) {
3269 b
= pa_startswith(rp
, PA_BUILDDIR
);
3277 const char *pa_get_temp_dir(void) {
3280 if ((t
= getenv("TMPDIR")) &&
3281 pa_is_path_absolute(t
))
3284 if ((t
= getenv("TMP")) &&
3285 pa_is_path_absolute(t
))
3288 if ((t
= getenv("TEMP")) &&
3289 pa_is_path_absolute(t
))
3292 if ((t
= getenv("TEMPDIR")) &&
3293 pa_is_path_absolute(t
))
3299 int pa_open_cloexec(const char *fn
, int flags
, mode_t mode
) {
3307 if ((fd
= open(fn
, flags
|O_CLOEXEC
, mode
)) >= 0)
3310 if (errno
!= EINVAL
)
3314 if ((fd
= open(fn
, flags
, mode
)) < 0)
3318 /* Some implementations might simply ignore O_CLOEXEC if it is not
3319 * understood, make sure FD_CLOEXEC is enabled anyway */
3321 pa_make_fd_cloexec(fd
);
3325 int pa_socket_cloexec(int domain
, int type
, int protocol
) {
3329 if ((fd
= socket(domain
, type
| SOCK_CLOEXEC
, protocol
)) >= 0)
3332 if (errno
!= EINVAL
)
3336 if ((fd
= socket(domain
, type
, protocol
)) < 0)
3340 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3341 * not understood, make sure FD_CLOEXEC is enabled anyway */
3343 pa_make_fd_cloexec(fd
);
3347 int pa_pipe_cloexec(int pipefd
[2]) {
3351 if ((r
= pipe2(pipefd
, O_CLOEXEC
)) >= 0)
3354 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3359 if ((r
= pipe(pipefd
)) < 0)
3363 pa_make_fd_cloexec(pipefd
[0]);
3364 pa_make_fd_cloexec(pipefd
[1]);
3369 int pa_accept_cloexec(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
) {
3373 if ((fd
= accept4(sockfd
, addr
, addrlen
, SOCK_CLOEXEC
)) >= 0)
3376 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3381 if ((fd
= accept(sockfd
, addr
, addrlen
)) < 0)
3385 pa_make_fd_cloexec(fd
);
3389 FILE* pa_fopen_cloexec(const char *path
, const char *mode
) {
3393 m
= pa_sprintf_malloc("%se", mode
);
3396 if ((f
= fopen(path
, m
))) {
3403 if (errno
!= EINVAL
)
3406 if (!(f
= fopen(path
, mode
)))
3410 pa_make_fd_cloexec(fileno(f
));
3414 void pa_nullify_stdfds(void) {
3417 pa_close(STDIN_FILENO
);
3418 pa_close(STDOUT_FILENO
);
3419 pa_close(STDERR_FILENO
);
3421 pa_assert_se(open("/dev/null", O_RDONLY
) == STDIN_FILENO
);
3422 pa_assert_se(open("/dev/null", O_WRONLY
) == STDOUT_FILENO
);
3423 pa_assert_se(open("/dev/null", O_WRONLY
) == STDERR_FILENO
);
3430 char *pa_read_line_from_file(const char *fn
) {
3432 char ln
[256] = "", *r
;
3434 if (!(f
= pa_fopen_cloexec(fn
, "r")))
3437 r
= fgets(ln
, sizeof(ln
)-1, f
);
3446 return pa_xstrdup(ln
);
3449 bool pa_running_in_vm(void) {
3451 #if defined(__i386__) || defined(__x86_64__)
3453 /* Both CPUID and DMI are x86 specific interfaces... */
3455 uint32_t eax
= 0x40000000;
3462 const char *const dmi_vendors
[] = {
3463 "/sys/class/dmi/id/sys_vendor",
3464 "/sys/class/dmi/id/board_vendor",
3465 "/sys/class/dmi/id/bios_vendor"
3470 for (i
= 0; i
< PA_ELEMENTSOF(dmi_vendors
); i
++) {
3473 if ((s
= pa_read_line_from_file(dmi_vendors
[i
]))) {
3475 if (pa_startswith(s
, "QEMU") ||
3476 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3477 pa_startswith(s
, "VMware") ||
3478 pa_startswith(s
, "VMW") ||
3479 pa_startswith(s
, "Microsoft Corporation") ||
3480 pa_startswith(s
, "innotek GmbH") ||
3481 pa_startswith(s
, "Xen")) {
3493 /* http://lwn.net/Articles/301888/ */
3496 __asm__
__volatile__ (
3497 /* ebx/rbx is being used for PIC! */
3498 " push %%"PA_REG_b
" \n\t"
3500 " mov %%ebx, %1 \n\t"
3501 " pop %%"PA_REG_b
" \n\t"
3503 : "=a" (eax
), "=r" (sig
.sig32
[0]), "=c" (sig
.sig32
[1]), "=d" (sig
.sig32
[2])
3507 if (pa_streq(sig
.text
, "XenVMMXenVMM") ||
3508 pa_streq(sig
.text
, "KVMKVMKVM") ||
3509 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3510 pa_streq(sig
.text
, "VMwareVMware") ||
3511 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3512 pa_streq(sig
.text
, "Microsoft Hv"))