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
;
159 /* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
160 char *pa_win32_get_toplevel(HANDLE handle
) {
161 static char *toplevel
= NULL
;
164 char library_path
[MAX_PATH
];
167 if (!GetModuleFileName(handle
, library_path
, MAX_PATH
))
170 toplevel
= pa_xstrdup(library_path
);
172 p
= strrchr(toplevel
, PA_PATH_SEP_CHAR
);
176 p
= strrchr(toplevel
, PA_PATH_SEP_CHAR
);
177 if (p
&& pa_streq(p
+ 1, "bin"))
186 static void set_nonblock(int fd
, bool nonblock
) {
192 pa_assert_se((v
= fcntl(fd
, F_GETFL
)) >= 0);
197 nv
= v
& ~O_NONBLOCK
;
200 pa_assert_se(fcntl(fd
, F_SETFL
, v
|O_NONBLOCK
) >= 0);
202 #elif defined(OS_IS_WIN32)
210 if (ioctlsocket(fd
, FIONBIO
, &arg
) < 0) {
211 pa_assert_se(WSAGetLastError() == WSAENOTSOCK
);
212 pa_log_warn("Only sockets can be made non-blocking!");
216 /* There is no method to query status, so we remember all fds */
218 FD_SET(fd
, &nonblocking_fds
);
220 FD_CLR(fd
, &nonblocking_fds
);
222 pa_log_warn("Non-blocking I/O not supported.!");
227 /** Make a file descriptor nonblock. Doesn't do any error checking */
228 void pa_make_fd_nonblock(int fd
) {
229 set_nonblock(fd
, true);
232 /** Make a file descriptor blocking. Doesn't do any error checking */
233 void pa_make_fd_block(int fd
) {
234 set_nonblock(fd
, false);
237 /** Query if a file descriptor is non-blocking */
238 bool pa_is_fd_nonblock(int fd
) {
244 pa_assert_se((v
= fcntl(fd
, F_GETFL
)) >= 0);
246 return !!(v
& O_NONBLOCK
);
248 #elif defined(OS_IS_WIN32)
249 return !!FD_ISSET(fd
, &nonblocking_fds
);
256 /* Set the FD_CLOEXEC flag for a fd */
257 void pa_make_fd_cloexec(int fd
) {
263 pa_assert_se((v
= fcntl(fd
, F_GETFD
, 0)) >= 0);
265 if (!(v
& FD_CLOEXEC
))
266 pa_assert_se(fcntl(fd
, F_SETFD
, v
|FD_CLOEXEC
) >= 0);
271 /** Creates a directory securely. Will create parent directories recursively if
272 * required. This will not update permissions on parent directories if they
273 * already exist, however. */
274 int pa_make_secure_dir(const char* dir
, mode_t m
, uid_t uid
, gid_t gid
, bool update_perms
) {
287 u
= umask((~m
) & 0777);
293 if (r
< 0 && errno
== ENOENT
&& retry
) {
294 /* If a parent directory in the path doesn't exist, try to create that
295 * first, then try again. */
296 pa_make_secure_parent_dir(dir
, m
, uid
, gid
, false);
301 if (r
< 0 && errno
!= EEXIST
)
304 #if defined(HAVE_FSTAT) && !defined(OS_IS_WIN32)
320 if (fstat(fd
, &st
) < 0) {
321 pa_assert_se(pa_close(fd
) >= 0);
325 if (!S_ISDIR(st
.st_mode
)) {
326 pa_assert_se(pa_close(fd
) >= 0);
335 if (uid
== (uid_t
) -1)
337 if (gid
== (gid_t
) -1)
339 if (fchown(fd
, uid
, gid
) < 0)
344 (void) fchmod(fd
, m
);
347 pa_assert_se(pa_close(fd
) >= 0);
352 if (lstat(dir
, &st
) < 0)
354 if (stat(dir
, &st
) < 0)
359 if (!S_ISDIR(st
.st_mode
) ||
360 (st
.st_uid
!= uid
) ||
361 (st
.st_gid
!= gid
) ||
362 ((st
.st_mode
& 0777) != m
)) {
367 pa_log_warn("Secure directory creation not supported on Win32.");
380 /* Return a newly allocated sting containing the parent directory of the specified file */
381 char *pa_parent_dir(const char *fn
) {
382 char *slash
, *dir
= pa_xstrdup(fn
);
384 if ((slash
= (char*) pa_path_get_filename(dir
)) == dir
) {
394 /* Creates a the parent directory of the specified path securely */
395 int pa_make_secure_parent_dir(const char *fn
, mode_t m
, uid_t uid
, gid_t gid
, bool update_perms
) {
399 if (!(dir
= pa_parent_dir(fn
)))
402 if (pa_make_secure_dir(dir
, m
, uid
, gid
, update_perms
) < 0)
412 /** Platform independent read function. Necessary since not all
413 * systems treat all file descriptors equal. If type is
414 * non-NULL it is used to cache the type of the fd. This is
415 * useful for making sure that only a single syscall is executed per
416 * function call. The variable pointed to should be initialized to 0
418 ssize_t
pa_read(int fd
, void *buf
, size_t count
, int *type
) {
422 if (!type
|| *type
== 0) {
427 if ((r
= recv(fd
, buf
, count
, 0)) >= 0)
430 err
= WSAGetLastError();
431 if (err
!= WSAENOTSOCK
) {
432 /* transparently handle non-blocking sockets, by waiting
434 if (err
== WSAEWOULDBLOCK
) {
438 if (pa_poll(&pfd
, 1, -1) >= 0) {
455 if ((r
= read(fd
, buf
, count
)) < 0)
463 /** Similar to pa_read(), but handles writes */
464 ssize_t
pa_write(int fd
, const void *buf
, size_t count
, int *type
) {
466 if (!type
|| *type
== 0) {
474 if ((r
= send(fd
, buf
, count
, MSG_NOSIGNAL
)) < 0) {
486 err
= WSAGetLastError();
487 if (err
!= WSAENOTSOCK
) {
488 /* transparently handle non-blocking sockets, by waiting
490 if (err
== WSAEWOULDBLOCK
) {
493 pfd
.events
= POLLOUT
;
494 if (pa_poll(&pfd
, 1, -1) >= 0) {
502 if (errno
!= ENOTSOCK
)
513 if ((r
= write(fd
, buf
, count
)) < 0)
521 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
522 * unless EOF is reached or an error occurred */
523 ssize_t
pa_loop_read(int fd
, void*data
, size_t size
, int *type
) {
539 if ((r
= pa_read(fd
, data
, size
, type
)) < 0)
546 data
= (uint8_t*) data
+ r
;
553 /** Similar to pa_loop_read(), but wraps write() */
554 ssize_t
pa_loop_write(int fd
, const void*data
, size_t size
, int *type
) {
570 if ((r
= pa_write(fd
, data
, size
, type
)) < 0)
577 data
= (const uint8_t*) data
+ r
;
584 /** Platform independent close function. Necessary since not all
585 * systems treat all file descriptors equal. */
586 int pa_close(int fd
) {
591 FD_CLR(fd
, &nonblocking_fds
);
593 if ((ret
= closesocket(fd
)) == 0)
596 if (WSAGetLastError() != WSAENOTSOCK
) {
597 errno
= WSAGetLastError();
605 if ((r
= close(fd
)) < 0)
613 /* Print a warning messages in case that the given signal is not
614 * blocked or trapped */
615 void pa_check_signal_is_blocked(int sig
) {
616 #ifdef HAVE_SIGACTION
620 /* If POSIX threads are supported use thread-aware
621 * pthread_sigmask() function, to check if the signal is
622 * blocked. Otherwise fall back to sigprocmask() */
625 if (pthread_sigmask(SIG_SETMASK
, NULL
, &set
) < 0) {
627 if (sigprocmask(SIG_SETMASK
, NULL
, &set
) < 0) {
628 pa_log("sigprocmask(): %s", pa_cstrerror(errno
));
635 if (sigismember(&set
, sig
))
638 /* Check whether the signal is trapped */
640 if (sigaction(sig
, NULL
, &sa
) < 0) {
641 pa_log("sigaction(): %s", pa_cstrerror(errno
));
645 if (sa
.sa_handler
!= SIG_DFL
)
648 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig
));
649 #else /* HAVE_SIGACTION */
650 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig
));
654 /* The following function is based on an example from the GNU libc
655 * documentation. This function is similar to GNU's asprintf(). */
656 char *pa_sprintf_malloc(const char *format
, ...) {
666 c
= pa_xrealloc(c
, size
);
668 va_start(ap
, format
);
669 r
= vsnprintf(c
, size
, format
, ap
);
674 if (r
> -1 && (size_t) r
< size
)
677 if (r
> -1) /* glibc 2.1 */
684 /* Same as the previous function, but use a va_list instead of an
686 char *pa_vsprintf_malloc(const char *format
, va_list ap
) {
696 c
= pa_xrealloc(c
, size
);
699 r
= vsnprintf(c
, size
, format
, aq
);
704 if (r
> -1 && (size_t) r
< size
)
707 if (r
> -1) /* glibc 2.1 */
714 /* Similar to OpenBSD's strlcpy() function */
715 char *pa_strlcpy(char *b
, const char *s
, size_t l
) {
733 #ifdef _POSIX_PRIORITY_SCHEDULING
734 static int set_scheduler(int rtprio
) {
736 struct sched_param sp
;
740 #ifdef HAVE_SYS_RESOURCE_H
746 dbus_error_init(&error
);
750 sp
.sched_priority
= rtprio
;
752 #ifdef SCHED_RESET_ON_FORK
753 if (pthread_setschedparam(pthread_self(), SCHED_RR
|SCHED_RESET_ON_FORK
, &sp
) == 0) {
754 pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
759 if (pthread_setschedparam(pthread_self(), SCHED_RR
, &sp
) == 0) {
760 pa_log_debug("SCHED_RR worked.");
763 #endif /* HAVE_SCHED_H */
766 /* Try to talk to RealtimeKit */
768 if (!(bus
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
))) {
769 pa_log("Failed to connect to system bus: %s\n", error
.message
);
770 dbus_error_free(&error
);
775 /* We need to disable exit on disconnect because otherwise
776 * dbus_shutdown will kill us. See
777 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
778 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
780 rttime
= rtkit_get_rttime_usec_max(bus
);
782 #ifdef HAVE_SYS_RESOURCE_H
783 r
= getrlimit(RLIMIT_RTTIME
, &rl
);
785 if (r
>= 0 && (long long) rl
.rlim_max
> rttime
) {
786 pa_log_info("Clamping rlimit-rttime to %lld for RealtimeKit\n", rttime
);
787 rl
.rlim_cur
= rl
.rlim_max
= rttime
;
788 r
= setrlimit(RLIMIT_RTTIME
, &rl
);
791 pa_log("setrlimit() failed: %s", pa_cstrerror(errno
));
794 r
= rtkit_make_realtime(bus
, 0, rtprio
);
795 dbus_connection_close(bus
);
796 dbus_connection_unref(bus
);
799 pa_log_debug("RealtimeKit worked.");
805 dbus_connection_close(bus
);
806 dbus_connection_unref(bus
);
818 /* Make the current thread a realtime thread, and acquire the highest
819 * rtprio we can get that is less or equal the specified parameter. If
820 * the thread is already realtime, don't do anything. */
821 int pa_make_realtime(int rtprio
) {
823 #if defined(OS_IS_DARWIN)
824 struct thread_time_constraint_policy ttcpolicy
;
826 size_t size
= sizeof(freq
);
829 ret
= sysctlbyname("hw.cpufrequency", &freq
, &size
, NULL
, 0);
831 pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
835 pa_log_debug("sysctl for hw.cpufrequency: %llu", freq
);
837 /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
838 ttcpolicy
.period
= freq
/ 160;
839 ttcpolicy
.computation
= freq
/ 3300;
840 ttcpolicy
.constraint
= freq
/ 2200;
841 ttcpolicy
.preemptible
= 1;
843 ret
= thread_policy_set(mach_thread_self(),
844 THREAD_TIME_CONSTRAINT_POLICY
,
845 (thread_policy_t
) &ttcpolicy
,
846 THREAD_TIME_CONSTRAINT_POLICY_COUNT
);
848 pa_log_info("Unable to set real-time thread priority (%08x).", ret
);
852 pa_log_info("Successfully acquired real-time thread priority.");
855 #elif defined(_POSIX_PRIORITY_SCHEDULING)
858 if (set_scheduler(rtprio
) >= 0) {
859 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio
);
863 for (p
= rtprio
-1; p
>= 1; p
--)
864 if (set_scheduler(p
) >= 0) {
865 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p
, rtprio
);
868 #elif defined(OS_IS_WIN32)
869 /* Windows only allows realtime scheduling to be set on a per process basis.
870 * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
871 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL
)) {
872 pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
876 pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
881 pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno
));
885 #ifdef HAVE_SYS_RESOURCE_H
886 static int set_nice(int nice_level
) {
892 dbus_error_init(&error
);
895 #ifdef HAVE_SYS_RESOURCE_H
896 if (setpriority(PRIO_PROCESS
, 0, nice_level
) >= 0) {
897 pa_log_debug("setpriority() worked.");
903 /* Try to talk to RealtimeKit */
905 if (!(bus
= dbus_bus_get(DBUS_BUS_SYSTEM
, &error
))) {
906 pa_log("Failed to connect to system bus: %s\n", error
.message
);
907 dbus_error_free(&error
);
912 /* We need to disable exit on disconnect because otherwise
913 * dbus_shutdown will kill us. See
914 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
915 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
917 r
= rtkit_make_high_priority(bus
, 0, nice_level
);
918 dbus_connection_unref(bus
);
921 pa_log_debug("RealtimeKit worked.");
932 /* Raise the priority of the current process as much as possible that
933 * is <= the specified nice level..*/
934 int pa_raise_priority(int nice_level
) {
936 #ifdef HAVE_SYS_RESOURCE_H
939 if (set_nice(nice_level
) >= 0) {
940 pa_log_info("Successfully gained nice level %i.", nice_level
);
944 for (n
= nice_level
+1; n
< 0; n
++)
945 if (set_nice(n
) >= 0) {
946 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n
, nice_level
);
950 pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno
));
955 if (nice_level
< 0) {
956 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS
)) {
957 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
962 pa_log_info("Successfully gained high priority class.");
969 /* Reset the priority to normal, inverting the changes made by
970 * pa_raise_priority() and pa_make_realtime()*/
971 void pa_reset_priority(void) {
972 #ifdef HAVE_SYS_RESOURCE_H
973 struct sched_param sp
;
975 setpriority(PRIO_PROCESS
, 0, 0);
978 pthread_setschedparam(pthread_self(), SCHED_OTHER
, &sp
);
982 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS
);
986 int pa_match(const char *expr
, const char *v
) {
991 if (regcomp(&re
, expr
, REG_NOSUB
|REG_EXTENDED
) != 0) {
996 if ((k
= regexec(&re
, v
, 0, NULL
, 0)) == 0)
998 else if (k
== REG_NOMATCH
)
1011 /* Try to parse a boolean string value.*/
1012 int pa_parse_boolean(const char *v
) {
1015 /* First we check language independent */
1016 if (pa_streq(v
, "1") || !strcasecmp(v
, "y") || !strcasecmp(v
, "t")
1017 || !strcasecmp(v
, "yes") || !strcasecmp(v
, "true") || !strcasecmp(v
, "on"))
1019 else if (pa_streq(v
, "0") || !strcasecmp(v
, "n") || !strcasecmp(v
, "f")
1020 || !strcasecmp(v
, "no") || !strcasecmp(v
, "false") || !strcasecmp(v
, "off"))
1023 #ifdef HAVE_LANGINFO_H
1026 /* And then we check language dependent */
1027 if ((expr
= nl_langinfo(YESEXPR
)))
1029 if (pa_match(expr
, v
) > 0)
1032 if ((expr
= nl_langinfo(NOEXPR
)))
1034 if (pa_match(expr
, v
) > 0)
1043 /* Try to parse a volume string to pa_volume_t. The allowed formats are:
1044 * db, % and unsigned integer */
1045 int pa_parse_volume(const char *v
, pa_volume_t
*volume
) {
1059 memcpy(str
, v
, len
+ 1);
1061 if (str
[len
- 1] == '%') {
1062 str
[len
- 1] = '\0';
1063 if (pa_atou(str
, &i
) == 0) {
1064 *volume
= PA_CLAMP_VOLUME((uint64_t) PA_VOLUME_NORM
* i
/ 100);
1067 } else if (len
> 2 && (str
[len
- 1] == 'b' || str
[len
- 1] == 'B') &&
1068 (str
[len
- 2] == 'd' || str
[len
- 2] == 'D')) {
1069 str
[len
- 2] = '\0';
1070 if (pa_atod(str
, &d
) == 0) {
1071 *volume
= pa_sw_volume_from_dB(d
);
1075 if (pa_atou(v
, &i
) == 0) {
1076 *volume
= PA_CLAMP_VOLUME(i
);
1085 /* Split the specified string wherever one of the strings in delimiter
1086 * occurs. Each time it is called returns a newly allocated string
1087 * with pa_xmalloc(). The variable state points to, should be
1088 * initialized to NULL before the first call. */
1089 char *pa_split(const char *c
, const char *delimiter
, const char**state
) {
1090 const char *current
= *state
? *state
: c
;
1096 l
= strcspn(current
, delimiter
);
1102 return pa_xstrndup(current
, l
);
1105 /* Split the specified string wherever one of the strings in delimiter
1106 * occurs. Each time it is called returns a pointer to the substring within the
1107 * string and the length in 'n'. Note that the resultant string cannot be used
1108 * as-is without the length parameter, since it is merely pointing to a point
1109 * within the original string. The variable state points to, should be
1110 * initialized to NULL before the first call. */
1111 const char *pa_split_in_place(const char *c
, const char *delimiter
, int *n
, const char**state
) {
1112 const char *current
= *state
? *state
: c
;
1118 l
= strcspn(current
, delimiter
);
1128 /* Split a string into words. Otherwise similar to pa_split(). */
1129 char *pa_split_spaces(const char *c
, const char **state
) {
1130 const char *current
= *state
? *state
: c
;
1133 if (!*current
|| *c
== 0)
1136 current
+= strspn(current
, WHITESPACE
);
1137 l
= strcspn(current
, WHITESPACE
);
1141 return pa_xstrndup(current
, l
);
1144 PA_STATIC_TLS_DECLARE(signame
, pa_xfree
);
1146 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
1147 const char *pa_sig2str(int sig
) {
1160 char buf
[SIG2STR_MAX
];
1162 if (sig2str(sig
, buf
) == 0) {
1163 pa_xfree(PA_STATIC_TLS_GET(signame
));
1164 t
= pa_sprintf_malloc("SIG%s", buf
);
1165 PA_STATIC_TLS_SET(signame
, t
);
1173 case SIGHUP
: return "SIGHUP";
1175 case SIGINT
: return "SIGINT";
1177 case SIGQUIT
: return "SIGQUIT";
1179 case SIGILL
: return "SIGULL";
1181 case SIGTRAP
: return "SIGTRAP";
1183 case SIGABRT
: return "SIGABRT";
1185 case SIGBUS
: return "SIGBUS";
1187 case SIGFPE
: return "SIGFPE";
1189 case SIGKILL
: return "SIGKILL";
1192 case SIGUSR1
: return "SIGUSR1";
1194 case SIGSEGV
: return "SIGSEGV";
1196 case SIGUSR2
: return "SIGUSR2";
1199 case SIGPIPE
: return "SIGPIPE";
1202 case SIGALRM
: return "SIGALRM";
1204 case SIGTERM
: return "SIGTERM";
1206 case SIGSTKFLT
: return "SIGSTKFLT";
1209 case SIGCHLD
: return "SIGCHLD";
1212 case SIGCONT
: return "SIGCONT";
1215 case SIGSTOP
: return "SIGSTOP";
1218 case SIGTSTP
: return "SIGTSTP";
1221 case SIGTTIN
: return "SIGTTIN";
1224 case SIGTTOU
: return "SIGTTOU";
1227 case SIGURG
: return "SIGURG";
1230 case SIGXCPU
: return "SIGXCPU";
1233 case SIGXFSZ
: return "SIGXFSZ";
1236 case SIGVTALRM
: return "SIGVTALRM";
1239 case SIGPROF
: return "SIGPROF";
1242 case SIGWINCH
: return "SIGWINCH";
1245 case SIGIO
: return "SIGIO";
1248 case SIGPWR
: return "SIGPWR";
1251 case SIGSYS
: return "SIGSYS";
1256 if (sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
1257 pa_xfree(PA_STATIC_TLS_GET(signame
));
1258 t
= pa_sprintf_malloc("SIGRTMIN+%i", sig
- SIGRTMIN
);
1259 PA_STATIC_TLS_SET(signame
, t
);
1268 pa_xfree(PA_STATIC_TLS_GET(signame
));
1269 t
= pa_sprintf_malloc("SIG%i", sig
);
1270 PA_STATIC_TLS_SET(signame
, t
);
1276 /* Check whether the specified GID and the group name match */
1277 static int is_group(gid_t gid
, const char *name
) {
1278 struct group
*group
= NULL
;
1282 if (!(group
= pa_getgrgid_malloc(gid
))) {
1286 pa_log("pa_getgrgid_malloc(%u): %s", gid
, pa_cstrerror(errno
));
1291 r
= pa_streq(name
, group
->gr_name
);
1294 pa_getgrgid_free(group
);
1299 /* Check the current user is member of the specified group */
1300 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1301 GETGROUPS_T
*gids
, tgid
;
1302 long n
= sysconf(_SC_NGROUPS_MAX
);
1307 gids
= pa_xmalloc(sizeof(GETGROUPS_T
) * (size_t) n
);
1309 if ((n
= getgroups((int) n
, gids
)) < 0) {
1310 pa_log("getgroups(): %s", pa_cstrerror(errno
));
1314 for (i
= 0; i
< n
; i
++) {
1316 if ((k
= is_group(gids
[i
], name
)) < 0)
1325 if ((k
= is_group(tgid
= getgid(), name
)) < 0)
1341 /* Check whether the specific user id is a member of the specified group */
1342 int pa_uid_in_group(uid_t uid
, const char *name
) {
1343 struct group
*group
= NULL
;
1348 if (!(group
= pa_getgrnam_malloc(name
))) {
1355 for (i
= group
->gr_mem
; *i
; i
++) {
1356 struct passwd
*pw
= NULL
;
1359 if (!(pw
= pa_getpwnam_malloc(*i
)))
1362 if (pw
->pw_uid
== uid
)
1365 pa_getpwnam_free(pw
);
1372 pa_getgrnam_free(group
);
1377 /* Get the GID of a given group, return (gid_t) -1 on failure. */
1378 gid_t
pa_get_gid_of_group(const char *name
) {
1379 gid_t ret
= (gid_t
) -1;
1380 struct group
*gr
= NULL
;
1383 if (!(gr
= pa_getgrnam_malloc(name
))) {
1392 pa_getgrnam_free(gr
);
1396 int pa_check_in_group(gid_t g
) {
1397 gid_t gids
[NGROUPS_MAX
];
1400 if ((r
= getgroups(NGROUPS_MAX
, gids
)) < 0)
1410 #else /* HAVE_GRP_H */
1412 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1418 int pa_uid_in_group(uid_t uid
, const char *name
) {
1423 gid_t
pa_get_gid_of_group(const char *name
) {
1428 int pa_check_in_group(gid_t g
) {
1435 /* Lock or unlock a file entirely.
1436 (advisory on UNIX, mandatory on Windows) */
1437 int pa_lock_fd(int fd
, int b
) {
1439 struct flock f_lock
;
1441 /* Try a R/W lock first */
1443 f_lock
.l_type
= (short) (b
? F_WRLCK
: F_UNLCK
);
1444 f_lock
.l_whence
= SEEK_SET
;
1448 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1451 /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
1452 if (b
&& errno
== EBADF
) {
1453 f_lock
.l_type
= F_RDLCK
;
1454 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1458 pa_log("%slock: %s", !b
? "un" : "", pa_cstrerror(errno
));
1462 HANDLE h
= (HANDLE
) _get_osfhandle(fd
);
1464 if (b
&& LockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1466 if (!b
&& UnlockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1469 pa_log("%slock failed: 0x%08X", !b
? "un" : "", GetLastError());
1471 /* FIXME: Needs to set errno! */
1477 /* Remove trailing newlines from a string */
1478 char* pa_strip_nl(char *s
) {
1481 s
[strcspn(s
, NEWLINE
)] = 0;
1485 char *pa_strip(char *s
) {
1488 /* Drops trailing whitespace. Modifies the string in
1489 * place. Returns pointer to first non-space character */
1491 s
+= strspn(s
, WHITESPACE
);
1493 for (e
= s
; *e
; e
++)
1494 if (!strchr(WHITESPACE
, *e
))
1505 /* Create a temporary lock file and lock it. */
1506 int pa_lock_lockfile(const char *fn
) {
1513 if ((fd
= pa_open_cloexec(fn
, O_CREAT
|O_RDWR
1517 , S_IRUSR
|S_IWUSR
)) < 0) {
1518 pa_log_warn("Failed to create lock file '%s': %s", fn
, pa_cstrerror(errno
));
1522 if (pa_lock_fd(fd
, 1) < 0) {
1523 pa_log_warn("Failed to lock file '%s'.", fn
);
1527 if (fstat(fd
, &st
) < 0) {
1528 pa_log_warn("Failed to fstat() file '%s': %s", fn
, pa_cstrerror(errno
));
1532 /* Check whether the file has been removed meanwhile. When yes,
1533 * restart this loop, otherwise, we're done */
1534 if (st
.st_nlink
>= 1)
1537 if (pa_lock_fd(fd
, 0) < 0) {
1538 pa_log_warn("Failed to unlock file '%s'.", fn
);
1542 if (pa_close(fd
) < 0) {
1543 pa_log_warn("Failed to close file '%s': %s", fn
, pa_cstrerror(errno
));
1554 int saved_errno
= errno
;
1556 errno
= saved_errno
;
1562 /* Unlock a temporary lock file */
1563 int pa_unlock_lockfile(const char *fn
, int fd
) {
1568 if (unlink(fn
) < 0) {
1569 pa_log_warn("Unable to remove lock file '%s': %s", fn
, pa_cstrerror(errno
));
1574 if (pa_lock_fd(fd
, 0) < 0) {
1575 pa_log_warn("Failed to unlock file '%s'.", fn
);
1579 if (pa_close(fd
) < 0) {
1580 pa_log_warn("Failed to close '%s': %s", fn
, pa_cstrerror(errno
));
1587 static char *get_config_home(char *home
) {
1590 t
= getenv("XDG_CONFIG_HOME");
1592 return pa_xstrdup(t
);
1594 return pa_sprintf_malloc("%s" PA_PATH_SEP
".config", home
);
1597 static int check_ours(const char *p
) {
1602 if (stat(p
, &st
) < 0)
1606 if (st
.st_uid
!= getuid())
1613 static char *get_pulse_home(void) {
1614 char *h
, *ret
, *config_home
;
1617 h
= pa_get_home_dir_malloc();
1619 pa_log_error("Failed to get home directory.");
1624 if (t
< 0 && t
!= -ENOENT
) {
1625 pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t
));
1630 /* If the old directory exists, use it. */
1631 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse", h
);
1632 if (access(ret
, F_OK
) >= 0) {
1638 /* Otherwise go for the XDG compliant directory. */
1639 config_home
= get_config_home(h
);
1641 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", config_home
);
1647 char *pa_get_state_dir(void) {
1650 /* The state directory shall contain dynamic data that should be
1651 * kept across reboots, and is private to this user */
1653 if (!(d
= pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1654 if (!(d
= get_pulse_home()))
1657 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1658 * dir then this will break. */
1660 if (pa_make_secure_dir(d
, 0700U, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1661 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1669 char *pa_get_home_dir_malloc(void) {
1671 size_t allocated
= 128;
1674 homedir
= pa_xmalloc(allocated
);
1676 if (!pa_get_home_dir(homedir
, allocated
)) {
1681 if (strlen(homedir
) < allocated
- 1)
1691 char *pa_get_binary_name_malloc(void) {
1693 size_t allocated
= 128;
1696 t
= pa_xmalloc(allocated
);
1698 if (!pa_get_binary_name(t
, allocated
)) {
1703 if (strlen(t
) < allocated
- 1)
1713 static char* make_random_dir(mode_t m
) {
1714 static const char table
[] =
1715 "abcdefghijklmnopqrstuvwxyz"
1716 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1722 fn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1723 pathlen
= strlen(fn
);
1731 for (i
= pathlen
- 12; i
< pathlen
; i
++)
1732 fn
[i
] = table
[rand() % (sizeof(table
)-1)];
1734 u
= umask((~m
) & 0777);
1741 saved_errno
= errno
;
1743 errno
= saved_errno
;
1748 if (errno
!= EEXIST
) {
1749 pa_log_error("Failed to create random directory %s: %s", fn
, pa_cstrerror(errno
));
1756 static int make_random_dir_and_link(mode_t m
, const char *k
) {
1759 if (!(p
= make_random_dir(m
)))
1763 if (symlink(p
, k
) < 0) {
1764 int saved_errno
= errno
;
1766 if (errno
!= EEXIST
)
1767 pa_log_error("Failed to symlink %s to %s: %s", k
, p
, pa_cstrerror(errno
));
1772 errno
= saved_errno
;
1784 char *pa_get_runtime_dir(void) {
1785 char *d
, *k
= NULL
, *p
= NULL
, *t
= NULL
, *mid
;
1788 /* The runtime directory shall contain dynamic data that needs NOT
1789 * to be kept across reboots and is usually private to the user,
1790 * except in system mode, where it might be accessible by other
1791 * users, too. Since we need POSIX locking and UNIX sockets in
1792 * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
1793 * set create a directory in $HOME and link it to a random subdir
1794 * in /tmp, if it was not explicitly configured. */
1796 m
= pa_in_system_mode() ? 0755U : 0700U;
1798 /* Use the explicitly configured value if it is set */
1799 d
= getenv("PULSE_RUNTIME_PATH");
1802 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1803 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1807 return pa_xstrdup(d
);
1810 /* Use the XDG standard for the runtime directory. */
1811 d
= getenv("XDG_RUNTIME_DIR");
1813 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", d
);
1815 if (pa_make_secure_dir(k
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1816 pa_log_error("Failed to create secure directory (%s): %s", k
, pa_cstrerror(errno
));
1823 /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
1824 d
= get_pulse_home();
1828 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, true) < 0) {
1829 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1834 mid
= pa_machine_id();
1840 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-runtime", d
, mid
);
1845 /* OK, first let's check if the "runtime" symlink already exists */
1850 if (errno
!= ENOENT
) {
1851 pa_log_error("Failed to stat runtime directory %s: %s", k
, pa_cstrerror(errno
));
1856 /* Hmm, so the runtime directory didn't exist yet, so let's
1857 * create one in /tmp and symlink that to it */
1859 if (make_random_dir_and_link(0700, k
) < 0) {
1861 /* Mhmm, maybe another process was quicker than us,
1862 * let's check if that was valid */
1863 if (errno
== EEXIST
)
1869 /* No symlink possible, so let's just create the runtime directly
1870 * Do not check again if it exists since it cannot be a symlink */
1871 if (mkdir(k
) < 0 && errno
!= EEXIST
)
1878 /* Make sure that this actually makes sense */
1879 if (!pa_is_path_absolute(p
)) {
1880 pa_log_error("Path %s in link %s is not absolute.", p
, k
);
1885 /* Hmm, so this symlink is still around, make sure nobody fools us */
1889 if (lstat(p
, &st
) < 0) {
1891 if (errno
!= ENOENT
) {
1892 pa_log_error("Failed to stat runtime directory %s: %s", p
, pa_cstrerror(errno
));
1898 if (S_ISDIR(st
.st_mode
) &&
1899 (st
.st_uid
== getuid()) &&
1900 ((st
.st_mode
& 0777) == 0700)) {
1906 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1914 /* Hmm, so the link points to some nonexisting or invalid
1915 * dir. Let's replace it by a new link. We first create a
1916 * temporary link and then rename that to allow concurrent
1917 * execution of this function. */
1919 t
= pa_sprintf_malloc("%s.tmp", k
);
1921 if (make_random_dir_and_link(0700, t
) < 0) {
1923 if (errno
!= EEXIST
) {
1924 pa_log_error("Failed to symlink %s: %s", t
, pa_cstrerror(errno
));
1931 /* Hmm, someone else was quicker then us. Let's give
1932 * him some time to finish, and retry. */
1937 /* OK, we succeeded in creating the temporary symlink, so
1938 * let's rename it */
1939 if (rename(t
, k
) < 0) {
1940 pa_log_error("Failed to rename %s to %s: %s", t
, k
, pa_cstrerror(errno
));
1956 /* Try to open a configuration file. If "env" is specified, open the
1957 * value of the specified environment variable. Otherwise look for a
1958 * file "local" in the home directory or a file "global" in global
1959 * file system. If "result" is non-NULL, a pointer to a newly
1960 * allocated buffer containing the used configuration file is
1962 FILE *pa_open_config_file(const char *global
, const char *local
, const char *env
, char **result
) {
1966 if (env
&& (fn
= getenv(env
))) {
1967 if ((f
= pa_fopen_cloexec(fn
, "r"))) {
1969 *result
= pa_xstrdup(fn
);
1974 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1983 if ((e
= getenv("PULSE_CONFIG_PATH"))) {
1984 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1985 f
= pa_fopen_cloexec(fn
, "r");
1986 } else if ((h
= pa_get_home_dir_malloc())) {
1987 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1988 f
= pa_fopen_cloexec(fn
, "r");
1991 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".config/pulse" PA_PATH_SEP
"%s", h
, local
);
1992 f
= pa_fopen_cloexec(fn
, "r");
2000 *result
= pa_xstrdup(fn
);
2006 if (errno
!= ENOENT
) {
2007 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2019 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
2020 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
2021 pa_win32_get_toplevel(NULL
),
2022 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
2025 gfn
= pa_xstrdup(global
);
2027 if ((f
= pa_fopen_cloexec(gfn
, "r"))) {
2042 char *pa_find_config_file(const char *global
, const char *local
, const char *env
) {
2045 if (env
&& (fn
= getenv(env
))) {
2046 if (access(fn
, R_OK
) == 0)
2047 return pa_xstrdup(fn
);
2049 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2058 if ((e
= getenv("PULSE_CONFIG_PATH")))
2059 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
2060 else if ((h
= pa_get_home_dir_malloc())) {
2061 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
2066 if (access(fn
, R_OK
) == 0) {
2067 char *r
= pa_xstrdup(fn
);
2072 if (errno
!= ENOENT
) {
2073 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2085 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
2086 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
2087 pa_win32_get_toplevel(NULL
),
2088 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
2091 gfn
= pa_xstrdup(global
);
2093 if (access(gfn
, R_OK
) == 0)
2103 /* Format the specified data as a hexademical string */
2104 char *pa_hexstr(const uint8_t* d
, size_t dlength
, char *s
, size_t slength
) {
2105 size_t i
= 0, j
= 0;
2106 const char hex
[] = "0123456789abcdef";
2110 pa_assert(slength
> 0);
2112 while (j
+2 < slength
&& i
< dlength
) {
2113 s
[j
++] = hex
[*d
>> 4];
2114 s
[j
++] = hex
[*d
& 0xF];
2120 s
[j
< slength
? j
: slength
] = 0;
2124 /* Convert a hexadecimal digit to a number or -1 if invalid */
2125 static int hexc(char c
) {
2126 if (c
>= '0' && c
<= '9')
2129 if (c
>= 'A' && c
<= 'F')
2130 return c
- 'A' + 10;
2132 if (c
>= 'a' && c
<= 'f')
2133 return c
- 'a' + 10;
2139 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
2140 size_t pa_parsehex(const char *p
, uint8_t *d
, size_t dlength
) {
2146 while (j
< dlength
&& *p
) {
2149 if ((b
= hexc(*(p
++))) < 0)
2152 d
[j
] = (uint8_t) (b
<< 4);
2157 if ((b
= hexc(*(p
++))) < 0)
2160 d
[j
] |= (uint8_t) b
;
2167 /* Returns nonzero when *s starts with *pfx */
2168 bool pa_startswith(const char *s
, const char *pfx
) {
2176 return strlen(s
) >= l
&& strncmp(s
, pfx
, l
) == 0;
2179 /* Returns nonzero when *s ends with *sfx */
2180 bool pa_endswith(const char *s
, const char *sfx
) {
2189 return l1
>= l2
&& pa_streq(s
+ l1
- l2
, sfx
);
2192 bool pa_is_path_absolute(const char *fn
) {
2198 return strlen(fn
) >= 3 && isalpha(fn
[0]) && fn
[1] == ':' && fn
[2] == '\\';
2202 char *pa_make_path_absolute(const char *p
) {
2208 if (pa_is_path_absolute(p
))
2209 return pa_xstrdup(p
);
2211 if (!(cwd
= pa_getcwd()))
2212 return pa_xstrdup(p
);
2214 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", cwd
, p
);
2219 /* If fn is NULL, return the PulseAudio runtime or state dir (depending on the
2220 * rt parameter). If fn is non-NULL and starts with /, return fn. Otherwise,
2221 * append fn to the runtime/state dir and return it. */
2222 static char *get_path(const char *fn
, bool prependmid
, bool rt
) {
2225 rtp
= rt
? pa_get_runtime_dir() : pa_get_state_dir();
2228 char *r
, *canonical_rtp
;
2230 if (pa_is_path_absolute(fn
)) {
2232 return pa_xstrdup(fn
);
2238 /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
2239 if ((canonical_rtp
= pa_realpath(rtp
))) {
2240 if (strlen(rtp
) >= strlen(canonical_rtp
))
2243 pa_xfree(canonical_rtp
);
2244 canonical_rtp
= rtp
;
2247 canonical_rtp
= rtp
;
2252 if (!(mid
= pa_machine_id())) {
2253 pa_xfree(canonical_rtp
);
2257 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-%s", canonical_rtp
, mid
, fn
);
2260 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", canonical_rtp
, fn
);
2262 pa_xfree(canonical_rtp
);
2268 char *pa_runtime_path(const char *fn
) {
2269 return get_path(fn
, false, true);
2272 char *pa_state_path(const char *fn
, bool appendmid
) {
2273 return get_path(fn
, appendmid
, false);
2276 /* Convert the string s to a signed integer in *ret_i */
2277 int pa_atoi(const char *s
, int32_t *ret_i
) {
2283 if (pa_atol(s
, &l
) < 0)
2286 if ((int32_t) l
!= l
) {
2291 *ret_i
= (int32_t) l
;
2296 /* Convert the string s to an unsigned integer in *ret_u */
2297 int pa_atou(const char *s
, uint32_t *ret_u
) {
2305 l
= strtoul(s
, &x
, 0);
2307 if (!x
|| *x
|| errno
) {
2313 if ((uint32_t) l
!= l
) {
2318 *ret_u
= (uint32_t) l
;
2323 /* Convert the string s to a signed long integer in *ret_l. */
2324 int pa_atol(const char *s
, long *ret_l
) {
2332 l
= strtol(s
, &x
, 0);
2334 if (!x
|| *x
|| errno
) {
2345 #ifdef HAVE_STRTOF_L
2346 static locale_t c_locale
= NULL
;
2348 static void c_locale_destroy(void) {
2349 freelocale(c_locale
);
2353 int pa_atod(const char *s
, double *ret_d
) {
2360 /* This should be locale independent */
2362 #ifdef HAVE_STRTOF_L
2366 if ((c_locale
= newlocale(LC_ALL_MASK
, "C", NULL
)))
2367 atexit(c_locale_destroy
);
2373 f
= strtod_l(s
, &x
, c_locale
);
2381 if (!x
|| *x
|| errno
) {
2392 /* Same as snprintf, but guarantees NUL-termination on every platform */
2393 size_t pa_snprintf(char *str
, size_t size
, const char *format
, ...) {
2398 pa_assert(size
> 0);
2401 va_start(ap
, format
);
2402 ret
= pa_vsnprintf(str
, size
, format
, ap
);
2408 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2409 size_t pa_vsnprintf(char *str
, size_t size
, const char *format
, va_list ap
) {
2413 pa_assert(size
> 0);
2416 ret
= vsnprintf(str
, size
, format
, ap
);
2423 if ((size_t) ret
> size
-1)
2426 return (size_t) ret
;
2429 /* Truncate the specified string, but guarantee that the string
2430 * returned still validates as UTF8 */
2431 char *pa_truncate_utf8(char *c
, size_t l
) {
2433 pa_assert(pa_utf8_valid(c
));
2440 while (l
> 0 && !pa_utf8_valid(c
))
2446 char *pa_getcwd(void) {
2450 char *p
= pa_xmalloc(l
);
2454 if (errno
!= ERANGE
)
2462 void *pa_will_need(const void *p
, size_t l
) {
2463 #ifdef RLIMIT_MEMLOCK
2474 a
= PA_PAGE_ALIGN_PTR(p
);
2475 size
= (size_t) ((const uint8_t*) p
+ l
- (const uint8_t*) a
);
2477 #ifdef HAVE_POSIX_MADVISE
2478 if ((r
= posix_madvise((void*) a
, size
, POSIX_MADV_WILLNEED
)) == 0) {
2479 pa_log_debug("posix_madvise() worked fine!");
2484 /* Most likely the memory was not mmap()ed from a file and thus
2485 * madvise() didn't work, so let's misuse mlock() do page this
2486 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2487 * inviting, the man page of mlock() tells us: "All pages that
2488 * contain a part of the specified address range are guaranteed to
2489 * be resident in RAM when the call returns successfully." */
2491 #ifdef RLIMIT_MEMLOCK
2492 pa_assert_se(getrlimit(RLIMIT_MEMLOCK
, &rlim
) == 0);
2494 if (rlim
.rlim_cur
< PA_PAGE_SIZE
) {
2495 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
));
2500 bs
= PA_PAGE_ALIGN((size_t) rlim
.rlim_cur
);
2502 bs
= PA_PAGE_SIZE
*4;
2505 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r
));
2508 while (size
> 0 && bs
> 0) {
2513 if (mlock(a
, bs
) < 0) {
2514 bs
= PA_PAGE_ALIGN(bs
/ 2);
2518 pa_assert_se(munlock(a
, bs
) == 0);
2520 a
= (const uint8_t*) a
+ bs
;
2526 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno
));
2528 pa_log_debug("mlock() worked fine!");
2533 void pa_close_pipe(int fds
[2]) {
2537 pa_assert_se(pa_close(fds
[0]) == 0);
2540 pa_assert_se(pa_close(fds
[1]) == 0);
2542 fds
[0] = fds
[1] = -1;
2545 char *pa_readlink(const char *p
) {
2546 #ifdef HAVE_READLINK
2555 if ((n
= readlink(p
, c
, l
-1)) < 0) {
2560 if ((size_t) n
< l
-1) {
2573 int pa_close_all(int except_fd
, ...) {
2578 va_start(ap
, except_fd
);
2581 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2586 p
= pa_xnew(int, n
+1);
2588 va_start(ap
, except_fd
);
2591 if (except_fd
>= 0) {
2595 while ((fd
= va_arg(ap
, int)) >= 0)
2602 r
= pa_close_allv(p
);
2608 int pa_close_allv(const int except_fds
[]) {
2617 if ((d
= opendir("/proc/self/fd"))) {
2621 while ((de
= readdir(d
))) {
2627 if (de
->d_name
[0] == '.')
2631 l
= strtol(de
->d_name
, &e
, 10);
2632 if (errno
!= 0 || !e
|| *e
) {
2640 if ((long) fd
!= l
) {
2653 for (i
= 0; except_fds
[i
] >= 0; i
++)
2654 if (except_fds
[i
] == fd
) {
2662 if (pa_close(fd
) < 0) {
2663 saved_errno
= errno
;
2665 errno
= saved_errno
;
2677 if (getrlimit(RLIMIT_NOFILE
, &rl
) >= 0)
2678 maxfd
= (int) rl
.rlim_max
;
2680 maxfd
= sysconf(_SC_OPEN_MAX
);
2682 for (fd
= 3; fd
< maxfd
; fd
++) {
2687 for (i
= 0; except_fds
[i
] >= 0; i
++)
2688 if (except_fds
[i
] == fd
) {
2696 if (pa_close(fd
) < 0 && errno
!= EBADF
)
2699 #endif /* !OS_IS_WIN32 */
2704 int pa_unblock_sigs(int except
, ...) {
2709 va_start(ap
, except
);
2712 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2717 p
= pa_xnew(int, n
+1);
2719 va_start(ap
, except
);
2726 while ((sig
= va_arg(ap
, int)) >= 0)
2733 r
= pa_unblock_sigsv(p
);
2739 int pa_unblock_sigsv(const int except
[]) {
2744 if (sigemptyset(&ss
) < 0)
2747 for (i
= 0; except
[i
] > 0; i
++)
2748 if (sigaddset(&ss
, except
[i
]) < 0)
2751 return sigprocmask(SIG_SETMASK
, &ss
, NULL
);
2757 int pa_reset_sigs(int except
, ...) {
2762 va_start(ap
, except
);
2765 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2770 p
= pa_xnew(int, n
+1);
2772 va_start(ap
, except
);
2779 while ((sig
= va_arg(ap
, int)) >= 0)
2786 r
= pa_reset_sigsv(p
);
2792 int pa_reset_sigsv(const int except
[]) {
2796 for (sig
= 1; sig
< NSIG
; sig
++) {
2808 for (i
= 0; except
[i
] > 0; i
++) {
2809 if (sig
== except
[i
]) {
2818 struct sigaction sa
;
2820 memset(&sa
, 0, sizeof(sa
));
2821 sa
.sa_handler
= SIG_DFL
;
2823 /* On Linux the first two RT signals are reserved by
2824 * glibc, and sigaction() will return EINVAL for them. */
2825 if ((sigaction(sig
, &sa
, NULL
) < 0))
2826 if (errno
!= EINVAL
)
2835 void pa_set_env(const char *key
, const char *value
) {
2839 /* This is not thread-safe */
2842 SetEnvironmentVariable(key
, value
);
2844 setenv(key
, value
, 1);
2848 void pa_set_env_and_record(const char *key
, const char *value
) {
2852 /* This is not thread-safe */
2854 pa_set_env(key
, value
);
2855 recorded_env
= pa_strlist_prepend(recorded_env
, key
);
2858 void pa_unset_env_recorded(void) {
2860 /* This is not thread-safe */
2865 recorded_env
= pa_strlist_pop(recorded_env
, &s
);
2871 SetEnvironmentVariable(s
, NULL
);
2879 bool pa_in_system_mode(void) {
2882 if (!(e
= getenv("PULSE_SYSTEM")))
2888 /* Checks a whitespace-separated list of words in haystack for needle */
2889 bool pa_str_in_list_spaces(const char *haystack
, const char *needle
) {
2891 const char *state
= NULL
;
2893 if (!haystack
|| !needle
)
2896 while ((s
= pa_split_spaces(haystack
, &state
))) {
2897 if (pa_streq(needle
, s
)) {
2908 char *pa_get_user_name_malloc(void) {
2912 #ifdef _SC_LOGIN_NAME_MAX
2913 k
= (ssize_t
) sysconf(_SC_LOGIN_NAME_MAX
);
2919 u
= pa_xnew(char, k
+1);
2921 if (!(pa_get_user_name(u
, k
))) {
2929 char *pa_get_host_name_malloc(void) {
2938 if (!pa_get_host_name(c
, l
)) {
2940 if (errno
!= EINVAL
&& errno
!= ENAMETOOLONG
)
2943 } else if (strlen(c
) < l
-1) {
2951 u
= pa_utf8_filter(c
);
2956 /* Hmm, the hostname is as long the space we offered the
2957 * function, we cannot know if it fully fit in, so let's play
2958 * safe and retry. */
2967 char *pa_machine_id(void) {
2971 /* The returned value is supposed be some kind of ascii identifier
2972 * that is unique and stable across reboots. */
2974 /* First we try the /etc/machine-id, which is the best option we
2975 * have, since it fits perfectly our needs and is not as volatile
2976 * as the hostname which might be set from dhcp. */
2978 if ((f
= pa_fopen_cloexec(PA_MACHINE_ID
, "r")) ||
2979 (f
= pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK
, "r"))) {
2980 char ln
[34] = "", *r
;
2982 r
= fgets(ln
, sizeof(ln
)-1, f
);
2988 return pa_utf8_filter(ln
);
2991 if ((h
= pa_get_host_name_malloc()))
2994 #if !defined(OS_IS_WIN32) && !defined(__ANDROID__)
2995 /* If no hostname was set we use the POSIX hostid. It's usually
2996 * the IPv4 address. Might not be that stable. */
2997 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
3003 char *pa_session_id(void) {
3006 e
= getenv("XDG_SESSION_ID");
3010 return pa_utf8_filter(e
);
3013 char *pa_uname_string(void) {
3017 pa_assert_se(uname(&u
) >= 0);
3019 return pa_sprintf_malloc("%s %s %s %s", u
.sysname
, u
.machine
, u
.release
, u
.version
);
3025 i
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
3026 pa_assert_se(GetVersionEx(&i
));
3028 return pa_sprintf_malloc("Windows %d.%d (%d) %s", i
.dwMajorVersion
, i
.dwMinorVersion
, i
.dwBuildNumber
, i
.szCSDVersion
);
3032 #ifdef HAVE_VALGRIND_MEMCHECK_H
3033 bool pa_in_valgrind(void) {
3036 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
3037 * here instead of really checking whether we run in valgrind or
3041 b
= getenv("VALGRIND") ? 2 : 1;
3047 unsigned pa_gcd(unsigned a
, unsigned b
) {
3058 void pa_reduce(unsigned *num
, unsigned *den
) {
3060 unsigned gcd
= pa_gcd(*num
, *den
);
3068 pa_assert(pa_gcd(*num
, *den
) == 1);
3071 unsigned pa_ncpus(void) {
3074 #ifdef _SC_NPROCESSORS_CONF
3075 ncpus
= sysconf(_SC_NPROCESSORS_CONF
);
3080 return ncpus
<= 0 ? 1 : (unsigned) ncpus
;
3083 char *pa_replace(const char*s
, const char*a
, const char *b
) {
3092 sb
= pa_strbuf_new();
3097 if (!(p
= strstr(s
, a
)))
3100 pa_strbuf_putsn(sb
, s
, p
-s
);
3101 pa_strbuf_puts(sb
, b
);
3105 pa_strbuf_puts(sb
, s
);
3107 return pa_strbuf_tostring_free(sb
);
3110 char *pa_escape(const char *p
, const char *chars
) {
3113 pa_strbuf
*buf
= pa_strbuf_new();
3115 for (s
= p
; *s
; ++s
) {
3117 pa_strbuf_putc(buf
, '\\');
3119 for (c
= chars
; *c
; ++c
) {
3121 pa_strbuf_putc(buf
, '\\');
3126 pa_strbuf_putc(buf
, *s
);
3129 return pa_strbuf_tostring_free(buf
);
3132 char *pa_unescape(char *p
) {
3134 bool escaped
= false;
3136 for (s
= p
, d
= p
; *s
; s
++) {
3137 if (!escaped
&& *s
== '\\') {
3151 char *pa_realpath(const char *path
) {
3155 /* We want only absolute paths */
3156 if (path
[0] != '/') {
3161 #if defined(__GLIBC__)
3165 if (!(r
= realpath(path
, NULL
)))
3168 /* We copy this here in case our pa_xmalloc() is not
3169 * implemented on top of libc malloc() */
3173 #elif defined(PATH_MAX)
3176 path_buf
= pa_xmalloc(PATH_MAX
);
3178 #if defined(OS_IS_WIN32)
3179 if (!(t
= _fullpath(path_buf
, path
, _MAX_PATH
))) {
3184 if (!(t
= realpath(path
, path_buf
))) {
3191 #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."
3197 void pa_disable_sigpipe(void) {
3200 struct sigaction sa
;
3204 if (sigaction(SIGPIPE
, NULL
, &sa
) < 0) {
3205 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3209 sa
.sa_handler
= SIG_IGN
;
3211 if (sigaction(SIGPIPE
, &sa
, NULL
) < 0) {
3212 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3218 void pa_xfreev(void**a
) {
3224 for (p
= a
; *p
; p
++)
3230 char **pa_split_spaces_strv(const char *s
) {
3232 unsigned i
= 0, n
= 8;
3233 const char *state
= NULL
;
3235 t
= pa_xnew(char*, n
);
3236 while ((e
= pa_split_spaces(s
, &state
))) {
3241 t
= pa_xrenew(char*, t
, n
);
3254 char* pa_maybe_prefix_path(const char *path
, const char *prefix
) {
3257 if (pa_is_path_absolute(path
))
3258 return pa_xstrdup(path
);
3260 return pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", prefix
, path
);
3263 size_t pa_pipe_buf(int fd
) {
3268 if ((n
= fpathconf(fd
, _PC_PIPE_BUF
)) >= 0)
3279 void pa_reset_personality(void) {
3281 #if defined(__linux__) && !defined(__ANDROID__)
3282 if (personality(PER_LINUX
) < 0)
3283 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno
));
3288 bool pa_run_from_build_tree(void) {
3290 static bool b
= false;
3293 if ((rp
= pa_readlink("/proc/self/exe"))) {
3294 b
= pa_startswith(rp
, PA_BUILDDIR
);
3302 const char *pa_get_temp_dir(void) {
3305 if ((t
= getenv("TMPDIR")) &&
3306 pa_is_path_absolute(t
))
3309 if ((t
= getenv("TMP")) &&
3310 pa_is_path_absolute(t
))
3313 if ((t
= getenv("TEMP")) &&
3314 pa_is_path_absolute(t
))
3317 if ((t
= getenv("TEMPDIR")) &&
3318 pa_is_path_absolute(t
))
3324 int pa_open_cloexec(const char *fn
, int flags
, mode_t mode
) {
3332 if ((fd
= open(fn
, flags
|O_CLOEXEC
, mode
)) >= 0)
3335 if (errno
!= EINVAL
)
3339 if ((fd
= open(fn
, flags
, mode
)) < 0)
3343 /* Some implementations might simply ignore O_CLOEXEC if it is not
3344 * understood, make sure FD_CLOEXEC is enabled anyway */
3346 pa_make_fd_cloexec(fd
);
3350 int pa_socket_cloexec(int domain
, int type
, int protocol
) {
3354 if ((fd
= socket(domain
, type
| SOCK_CLOEXEC
, protocol
)) >= 0)
3357 if (errno
!= EINVAL
)
3361 if ((fd
= socket(domain
, type
, protocol
)) < 0)
3365 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3366 * not understood, make sure FD_CLOEXEC is enabled anyway */
3368 pa_make_fd_cloexec(fd
);
3372 int pa_pipe_cloexec(int pipefd
[2]) {
3376 if ((r
= pipe2(pipefd
, O_CLOEXEC
)) >= 0)
3379 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3384 if ((r
= pipe(pipefd
)) < 0)
3388 pa_make_fd_cloexec(pipefd
[0]);
3389 pa_make_fd_cloexec(pipefd
[1]);
3394 int pa_accept_cloexec(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
) {
3398 if ((fd
= accept4(sockfd
, addr
, addrlen
, SOCK_CLOEXEC
)) >= 0)
3401 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3406 if ((fd
= accept(sockfd
, addr
, addrlen
)) < 0)
3410 pa_make_fd_cloexec(fd
);
3414 FILE* pa_fopen_cloexec(const char *path
, const char *mode
) {
3418 m
= pa_sprintf_malloc("%se", mode
);
3421 if ((f
= fopen(path
, m
))) {
3428 if (errno
!= EINVAL
)
3431 if (!(f
= fopen(path
, mode
)))
3435 pa_make_fd_cloexec(fileno(f
));
3439 void pa_nullify_stdfds(void) {
3442 pa_close(STDIN_FILENO
);
3443 pa_close(STDOUT_FILENO
);
3444 pa_close(STDERR_FILENO
);
3446 pa_assert_se(open("/dev/null", O_RDONLY
) == STDIN_FILENO
);
3447 pa_assert_se(open("/dev/null", O_WRONLY
) == STDOUT_FILENO
);
3448 pa_assert_se(open("/dev/null", O_WRONLY
) == STDERR_FILENO
);
3455 char *pa_read_line_from_file(const char *fn
) {
3457 char ln
[256] = "", *r
;
3459 if (!(f
= pa_fopen_cloexec(fn
, "r")))
3462 r
= fgets(ln
, sizeof(ln
)-1, f
);
3471 return pa_xstrdup(ln
);
3474 bool pa_running_in_vm(void) {
3476 #if defined(__i386__) || defined(__x86_64__)
3478 /* Both CPUID and DMI are x86 specific interfaces... */
3480 uint32_t eax
= 0x40000000;
3487 const char *const dmi_vendors
[] = {
3488 "/sys/class/dmi/id/sys_vendor",
3489 "/sys/class/dmi/id/board_vendor",
3490 "/sys/class/dmi/id/bios_vendor"
3495 for (i
= 0; i
< PA_ELEMENTSOF(dmi_vendors
); i
++) {
3498 if ((s
= pa_read_line_from_file(dmi_vendors
[i
]))) {
3500 if (pa_startswith(s
, "QEMU") ||
3501 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3502 pa_startswith(s
, "VMware") ||
3503 pa_startswith(s
, "VMW") ||
3504 pa_startswith(s
, "Microsoft Corporation") ||
3505 pa_startswith(s
, "innotek GmbH") ||
3506 pa_startswith(s
, "Xen")) {
3518 /* http://lwn.net/Articles/301888/ */
3521 __asm__
__volatile__ (
3522 /* ebx/rbx is being used for PIC! */
3523 " push %%"PA_REG_b
" \n\t"
3525 " mov %%ebx, %1 \n\t"
3526 " pop %%"PA_REG_b
" \n\t"
3528 : "=a" (eax
), "=r" (sig
.sig32
[0]), "=c" (sig
.sig32
[1]), "=d" (sig
.sig32
[2])
3532 if (pa_streq(sig
.text
, "XenVMMXenVMM") ||
3533 pa_streq(sig
.text
, "KVMKVMKVM") ||
3534 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3535 pa_streq(sig
.text
, "VMwareVMware") ||
3536 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3537 pa_streq(sig
.text
, "Microsoft Hv"))