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>
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
;
155 /* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
156 char *pa_win32_get_toplevel(HANDLE handle
) {
157 static char *toplevel
= NULL
;
160 char library_path
[MAX_PATH
];
163 if (!GetModuleFileName(handle
, library_path
, MAX_PATH
))
166 toplevel
= pa_xstrdup(library_path
);
168 p
= strrchr(toplevel
, PA_PATH_SEP_CHAR
);
172 p
= strrchr(toplevel
, PA_PATH_SEP_CHAR
);
173 if (p
&& pa_streq(p
+ 1, "bin"))
182 /** Make a file descriptor nonblock. Doesn't do any error checking */
183 void pa_make_fd_nonblock(int fd
) {
189 pa_assert_se((v
= fcntl(fd
, F_GETFL
)) >= 0);
191 if (!(v
& O_NONBLOCK
))
192 pa_assert_se(fcntl(fd
, F_SETFL
, v
|O_NONBLOCK
) >= 0);
194 #elif defined(OS_IS_WIN32)
196 if (ioctlsocket(fd
, FIONBIO
, &arg
) < 0) {
197 pa_assert_se(WSAGetLastError() == WSAENOTSOCK
);
198 pa_log_warn("Only sockets can be made non-blocking!");
201 pa_log_warn("Non-blocking I/O not supported.!");
206 /* Set the FD_CLOEXEC flag for a fd */
207 void pa_make_fd_cloexec(int fd
) {
213 pa_assert_se((v
= fcntl(fd
, F_GETFD
, 0)) >= 0);
215 if (!(v
& FD_CLOEXEC
))
216 pa_assert_se(fcntl(fd
, F_SETFD
, v
|FD_CLOEXEC
) >= 0);
221 /** Creates a directory securely. Will create parent directories recursively if
222 * required. This will not update permissions on parent directories if they
223 * already exist, however. */
224 int pa_make_secure_dir(const char* dir
, mode_t m
, uid_t uid
, gid_t gid
, pa_bool_t update_perms
) {
227 pa_bool_t retry
= TRUE
;
237 u
= umask((~m
) & 0777);
243 if (r
< 0 && errno
== ENOENT
&& retry
) {
244 /* If a parent directory in the path doesn't exist, try to create that
245 * first, then try again. */
246 pa_make_secure_parent_dir(dir
, m
, uid
, gid
, FALSE
);
251 if (r
< 0 && errno
!= EEXIST
)
254 #if defined(HAVE_FSTAT) && !defined(OS_IS_WIN32)
270 if (fstat(fd
, &st
) < 0) {
271 pa_assert_se(pa_close(fd
) >= 0);
275 if (!S_ISDIR(st
.st_mode
)) {
276 pa_assert_se(pa_close(fd
) >= 0);
285 if (uid
== (uid_t
) -1)
287 if (gid
== (gid_t
) -1)
289 if (fchown(fd
, uid
, gid
) < 0)
294 (void) fchmod(fd
, m
);
297 pa_assert_se(pa_close(fd
) >= 0);
302 if (lstat(dir
, &st
) < 0)
304 if (stat(dir
, &st
) < 0)
309 if (!S_ISDIR(st
.st_mode
) ||
310 (st
.st_uid
!= uid
) ||
311 (st
.st_gid
!= gid
) ||
312 ((st
.st_mode
& 0777) != m
)) {
317 pa_log_warn("Secure directory creation not supported on Win32.");
330 /* Return a newly allocated sting containing the parent directory of the specified file */
331 char *pa_parent_dir(const char *fn
) {
332 char *slash
, *dir
= pa_xstrdup(fn
);
334 if ((slash
= (char*) pa_path_get_filename(dir
)) == dir
) {
344 /* Creates a the parent directory of the specified path securely */
345 int pa_make_secure_parent_dir(const char *fn
, mode_t m
, uid_t uid
, gid_t gid
, pa_bool_t update_perms
) {
349 if (!(dir
= pa_parent_dir(fn
)))
352 if (pa_make_secure_dir(dir
, m
, uid
, gid
, update_perms
) < 0)
362 /** Platform independent read function. Necessary since not all
363 * systems treat all file descriptors equal. If type is
364 * non-NULL it is used to cache the type of the fd. This is
365 * useful for making sure that only a single syscall is executed per
366 * function call. The variable pointed to should be initialized to 0
368 ssize_t
pa_read(int fd
, void *buf
, size_t count
, int *type
) {
372 if (!type
|| *type
== 0) {
377 if ((r
= recv(fd
, buf
, count
, 0)) >= 0)
380 err
= WSAGetLastError();
381 if (err
!= WSAENOTSOCK
) {
382 /* transparently handle non-blocking sockets, by waiting
384 if (err
== WSAEWOULDBLOCK
) {
388 if (pa_poll(&pfd
, 1, -1) >= 0) {
405 if ((r
= read(fd
, buf
, count
)) < 0)
413 /** Similar to pa_read(), but handles writes */
414 ssize_t
pa_write(int fd
, const void *buf
, size_t count
, int *type
) {
416 if (!type
|| *type
== 0) {
424 if ((r
= send(fd
, buf
, count
, MSG_NOSIGNAL
)) < 0) {
436 err
= WSAGetLastError();
437 if (err
!= WSAENOTSOCK
) {
438 /* transparently handle non-blocking sockets, by waiting
440 if (err
== WSAEWOULDBLOCK
) {
443 pfd
.events
= POLLOUT
;
444 if (pa_poll(&pfd
, 1, -1) >= 0) {
452 if (errno
!= ENOTSOCK
)
463 if ((r
= write(fd
, buf
, count
)) < 0)
471 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
472 * unless EOF is reached or an error occurred */
473 ssize_t
pa_loop_read(int fd
, void*data
, size_t size
, int *type
) {
489 if ((r
= pa_read(fd
, data
, size
, type
)) < 0)
496 data
= (uint8_t*) data
+ r
;
503 /** Similar to pa_loop_read(), but wraps write() */
504 ssize_t
pa_loop_write(int fd
, const void*data
, size_t size
, int *type
) {
520 if ((r
= pa_write(fd
, data
, size
, type
)) < 0)
527 data
= (const uint8_t*) data
+ r
;
534 /** Platform independent read function. Necessary since not all
535 * systems treat all file descriptors equal. */
536 int pa_close(int fd
) {
541 if ((ret
= closesocket(fd
)) == 0)
544 if (WSAGetLastError() != WSAENOTSOCK
) {
545 errno
= WSAGetLastError();
553 if ((r
= close(fd
)) < 0)
561 /* Print a warning messages in case that the given signal is not
562 * blocked or trapped */
563 void pa_check_signal_is_blocked(int sig
) {
564 #ifdef HAVE_SIGACTION
568 /* If POSIX threads are supported use thread-aware
569 * pthread_sigmask() function, to check if the signal is
570 * blocked. Otherwise fall back to sigprocmask() */
573 if (pthread_sigmask(SIG_SETMASK
, NULL
, &set
) < 0) {
575 if (sigprocmask(SIG_SETMASK
, NULL
, &set
) < 0) {
576 pa_log("sigprocmask(): %s", pa_cstrerror(errno
));
583 if (sigismember(&set
, sig
))
586 /* Check whether the signal is trapped */
588 if (sigaction(sig
, NULL
, &sa
) < 0) {
589 pa_log("sigaction(): %s", pa_cstrerror(errno
));
593 if (sa
.sa_handler
!= SIG_DFL
)
596 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig
));
597 #else /* HAVE_SIGACTION */
598 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig
));
602 /* The following function is based on an example from the GNU libc
603 * documentation. This function is similar to GNU's asprintf(). */
604 char *pa_sprintf_malloc(const char *format
, ...) {
614 c
= pa_xrealloc(c
, size
);
616 va_start(ap
, format
);
617 r
= vsnprintf(c
, size
, format
, ap
);
622 if (r
> -1 && (size_t) r
< size
)
625 if (r
> -1) /* glibc 2.1 */
632 /* Same as the previous function, but use a va_list instead of an
634 char *pa_vsprintf_malloc(const char *format
, va_list ap
) {
644 c
= pa_xrealloc(c
, size
);
647 r
= vsnprintf(c
, size
, format
, aq
);
652 if (r
> -1 && (size_t) r
< size
)
655 if (r
> -1) /* glibc 2.1 */
662 /* Similar to OpenBSD's strlcpy() function */
663 char *pa_strlcpy(char *b
, const char *s
, size_t l
) {
681 #ifdef _POSIX_PRIORITY_SCHEDULING
682 static int set_scheduler(int rtprio
) {
684 struct sched_param sp
;
690 dbus_error_init(&error
);
694 sp
.sched_priority
= rtprio
;
696 #ifdef SCHED_RESET_ON_FORK
697 if (pthread_setschedparam(pthread_self(), SCHED_RR
|SCHED_RESET_ON_FORK
, &sp
) == 0) {
698 pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
703 if (pthread_setschedparam(pthread_self(), SCHED_RR
, &sp
) == 0) {
704 pa_log_debug("SCHED_RR worked.");
707 #endif /* HAVE_SCHED_H */
710 /* Try to talk to RealtimeKit */
712 if (!(bus
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
))) {
713 pa_log("Failed to connect to system bus: %s\n", error
.message
);
714 dbus_error_free(&error
);
719 /* We need to disable exit on disconnect because otherwise
720 * dbus_shutdown will kill us. See
721 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
722 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
724 r
= rtkit_make_realtime(bus
, 0, rtprio
);
725 dbus_connection_close(bus
);
726 dbus_connection_unref(bus
);
729 pa_log_debug("RealtimeKit worked.");
742 /* Make the current thread a realtime thread, and acquire the highest
743 * rtprio we can get that is less or equal the specified parameter. If
744 * the thread is already realtime, don't do anything. */
745 int pa_make_realtime(int rtprio
) {
747 #if defined(OS_IS_DARWIN)
748 struct thread_time_constraint_policy ttcpolicy
;
750 size_t size
= sizeof(freq
);
753 ret
= sysctlbyname("hw.cpufrequency", &freq
, &size
, NULL
, 0);
755 pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
759 pa_log_debug("sysctl for hw.cpufrequency: %llu", freq
);
761 /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
762 ttcpolicy
.period
= freq
/ 160;
763 ttcpolicy
.computation
= freq
/ 3300;
764 ttcpolicy
.constraint
= freq
/ 2200;
765 ttcpolicy
.preemptible
= 1;
767 ret
= thread_policy_set(mach_thread_self(),
768 THREAD_TIME_CONSTRAINT_POLICY
,
769 (thread_policy_t
) &ttcpolicy
,
770 THREAD_TIME_CONSTRAINT_POLICY_COUNT
);
772 pa_log_info("Unable to set real-time thread priority (%08x).", ret
);
776 pa_log_info("Successfully acquired real-time thread priority.");
779 #elif defined(_POSIX_PRIORITY_SCHEDULING)
782 if (set_scheduler(rtprio
) >= 0) {
783 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio
);
787 for (p
= rtprio
-1; p
>= 1; p
--)
788 if (set_scheduler(p
) >= 0) {
789 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p
, rtprio
);
792 #elif defined(OS_IS_WIN32)
793 /* Windows only allows realtime scheduling to be set on a per process basis.
794 * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
795 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL
)) {
796 pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
800 pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
805 pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno
));
809 #ifdef HAVE_SYS_RESOURCE_H
810 static int set_nice(int nice_level
) {
816 dbus_error_init(&error
);
819 #ifdef HAVE_SYS_RESOURCE_H
820 if (setpriority(PRIO_PROCESS
, 0, nice_level
) >= 0) {
821 pa_log_debug("setpriority() worked.");
827 /* Try to talk to RealtimeKit */
829 if (!(bus
= dbus_bus_get(DBUS_BUS_SYSTEM
, &error
))) {
830 pa_log("Failed to connect to system bus: %s\n", error
.message
);
831 dbus_error_free(&error
);
836 /* We need to disable exit on disconnect because otherwise
837 * dbus_shutdown will kill us. See
838 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
839 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
841 r
= rtkit_make_high_priority(bus
, 0, nice_level
);
842 dbus_connection_unref(bus
);
845 pa_log_debug("RealtimeKit worked.");
856 /* Raise the priority of the current process as much as possible that
857 * is <= the specified nice level..*/
858 int pa_raise_priority(int nice_level
) {
860 #ifdef HAVE_SYS_RESOURCE_H
863 if (set_nice(nice_level
) >= 0) {
864 pa_log_info("Successfully gained nice level %i.", nice_level
);
868 for (n
= nice_level
+1; n
< 0; n
++)
869 if (set_nice(n
) >= 0) {
870 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n
, nice_level
);
874 pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno
));
879 if (nice_level
< 0) {
880 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS
)) {
881 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
886 pa_log_info("Successfully gained high priority class.");
893 /* Reset the priority to normal, inverting the changes made by
894 * pa_raise_priority() and pa_make_realtime()*/
895 void pa_reset_priority(void) {
896 #ifdef HAVE_SYS_RESOURCE_H
897 struct sched_param sp
;
899 setpriority(PRIO_PROCESS
, 0, 0);
902 pthread_setschedparam(pthread_self(), SCHED_OTHER
, &sp
);
906 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS
);
910 int pa_match(const char *expr
, const char *v
) {
915 if (regcomp(&re
, expr
, REG_NOSUB
|REG_EXTENDED
) != 0) {
920 if ((k
= regexec(&re
, v
, 0, NULL
, 0)) == 0)
922 else if (k
== REG_NOMATCH
)
935 /* Try to parse a boolean string value.*/
936 int pa_parse_boolean(const char *v
) {
939 /* First we check language independent */
940 if (pa_streq(v
, "1") || !strcasecmp(v
, "y") || !strcasecmp(v
, "t")
941 || !strcasecmp(v
, "yes") || !strcasecmp(v
, "true") || !strcasecmp(v
, "on"))
943 else if (pa_streq(v
, "0") || !strcasecmp(v
, "n") || !strcasecmp(v
, "f")
944 || !strcasecmp(v
, "no") || !strcasecmp(v
, "false") || !strcasecmp(v
, "off"))
947 #ifdef HAVE_LANGINFO_H
950 /* And then we check language dependent */
951 if ((expr
= nl_langinfo(YESEXPR
)))
953 if (pa_match(expr
, v
) > 0)
956 if ((expr
= nl_langinfo(NOEXPR
)))
958 if (pa_match(expr
, v
) > 0)
967 /* Try to parse a volume string to pa_volume_t. The allowed formats are:
968 * db, % and unsigned integer */
969 int pa_parse_volume(const char *v
, pa_volume_t
*volume
) {
983 memcpy(str
, v
, len
+ 1);
985 if (str
[len
- 1] == '%') {
987 if (pa_atou(str
, &i
) == 0) {
988 *volume
= PA_CLAMP_VOLUME((uint64_t) PA_VOLUME_NORM
* i
/ 100);
991 } else if (len
> 2 && (str
[len
- 1] == 'b' || str
[len
- 1] == 'B') &&
992 (str
[len
- 2] == 'd' || str
[len
- 2] == 'D')) {
994 if (pa_atod(str
, &d
) == 0) {
995 *volume
= pa_sw_volume_from_dB(d
);
999 if (pa_atou(v
, &i
) == 0) {
1000 *volume
= PA_CLAMP_VOLUME(i
);
1009 /* Split the specified string wherever one of the strings in delimiter
1010 * occurs. Each time it is called returns a newly allocated string
1011 * with pa_xmalloc(). The variable state points to, should be
1012 * initialized to NULL before the first call. */
1013 char *pa_split(const char *c
, const char *delimiter
, const char**state
) {
1014 const char *current
= *state
? *state
: c
;
1020 l
= strcspn(current
, delimiter
);
1026 return pa_xstrndup(current
, l
);
1029 /* Split the specified string wherever one of the strings in delimiter
1030 * occurs. Each time it is called returns a pointer to the substring within the
1031 * string and the length in 'n'. Note that the resultant string cannot be used
1032 * as-is without the length parameter, since it is merely pointing to a point
1033 * within the original string. The variable state points to, should be
1034 * initialized to NULL before the first call. */
1035 const char *pa_split_in_place(const char *c
, const char *delimiter
, int *n
, const char**state
) {
1036 const char *current
= *state
? *state
: c
;
1042 l
= strcspn(current
, delimiter
);
1052 /* Split a string into words. Otherwise similar to pa_split(). */
1053 char *pa_split_spaces(const char *c
, const char **state
) {
1054 const char *current
= *state
? *state
: c
;
1057 if (!*current
|| *c
== 0)
1060 current
+= strspn(current
, WHITESPACE
);
1061 l
= strcspn(current
, WHITESPACE
);
1065 return pa_xstrndup(current
, l
);
1068 PA_STATIC_TLS_DECLARE(signame
, pa_xfree
);
1070 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
1071 const char *pa_sig2str(int sig
) {
1084 char buf
[SIG2STR_MAX
];
1086 if (sig2str(sig
, buf
) == 0) {
1087 pa_xfree(PA_STATIC_TLS_GET(signame
));
1088 t
= pa_sprintf_malloc("SIG%s", buf
);
1089 PA_STATIC_TLS_SET(signame
, t
);
1097 case SIGHUP
: return "SIGHUP";
1099 case SIGINT
: return "SIGINT";
1101 case SIGQUIT
: return "SIGQUIT";
1103 case SIGILL
: return "SIGULL";
1105 case SIGTRAP
: return "SIGTRAP";
1107 case SIGABRT
: return "SIGABRT";
1109 case SIGBUS
: return "SIGBUS";
1111 case SIGFPE
: return "SIGFPE";
1113 case SIGKILL
: return "SIGKILL";
1116 case SIGUSR1
: return "SIGUSR1";
1118 case SIGSEGV
: return "SIGSEGV";
1120 case SIGUSR2
: return "SIGUSR2";
1123 case SIGPIPE
: return "SIGPIPE";
1126 case SIGALRM
: return "SIGALRM";
1128 case SIGTERM
: return "SIGTERM";
1130 case SIGSTKFLT
: return "SIGSTKFLT";
1133 case SIGCHLD
: return "SIGCHLD";
1136 case SIGCONT
: return "SIGCONT";
1139 case SIGSTOP
: return "SIGSTOP";
1142 case SIGTSTP
: return "SIGTSTP";
1145 case SIGTTIN
: return "SIGTTIN";
1148 case SIGTTOU
: return "SIGTTOU";
1151 case SIGURG
: return "SIGURG";
1154 case SIGXCPU
: return "SIGXCPU";
1157 case SIGXFSZ
: return "SIGXFSZ";
1160 case SIGVTALRM
: return "SIGVTALRM";
1163 case SIGPROF
: return "SIGPROF";
1166 case SIGWINCH
: return "SIGWINCH";
1169 case SIGIO
: return "SIGIO";
1172 case SIGPWR
: return "SIGPWR";
1175 case SIGSYS
: return "SIGSYS";
1180 if (sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
1181 pa_xfree(PA_STATIC_TLS_GET(signame
));
1182 t
= pa_sprintf_malloc("SIGRTMIN+%i", sig
- SIGRTMIN
);
1183 PA_STATIC_TLS_SET(signame
, t
);
1192 pa_xfree(PA_STATIC_TLS_GET(signame
));
1193 t
= pa_sprintf_malloc("SIG%i", sig
);
1194 PA_STATIC_TLS_SET(signame
, t
);
1200 /* Check whether the specified GID and the group name match */
1201 static int is_group(gid_t gid
, const char *name
) {
1202 struct group
*group
= NULL
;
1206 if (!(group
= pa_getgrgid_malloc(gid
))) {
1210 pa_log("pa_getgrgid_malloc(%u): %s", gid
, pa_cstrerror(errno
));
1215 r
= pa_streq(name
, group
->gr_name
);
1218 pa_getgrgid_free(group
);
1223 /* Check the current user is member of the specified group */
1224 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1225 GETGROUPS_T
*gids
, tgid
;
1226 long n
= sysconf(_SC_NGROUPS_MAX
);
1231 gids
= pa_xmalloc(sizeof(GETGROUPS_T
) * (size_t) n
);
1233 if ((n
= getgroups((int) n
, gids
)) < 0) {
1234 pa_log("getgroups(): %s", pa_cstrerror(errno
));
1238 for (i
= 0; i
< n
; i
++) {
1240 if ((k
= is_group(gids
[i
], name
)) < 0)
1249 if ((k
= is_group(tgid
= getgid(), name
)) < 0)
1265 /* Check whether the specific user id is a member of the specified group */
1266 int pa_uid_in_group(uid_t uid
, const char *name
) {
1267 struct group
*group
= NULL
;
1272 if (!(group
= pa_getgrnam_malloc(name
))) {
1279 for (i
= group
->gr_mem
; *i
; i
++) {
1280 struct passwd
*pw
= NULL
;
1283 if (!(pw
= pa_getpwnam_malloc(*i
)))
1286 if (pw
->pw_uid
== uid
)
1289 pa_getpwnam_free(pw
);
1296 pa_getgrnam_free(group
);
1301 /* Get the GID of a given group, return (gid_t) -1 on failure. */
1302 gid_t
pa_get_gid_of_group(const char *name
) {
1303 gid_t ret
= (gid_t
) -1;
1304 struct group
*gr
= NULL
;
1307 if (!(gr
= pa_getgrnam_malloc(name
))) {
1316 pa_getgrnam_free(gr
);
1320 int pa_check_in_group(gid_t g
) {
1321 gid_t gids
[NGROUPS_MAX
];
1324 if ((r
= getgroups(NGROUPS_MAX
, gids
)) < 0)
1334 #else /* HAVE_GRP_H */
1336 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1342 int pa_uid_in_group(uid_t uid
, const char *name
) {
1347 gid_t
pa_get_gid_of_group(const char *name
) {
1352 int pa_check_in_group(gid_t g
) {
1359 /* Lock or unlock a file entirely.
1360 (advisory on UNIX, mandatory on Windows) */
1361 int pa_lock_fd(int fd
, int b
) {
1363 struct flock f_lock
;
1365 /* Try a R/W lock first */
1367 f_lock
.l_type
= (short) (b
? F_WRLCK
: F_UNLCK
);
1368 f_lock
.l_whence
= SEEK_SET
;
1372 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1375 /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
1376 if (b
&& errno
== EBADF
) {
1377 f_lock
.l_type
= F_RDLCK
;
1378 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1382 pa_log("%slock: %s", !b
? "un" : "", pa_cstrerror(errno
));
1386 HANDLE h
= (HANDLE
) _get_osfhandle(fd
);
1388 if (b
&& LockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1390 if (!b
&& UnlockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1393 pa_log("%slock failed: 0x%08X", !b
? "un" : "", GetLastError());
1395 /* FIXME: Needs to set errno! */
1401 /* Remove trailing newlines from a string */
1402 char* pa_strip_nl(char *s
) {
1405 s
[strcspn(s
, NEWLINE
)] = 0;
1409 char *pa_strip(char *s
) {
1412 /* Drops trailing whitespace. Modifies the string in
1413 * place. Returns pointer to first non-space character */
1415 s
+= strspn(s
, WHITESPACE
);
1417 for (e
= s
; *e
; e
++)
1418 if (!strchr(WHITESPACE
, *e
))
1429 /* Create a temporary lock file and lock it. */
1430 int pa_lock_lockfile(const char *fn
) {
1437 if ((fd
= pa_open_cloexec(fn
, O_CREAT
|O_RDWR
1441 , S_IRUSR
|S_IWUSR
)) < 0) {
1442 pa_log_warn("Failed to create lock file '%s': %s", fn
, pa_cstrerror(errno
));
1446 if (pa_lock_fd(fd
, 1) < 0) {
1447 pa_log_warn("Failed to lock file '%s'.", fn
);
1451 if (fstat(fd
, &st
) < 0) {
1452 pa_log_warn("Failed to fstat() file '%s': %s", fn
, pa_cstrerror(errno
));
1456 /* Check whether the file has been removed meanwhile. When yes,
1457 * restart this loop, otherwise, we're done */
1458 if (st
.st_nlink
>= 1)
1461 if (pa_lock_fd(fd
, 0) < 0) {
1462 pa_log_warn("Failed to unlock file '%s'.", fn
);
1466 if (pa_close(fd
) < 0) {
1467 pa_log_warn("Failed to close file '%s': %s", fn
, pa_cstrerror(errno
));
1478 int saved_errno
= errno
;
1480 errno
= saved_errno
;
1486 /* Unlock a temporary lock file */
1487 int pa_unlock_lockfile(const char *fn
, int fd
) {
1492 if (unlink(fn
) < 0) {
1493 pa_log_warn("Unable to remove lock file '%s': %s", fn
, pa_cstrerror(errno
));
1498 if (pa_lock_fd(fd
, 0) < 0) {
1499 pa_log_warn("Failed to unlock file '%s'.", fn
);
1503 if (pa_close(fd
) < 0) {
1504 pa_log_warn("Failed to close '%s': %s", fn
, pa_cstrerror(errno
));
1511 static char *get_config_home(char *home
) {
1514 t
= getenv("XDG_CONFIG_HOME");
1516 return pa_xstrdup(t
);
1518 return pa_sprintf_malloc("%s" PA_PATH_SEP
".config", home
);
1521 static int check_ours(const char *p
) {
1526 if (stat(p
, &st
) < 0)
1530 if (st
.st_uid
!= getuid())
1537 static char *get_pulse_home(void) {
1538 char *h
, *ret
, *config_home
;
1541 h
= pa_get_home_dir_malloc();
1543 pa_log_error("Failed to get home directory.");
1548 if (t
< 0 && t
!= -ENOENT
) {
1549 pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t
));
1554 /* If the old directory exists, use it. */
1555 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse", h
);
1556 if (access(ret
, F_OK
) >= 0) {
1562 /* Otherwise go for the XDG compliant directory. */
1563 config_home
= get_config_home(h
);
1565 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", config_home
);
1571 char *pa_get_state_dir(void) {
1574 /* The state directory shall contain dynamic data that should be
1575 * kept across reboots, and is private to this user */
1577 if (!(d
= pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1578 if (!(d
= get_pulse_home()))
1581 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1582 * dir then this will break. */
1584 if (pa_make_secure_dir(d
, 0700U, (uid_t
) -1, (gid_t
) -1, TRUE
) < 0) {
1585 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1593 char *pa_get_home_dir_malloc(void) {
1595 size_t allocated
= 128;
1598 homedir
= pa_xmalloc(allocated
);
1600 if (!pa_get_home_dir(homedir
, allocated
)) {
1605 if (strlen(homedir
) < allocated
- 1)
1615 char *pa_get_binary_name_malloc(void) {
1617 size_t allocated
= 128;
1620 t
= pa_xmalloc(allocated
);
1622 if (!pa_get_binary_name(t
, allocated
)) {
1627 if (strlen(t
) < allocated
- 1)
1637 static char* make_random_dir(mode_t m
) {
1638 static const char table
[] =
1639 "abcdefghijklmnopqrstuvwxyz"
1640 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1646 fn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1647 pathlen
= strlen(fn
);
1655 for (i
= pathlen
- 12; i
< pathlen
; i
++)
1656 fn
[i
] = table
[rand() % (sizeof(table
)-1)];
1658 u
= umask((~m
) & 0777);
1665 saved_errno
= errno
;
1667 errno
= saved_errno
;
1672 if (errno
!= EEXIST
) {
1673 pa_log_error("Failed to create random directory %s: %s", fn
, pa_cstrerror(errno
));
1680 static int make_random_dir_and_link(mode_t m
, const char *k
) {
1683 if (!(p
= make_random_dir(m
)))
1687 if (symlink(p
, k
) < 0) {
1688 int saved_errno
= errno
;
1690 if (errno
!= EEXIST
)
1691 pa_log_error("Failed to symlink %s to %s: %s", k
, p
, pa_cstrerror(errno
));
1696 errno
= saved_errno
;
1708 char *pa_get_runtime_dir(void) {
1709 char *d
, *k
= NULL
, *p
= NULL
, *t
= NULL
, *mid
;
1712 /* The runtime directory shall contain dynamic data that needs NOT
1713 * to be kept across reboots and is usually private to the user,
1714 * except in system mode, where it might be accessible by other
1715 * users, too. Since we need POSIX locking and UNIX sockets in
1716 * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
1717 * set create a directory in $HOME and link it to a random subdir
1718 * in /tmp, if it was not explicitly configured. */
1720 m
= pa_in_system_mode() ? 0755U : 0700U;
1722 /* Use the explicitly configured value if it is set */
1723 d
= getenv("PULSE_RUNTIME_PATH");
1726 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, TRUE
) < 0) {
1727 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1731 return pa_xstrdup(d
);
1734 /* Use the XDG standard for the runtime directory. */
1735 d
= getenv("XDG_RUNTIME_DIR");
1737 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", d
);
1739 if (pa_make_secure_dir(k
, m
, (uid_t
) -1, (gid_t
) -1, TRUE
) < 0) {
1740 pa_log_error("Failed to create secure directory (%s): %s", k
, pa_cstrerror(errno
));
1747 /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
1748 d
= get_pulse_home();
1752 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, TRUE
) < 0) {
1753 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1758 mid
= pa_machine_id();
1764 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-runtime", d
, mid
);
1769 /* OK, first let's check if the "runtime" symlink already exists */
1774 if (errno
!= ENOENT
) {
1775 pa_log_error("Failed to stat runtime directory %s: %s", k
, pa_cstrerror(errno
));
1780 /* Hmm, so the runtime directory didn't exist yet, so let's
1781 * create one in /tmp and symlink that to it */
1783 if (make_random_dir_and_link(0700, k
) < 0) {
1785 /* Mhmm, maybe another process was quicker than us,
1786 * let's check if that was valid */
1787 if (errno
== EEXIST
)
1793 /* No symlink possible, so let's just create the runtime directly
1794 * Do not check again if it exists since it cannot be a symlink */
1795 if (mkdir(k
) < 0 && errno
!= EEXIST
)
1802 /* Make sure that this actually makes sense */
1803 if (!pa_is_path_absolute(p
)) {
1804 pa_log_error("Path %s in link %s is not absolute.", p
, k
);
1809 /* Hmm, so this symlink is still around, make sure nobody fools us */
1813 if (lstat(p
, &st
) < 0) {
1815 if (errno
!= ENOENT
) {
1816 pa_log_error("Failed to stat runtime directory %s: %s", p
, pa_cstrerror(errno
));
1822 if (S_ISDIR(st
.st_mode
) &&
1823 (st
.st_uid
== getuid()) &&
1824 ((st
.st_mode
& 0777) == 0700)) {
1830 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1838 /* Hmm, so the link points to some nonexisting or invalid
1839 * dir. Let's replace it by a new link. We first create a
1840 * temporary link and then rename that to allow concurrent
1841 * execution of this function. */
1843 t
= pa_sprintf_malloc("%s.tmp", k
);
1845 if (make_random_dir_and_link(0700, t
) < 0) {
1847 if (errno
!= EEXIST
) {
1848 pa_log_error("Failed to symlink %s: %s", t
, pa_cstrerror(errno
));
1855 /* Hmm, someone else was quicker then us. Let's give
1856 * him some time to finish, and retry. */
1861 /* OK, we succeeded in creating the temporary symlink, so
1862 * let's rename it */
1863 if (rename(t
, k
) < 0) {
1864 pa_log_error("Failed to rename %s to %s: %s", t
, k
, pa_cstrerror(errno
));
1880 /* Try to open a configuration file. If "env" is specified, open the
1881 * value of the specified environment variable. Otherwise look for a
1882 * file "local" in the home directory or a file "global" in global
1883 * file system. If "result" is non-NULL, a pointer to a newly
1884 * allocated buffer containing the used configuration file is
1886 FILE *pa_open_config_file(const char *global
, const char *local
, const char *env
, char **result
) {
1890 if (env
&& (fn
= getenv(env
))) {
1891 if ((f
= pa_fopen_cloexec(fn
, "r"))) {
1893 *result
= pa_xstrdup(fn
);
1898 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1907 if ((e
= getenv("PULSE_CONFIG_PATH"))) {
1908 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1909 f
= pa_fopen_cloexec(fn
, "r");
1910 } else if ((h
= pa_get_home_dir_malloc())) {
1911 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1912 f
= pa_fopen_cloexec(fn
, "r");
1915 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".config/pulse" PA_PATH_SEP
"%s", h
, local
);
1916 f
= pa_fopen_cloexec(fn
, "r");
1924 *result
= pa_xstrdup(fn
);
1930 if (errno
!= ENOENT
) {
1931 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1943 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
1944 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
1945 pa_win32_get_toplevel(NULL
),
1946 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
1949 gfn
= pa_xstrdup(global
);
1951 if ((f
= pa_fopen_cloexec(gfn
, "r"))) {
1966 char *pa_find_config_file(const char *global
, const char *local
, const char *env
) {
1969 if (env
&& (fn
= getenv(env
))) {
1970 if (access(fn
, R_OK
) == 0)
1971 return pa_xstrdup(fn
);
1973 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1982 if ((e
= getenv("PULSE_CONFIG_PATH")))
1983 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1984 else if ((h
= pa_get_home_dir_malloc())) {
1985 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1990 if (access(fn
, R_OK
) == 0) {
1991 char *r
= pa_xstrdup(fn
);
1996 if (errno
!= ENOENT
) {
1997 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2009 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
2010 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
2011 pa_win32_get_toplevel(NULL
),
2012 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
2015 gfn
= pa_xstrdup(global
);
2017 if (access(gfn
, R_OK
) == 0)
2027 /* Format the specified data as a hexademical string */
2028 char *pa_hexstr(const uint8_t* d
, size_t dlength
, char *s
, size_t slength
) {
2029 size_t i
= 0, j
= 0;
2030 const char hex
[] = "0123456789abcdef";
2034 pa_assert(slength
> 0);
2036 while (j
+2 < slength
&& i
< dlength
) {
2037 s
[j
++] = hex
[*d
>> 4];
2038 s
[j
++] = hex
[*d
& 0xF];
2044 s
[j
< slength
? j
: slength
] = 0;
2048 /* Convert a hexadecimal digit to a number or -1 if invalid */
2049 static int hexc(char c
) {
2050 if (c
>= '0' && c
<= '9')
2053 if (c
>= 'A' && c
<= 'F')
2054 return c
- 'A' + 10;
2056 if (c
>= 'a' && c
<= 'f')
2057 return c
- 'a' + 10;
2063 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
2064 size_t pa_parsehex(const char *p
, uint8_t *d
, size_t dlength
) {
2070 while (j
< dlength
&& *p
) {
2073 if ((b
= hexc(*(p
++))) < 0)
2076 d
[j
] = (uint8_t) (b
<< 4);
2081 if ((b
= hexc(*(p
++))) < 0)
2084 d
[j
] |= (uint8_t) b
;
2091 /* Returns nonzero when *s starts with *pfx */
2092 pa_bool_t
pa_startswith(const char *s
, const char *pfx
) {
2100 return strlen(s
) >= l
&& strncmp(s
, pfx
, l
) == 0;
2103 /* Returns nonzero when *s ends with *sfx */
2104 pa_bool_t
pa_endswith(const char *s
, const char *sfx
) {
2113 return l1
>= l2
&& pa_streq(s
+ l1
- l2
, sfx
);
2116 pa_bool_t
pa_is_path_absolute(const char *fn
) {
2122 return strlen(fn
) >= 3 && isalpha(fn
[0]) && fn
[1] == ':' && fn
[2] == '\\';
2126 char *pa_make_path_absolute(const char *p
) {
2132 if (pa_is_path_absolute(p
))
2133 return pa_xstrdup(p
);
2135 if (!(cwd
= pa_getcwd()))
2136 return pa_xstrdup(p
);
2138 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", cwd
, p
);
2143 /* If fn is NULL, return the PulseAudio runtime or state dir (depending on the
2144 * rt parameter). If fn is non-NULL and starts with /, return fn. Otherwise,
2145 * append fn to the runtime/state dir and return it. */
2146 static char *get_path(const char *fn
, pa_bool_t prependmid
, pa_bool_t rt
) {
2149 rtp
= rt
? pa_get_runtime_dir() : pa_get_state_dir();
2152 char *r
, *canonical_rtp
;
2154 if (pa_is_path_absolute(fn
)) {
2156 return pa_xstrdup(fn
);
2162 /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
2163 if ((canonical_rtp
= pa_realpath(rtp
))) {
2164 if (strlen(rtp
) >= strlen(canonical_rtp
))
2167 pa_xfree(canonical_rtp
);
2168 canonical_rtp
= rtp
;
2171 canonical_rtp
= rtp
;
2176 if (!(mid
= pa_machine_id())) {
2177 pa_xfree(canonical_rtp
);
2181 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-%s", canonical_rtp
, mid
, fn
);
2184 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", canonical_rtp
, fn
);
2186 pa_xfree(canonical_rtp
);
2192 char *pa_runtime_path(const char *fn
) {
2193 return get_path(fn
, FALSE
, TRUE
);
2196 char *pa_state_path(const char *fn
, pa_bool_t appendmid
) {
2197 return get_path(fn
, appendmid
, FALSE
);
2200 /* Convert the string s to a signed integer in *ret_i */
2201 int pa_atoi(const char *s
, int32_t *ret_i
) {
2207 if (pa_atol(s
, &l
) < 0)
2210 if ((int32_t) l
!= l
) {
2215 *ret_i
= (int32_t) l
;
2220 /* Convert the string s to an unsigned integer in *ret_u */
2221 int pa_atou(const char *s
, uint32_t *ret_u
) {
2229 l
= strtoul(s
, &x
, 0);
2231 if (!x
|| *x
|| errno
) {
2237 if ((uint32_t) l
!= l
) {
2242 *ret_u
= (uint32_t) l
;
2247 /* Convert the string s to a signed long integer in *ret_l. */
2248 int pa_atol(const char *s
, long *ret_l
) {
2256 l
= strtol(s
, &x
, 0);
2258 if (!x
|| *x
|| errno
) {
2269 #ifdef HAVE_STRTOF_L
2270 static locale_t c_locale
= NULL
;
2272 static void c_locale_destroy(void) {
2273 freelocale(c_locale
);
2277 int pa_atod(const char *s
, double *ret_d
) {
2284 /* This should be locale independent */
2286 #ifdef HAVE_STRTOF_L
2290 if ((c_locale
= newlocale(LC_ALL_MASK
, "C", NULL
)))
2291 atexit(c_locale_destroy
);
2297 f
= strtod_l(s
, &x
, c_locale
);
2305 if (!x
|| *x
|| errno
) {
2316 /* Same as snprintf, but guarantees NUL-termination on every platform */
2317 size_t pa_snprintf(char *str
, size_t size
, const char *format
, ...) {
2322 pa_assert(size
> 0);
2325 va_start(ap
, format
);
2326 ret
= pa_vsnprintf(str
, size
, format
, ap
);
2332 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2333 size_t pa_vsnprintf(char *str
, size_t size
, const char *format
, va_list ap
) {
2337 pa_assert(size
> 0);
2340 ret
= vsnprintf(str
, size
, format
, ap
);
2347 if ((size_t) ret
> size
-1)
2350 return (size_t) ret
;
2353 /* Truncate the specified string, but guarantee that the string
2354 * returned still validates as UTF8 */
2355 char *pa_truncate_utf8(char *c
, size_t l
) {
2357 pa_assert(pa_utf8_valid(c
));
2364 while (l
> 0 && !pa_utf8_valid(c
))
2370 char *pa_getcwd(void) {
2374 char *p
= pa_xmalloc(l
);
2378 if (errno
!= ERANGE
)
2386 void *pa_will_need(const void *p
, size_t l
) {
2387 #ifdef RLIMIT_MEMLOCK
2398 a
= PA_PAGE_ALIGN_PTR(p
);
2399 size
= (size_t) ((const uint8_t*) p
+ l
- (const uint8_t*) a
);
2401 #ifdef HAVE_POSIX_MADVISE
2402 if ((r
= posix_madvise((void*) a
, size
, POSIX_MADV_WILLNEED
)) == 0) {
2403 pa_log_debug("posix_madvise() worked fine!");
2408 /* Most likely the memory was not mmap()ed from a file and thus
2409 * madvise() didn't work, so let's misuse mlock() do page this
2410 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2411 * inviting, the man page of mlock() tells us: "All pages that
2412 * contain a part of the specified address range are guaranteed to
2413 * be resident in RAM when the call returns successfully." */
2415 #ifdef RLIMIT_MEMLOCK
2416 pa_assert_se(getrlimit(RLIMIT_MEMLOCK
, &rlim
) == 0);
2418 if (rlim
.rlim_cur
< PA_PAGE_SIZE
) {
2419 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
));
2424 bs
= PA_PAGE_ALIGN((size_t) rlim
.rlim_cur
);
2426 bs
= PA_PAGE_SIZE
*4;
2429 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r
));
2432 while (size
> 0 && bs
> 0) {
2437 if (mlock(a
, bs
) < 0) {
2438 bs
= PA_PAGE_ALIGN(bs
/ 2);
2442 pa_assert_se(munlock(a
, bs
) == 0);
2444 a
= (const uint8_t*) a
+ bs
;
2450 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno
));
2452 pa_log_debug("mlock() worked fine!");
2457 void pa_close_pipe(int fds
[2]) {
2461 pa_assert_se(pa_close(fds
[0]) == 0);
2464 pa_assert_se(pa_close(fds
[1]) == 0);
2466 fds
[0] = fds
[1] = -1;
2469 char *pa_readlink(const char *p
) {
2470 #ifdef HAVE_READLINK
2479 if ((n
= readlink(p
, c
, l
-1)) < 0) {
2484 if ((size_t) n
< l
-1) {
2497 int pa_close_all(int except_fd
, ...) {
2502 va_start(ap
, except_fd
);
2505 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2510 p
= pa_xnew(int, n
+1);
2512 va_start(ap
, except_fd
);
2515 if (except_fd
>= 0) {
2519 while ((fd
= va_arg(ap
, int)) >= 0)
2526 r
= pa_close_allv(p
);
2532 int pa_close_allv(const int except_fds
[]) {
2541 if ((d
= opendir("/proc/self/fd"))) {
2545 while ((de
= readdir(d
))) {
2551 if (de
->d_name
[0] == '.')
2555 l
= strtol(de
->d_name
, &e
, 10);
2556 if (errno
!= 0 || !e
|| *e
) {
2564 if ((long) fd
!= l
) {
2577 for (i
= 0; except_fds
[i
] >= 0; i
++)
2578 if (except_fds
[i
] == fd
) {
2586 if (pa_close(fd
) < 0) {
2587 saved_errno
= errno
;
2589 errno
= saved_errno
;
2601 if (getrlimit(RLIMIT_NOFILE
, &rl
) >= 0)
2602 maxfd
= (int) rl
.rlim_max
;
2604 maxfd
= sysconf(_SC_OPEN_MAX
);
2606 for (fd
= 3; fd
< maxfd
; fd
++) {
2611 for (i
= 0; except_fds
[i
] >= 0; i
++)
2612 if (except_fds
[i
] == fd
) {
2620 if (pa_close(fd
) < 0 && errno
!= EBADF
)
2623 #endif /* !OS_IS_WIN32 */
2628 int pa_unblock_sigs(int except
, ...) {
2633 va_start(ap
, except
);
2636 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2641 p
= pa_xnew(int, n
+1);
2643 va_start(ap
, except
);
2650 while ((sig
= va_arg(ap
, int)) >= 0)
2657 r
= pa_unblock_sigsv(p
);
2663 int pa_unblock_sigsv(const int except
[]) {
2668 if (sigemptyset(&ss
) < 0)
2671 for (i
= 0; except
[i
] > 0; i
++)
2672 if (sigaddset(&ss
, except
[i
]) < 0)
2675 return sigprocmask(SIG_SETMASK
, &ss
, NULL
);
2681 int pa_reset_sigs(int except
, ...) {
2686 va_start(ap
, except
);
2689 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2694 p
= pa_xnew(int, n
+1);
2696 va_start(ap
, except
);
2703 while ((sig
= va_arg(ap
, int)) >= 0)
2710 r
= pa_reset_sigsv(p
);
2716 int pa_reset_sigsv(const int except
[]) {
2720 for (sig
= 1; sig
< NSIG
; sig
++) {
2721 pa_bool_t reset
= TRUE
;
2732 for (i
= 0; except
[i
] > 0; i
++) {
2733 if (sig
== except
[i
]) {
2742 struct sigaction sa
;
2744 memset(&sa
, 0, sizeof(sa
));
2745 sa
.sa_handler
= SIG_DFL
;
2747 /* On Linux the first two RT signals are reserved by
2748 * glibc, and sigaction() will return EINVAL for them. */
2749 if ((sigaction(sig
, &sa
, NULL
) < 0))
2750 if (errno
!= EINVAL
)
2759 void pa_set_env(const char *key
, const char *value
) {
2763 /* This is not thread-safe */
2766 SetEnvironmentVariable(key
, value
);
2768 setenv(key
, value
, 1);
2772 void pa_set_env_and_record(const char *key
, const char *value
) {
2776 /* This is not thread-safe */
2778 pa_set_env(key
, value
);
2779 recorded_env
= pa_strlist_prepend(recorded_env
, key
);
2782 void pa_unset_env_recorded(void) {
2784 /* This is not thread-safe */
2789 recorded_env
= pa_strlist_pop(recorded_env
, &s
);
2795 SetEnvironmentVariable(s
, NULL
);
2803 pa_bool_t
pa_in_system_mode(void) {
2806 if (!(e
= getenv("PULSE_SYSTEM")))
2812 /* Checks a whitespace-separated list of words in haystack for needle */
2813 pa_bool_t
pa_str_in_list_spaces(const char *haystack
, const char *needle
) {
2815 const char *state
= NULL
;
2817 if (!haystack
|| !needle
)
2820 while ((s
= pa_split_spaces(haystack
, &state
))) {
2821 if (pa_streq(needle
, s
)) {
2832 char *pa_get_user_name_malloc(void) {
2836 #ifdef _SC_LOGIN_NAME_MAX
2837 k
= (ssize_t
) sysconf(_SC_LOGIN_NAME_MAX
);
2843 u
= pa_xnew(char, k
+1);
2845 if (!(pa_get_user_name(u
, k
))) {
2853 char *pa_get_host_name_malloc(void) {
2862 if (!pa_get_host_name(c
, l
)) {
2864 if (errno
!= EINVAL
&& errno
!= ENAMETOOLONG
)
2867 } else if (strlen(c
) < l
-1) {
2875 u
= pa_utf8_filter(c
);
2880 /* Hmm, the hostname is as long the space we offered the
2881 * function, we cannot know if it fully fit in, so let's play
2882 * safe and retry. */
2891 char *pa_machine_id(void) {
2895 /* The returned value is supposed be some kind of ascii identifier
2896 * that is unique and stable across reboots. */
2898 /* First we try the /etc/machine-id, which is the best option we
2899 * have, since it fits perfectly our needs and is not as volatile
2900 * as the hostname which might be set from dhcp. */
2902 if ((f
= pa_fopen_cloexec(PA_MACHINE_ID
, "r")) ||
2903 (f
= pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK
, "r"))) {
2904 char ln
[34] = "", *r
;
2906 r
= fgets(ln
, sizeof(ln
)-1, f
);
2912 return pa_utf8_filter(ln
);
2915 if ((h
= pa_get_host_name_malloc()))
2919 /* If no hostname was set we use the POSIX hostid. It's usually
2920 * the IPv4 address. Might not be that stable. */
2921 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
2927 char *pa_session_id(void) {
2930 e
= getenv("XDG_SESSION_ID");
2934 return pa_utf8_filter(e
);
2937 char *pa_uname_string(void) {
2941 pa_assert_se(uname(&u
) >= 0);
2943 return pa_sprintf_malloc("%s %s %s %s", u
.sysname
, u
.machine
, u
.release
, u
.version
);
2949 i
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
2950 pa_assert_se(GetVersionEx(&i
));
2952 return pa_sprintf_malloc("Windows %d.%d (%d) %s", i
.dwMajorVersion
, i
.dwMinorVersion
, i
.dwBuildNumber
, i
.szCSDVersion
);
2956 #ifdef HAVE_VALGRIND_MEMCHECK_H
2957 pa_bool_t
pa_in_valgrind(void) {
2960 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
2961 * here instead of really checking whether we run in valgrind or
2965 b
= getenv("VALGRIND") ? 2 : 1;
2971 unsigned pa_gcd(unsigned a
, unsigned b
) {
2982 void pa_reduce(unsigned *num
, unsigned *den
) {
2984 unsigned gcd
= pa_gcd(*num
, *den
);
2992 pa_assert(pa_gcd(*num
, *den
) == 1);
2995 unsigned pa_ncpus(void) {
2998 #ifdef _SC_NPROCESSORS_CONF
2999 ncpus
= sysconf(_SC_NPROCESSORS_CONF
);
3004 return ncpus
<= 0 ? 1 : (unsigned) ncpus
;
3007 char *pa_replace(const char*s
, const char*a
, const char *b
) {
3016 sb
= pa_strbuf_new();
3021 if (!(p
= strstr(s
, a
)))
3024 pa_strbuf_putsn(sb
, s
, p
-s
);
3025 pa_strbuf_puts(sb
, b
);
3029 pa_strbuf_puts(sb
, s
);
3031 return pa_strbuf_tostring_free(sb
);
3034 char *pa_escape(const char *p
, const char *chars
) {
3037 pa_strbuf
*buf
= pa_strbuf_new();
3039 for (s
= p
; *s
; ++s
) {
3041 pa_strbuf_putc(buf
, '\\');
3043 for (c
= chars
; *c
; ++c
) {
3045 pa_strbuf_putc(buf
, '\\');
3050 pa_strbuf_putc(buf
, *s
);
3053 return pa_strbuf_tostring_free(buf
);
3056 char *pa_unescape(char *p
) {
3058 pa_bool_t escaped
= FALSE
;
3060 for (s
= p
, d
= p
; *s
; s
++) {
3061 if (!escaped
&& *s
== '\\') {
3075 char *pa_realpath(const char *path
) {
3079 /* We want only absolute paths */
3080 if (path
[0] != '/') {
3085 #if defined(__GLIBC__)
3089 if (!(r
= realpath(path
, NULL
)))
3092 /* We copy this here in case our pa_xmalloc() is not
3093 * implemented on top of libc malloc() */
3097 #elif defined(PATH_MAX)
3100 path_buf
= pa_xmalloc(PATH_MAX
);
3102 #if defined(OS_IS_WIN32)
3103 if (!(t
= _fullpath(path_buf
, path
, _MAX_PATH
))) {
3108 if (!(t
= realpath(path
, path_buf
))) {
3115 #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."
3121 void pa_disable_sigpipe(void) {
3124 struct sigaction sa
;
3128 if (sigaction(SIGPIPE
, NULL
, &sa
) < 0) {
3129 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3133 sa
.sa_handler
= SIG_IGN
;
3135 if (sigaction(SIGPIPE
, &sa
, NULL
) < 0) {
3136 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3142 void pa_xfreev(void**a
) {
3148 for (p
= a
; *p
; p
++)
3154 char **pa_split_spaces_strv(const char *s
) {
3156 unsigned i
= 0, n
= 8;
3157 const char *state
= NULL
;
3159 t
= pa_xnew(char*, n
);
3160 while ((e
= pa_split_spaces(s
, &state
))) {
3165 t
= pa_xrenew(char*, t
, n
);
3178 char* pa_maybe_prefix_path(const char *path
, const char *prefix
) {
3181 if (pa_is_path_absolute(path
))
3182 return pa_xstrdup(path
);
3184 return pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", prefix
, path
);
3187 size_t pa_pipe_buf(int fd
) {
3192 if ((n
= fpathconf(fd
, _PC_PIPE_BUF
)) >= 0)
3203 void pa_reset_personality(void) {
3206 if (personality(PER_LINUX
) < 0)
3207 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno
));
3212 pa_bool_t
pa_run_from_build_tree(void) {
3214 static pa_bool_t b
= FALSE
;
3217 if ((rp
= pa_readlink("/proc/self/exe"))) {
3218 b
= pa_startswith(rp
, PA_BUILDDIR
);
3226 const char *pa_get_temp_dir(void) {
3229 if ((t
= getenv("TMPDIR")) &&
3230 pa_is_path_absolute(t
))
3233 if ((t
= getenv("TMP")) &&
3234 pa_is_path_absolute(t
))
3237 if ((t
= getenv("TEMP")) &&
3238 pa_is_path_absolute(t
))
3241 if ((t
= getenv("TEMPDIR")) &&
3242 pa_is_path_absolute(t
))
3248 int pa_open_cloexec(const char *fn
, int flags
, mode_t mode
) {
3256 if ((fd
= open(fn
, flags
|O_CLOEXEC
, mode
)) >= 0)
3259 if (errno
!= EINVAL
)
3263 if ((fd
= open(fn
, flags
, mode
)) < 0)
3267 /* Some implementations might simply ignore O_CLOEXEC if it is not
3268 * understood, make sure FD_CLOEXEC is enabled anyway */
3270 pa_make_fd_cloexec(fd
);
3274 int pa_socket_cloexec(int domain
, int type
, int protocol
) {
3278 if ((fd
= socket(domain
, type
| SOCK_CLOEXEC
, protocol
)) >= 0)
3281 if (errno
!= EINVAL
)
3285 if ((fd
= socket(domain
, type
, protocol
)) < 0)
3289 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3290 * not understood, make sure FD_CLOEXEC is enabled anyway */
3292 pa_make_fd_cloexec(fd
);
3296 int pa_pipe_cloexec(int pipefd
[2]) {
3300 if ((r
= pipe2(pipefd
, O_CLOEXEC
)) >= 0)
3303 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3308 if ((r
= pipe(pipefd
)) < 0)
3312 pa_make_fd_cloexec(pipefd
[0]);
3313 pa_make_fd_cloexec(pipefd
[1]);
3318 int pa_accept_cloexec(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
) {
3322 if ((fd
= accept4(sockfd
, addr
, addrlen
, SOCK_CLOEXEC
)) >= 0)
3325 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3330 if ((fd
= accept(sockfd
, addr
, addrlen
)) < 0)
3334 pa_make_fd_cloexec(fd
);
3338 FILE* pa_fopen_cloexec(const char *path
, const char *mode
) {
3342 m
= pa_sprintf_malloc("%se", mode
);
3345 if ((f
= fopen(path
, m
))) {
3352 if (errno
!= EINVAL
)
3355 if (!(f
= fopen(path
, mode
)))
3359 pa_make_fd_cloexec(fileno(f
));
3363 void pa_nullify_stdfds(void) {
3366 pa_close(STDIN_FILENO
);
3367 pa_close(STDOUT_FILENO
);
3368 pa_close(STDERR_FILENO
);
3370 pa_assert_se(open("/dev/null", O_RDONLY
) == STDIN_FILENO
);
3371 pa_assert_se(open("/dev/null", O_WRONLY
) == STDOUT_FILENO
);
3372 pa_assert_se(open("/dev/null", O_WRONLY
) == STDERR_FILENO
);
3379 char *pa_read_line_from_file(const char *fn
) {
3381 char ln
[256] = "", *r
;
3383 if (!(f
= pa_fopen_cloexec(fn
, "r")))
3386 r
= fgets(ln
, sizeof(ln
)-1, f
);
3395 return pa_xstrdup(ln
);
3398 pa_bool_t
pa_running_in_vm(void) {
3400 #if defined(__i386__) || defined(__x86_64__)
3402 /* Both CPUID and DMI are x86 specific interfaces... */
3404 uint32_t eax
= 0x40000000;
3411 const char *const dmi_vendors
[] = {
3412 "/sys/class/dmi/id/sys_vendor",
3413 "/sys/class/dmi/id/board_vendor",
3414 "/sys/class/dmi/id/bios_vendor"
3419 for (i
= 0; i
< PA_ELEMENTSOF(dmi_vendors
); i
++) {
3422 if ((s
= pa_read_line_from_file(dmi_vendors
[i
]))) {
3424 if (pa_startswith(s
, "QEMU") ||
3425 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3426 pa_startswith(s
, "VMware") ||
3427 pa_startswith(s
, "VMW") ||
3428 pa_startswith(s
, "Microsoft Corporation") ||
3429 pa_startswith(s
, "innotek GmbH") ||
3430 pa_startswith(s
, "Xen")) {
3442 /* http://lwn.net/Articles/301888/ */
3445 __asm__
__volatile__ (
3446 /* ebx/rbx is being used for PIC! */
3447 " push %%"PA_REG_b
" \n\t"
3449 " mov %%ebx, %1 \n\t"
3450 " pop %%"PA_REG_b
" \n\t"
3452 : "=a" (eax
), "=r" (sig
.sig32
[0]), "=c" (sig
.sig32
[1]), "=d" (sig
.sig32
[2])
3456 if (pa_streq(sig
.text
, "XenVMMXenVMM") ||
3457 pa_streq(sig
.text
, "KVMKVMKVM") ||
3458 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3459 pa_streq(sig
.text
, "VMwareVMware") ||
3460 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3461 pa_streq(sig
.text
, "Microsoft Hv"))