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) {
422 if ((r
= send(fd
, buf
, count
, MSG_NOSIGNAL
)) < 0) {
434 err
= WSAGetLastError();
435 if (err
!= WSAENOTSOCK
) {
436 /* transparently handle non-blocking sockets, by waiting
438 if (err
== WSAEWOULDBLOCK
) {
441 pfd
.events
= POLLOUT
;
442 if (pa_poll(&pfd
, 1, -1) >= 0) {
450 if (errno
!= ENOTSOCK
)
461 if ((r
= write(fd
, buf
, count
)) < 0)
469 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
470 * unless EOF is reached or an error occurred */
471 ssize_t
pa_loop_read(int fd
, void*data
, size_t size
, int *type
) {
487 if ((r
= pa_read(fd
, data
, size
, type
)) < 0)
494 data
= (uint8_t*) data
+ r
;
501 /** Similar to pa_loop_read(), but wraps write() */
502 ssize_t
pa_loop_write(int fd
, const void*data
, size_t size
, int *type
) {
518 if ((r
= pa_write(fd
, data
, size
, type
)) < 0)
525 data
= (const uint8_t*) data
+ r
;
532 /** Platform independent read function. Necessary since not all
533 * systems treat all file descriptors equal. */
534 int pa_close(int fd
) {
539 if ((ret
= closesocket(fd
)) == 0)
542 if (WSAGetLastError() != WSAENOTSOCK
) {
543 errno
= WSAGetLastError();
551 if ((r
= close(fd
)) < 0)
559 /* Print a warning messages in case that the given signal is not
560 * blocked or trapped */
561 void pa_check_signal_is_blocked(int sig
) {
562 #ifdef HAVE_SIGACTION
566 /* If POSIX threads are supported use thread-aware
567 * pthread_sigmask() function, to check if the signal is
568 * blocked. Otherwise fall back to sigprocmask() */
571 if (pthread_sigmask(SIG_SETMASK
, NULL
, &set
) < 0) {
573 if (sigprocmask(SIG_SETMASK
, NULL
, &set
) < 0) {
574 pa_log("sigprocmask(): %s", pa_cstrerror(errno
));
581 if (sigismember(&set
, sig
))
584 /* Check whether the signal is trapped */
586 if (sigaction(sig
, NULL
, &sa
) < 0) {
587 pa_log("sigaction(): %s", pa_cstrerror(errno
));
591 if (sa
.sa_handler
!= SIG_DFL
)
594 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig
));
595 #else /* HAVE_SIGACTION */
596 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig
));
600 /* The following function is based on an example from the GNU libc
601 * documentation. This function is similar to GNU's asprintf(). */
602 char *pa_sprintf_malloc(const char *format
, ...) {
612 c
= pa_xrealloc(c
, size
);
614 va_start(ap
, format
);
615 r
= vsnprintf(c
, size
, format
, ap
);
620 if (r
> -1 && (size_t) r
< size
)
623 if (r
> -1) /* glibc 2.1 */
630 /* Same as the previous function, but use a va_list instead of an
632 char *pa_vsprintf_malloc(const char *format
, va_list ap
) {
642 c
= pa_xrealloc(c
, size
);
645 r
= vsnprintf(c
, size
, format
, aq
);
650 if (r
> -1 && (size_t) r
< size
)
653 if (r
> -1) /* glibc 2.1 */
660 /* Similar to OpenBSD's strlcpy() function */
661 char *pa_strlcpy(char *b
, const char *s
, size_t l
) {
679 #ifdef _POSIX_PRIORITY_SCHEDULING
680 static int set_scheduler(int rtprio
) {
682 struct sched_param sp
;
688 dbus_error_init(&error
);
692 sp
.sched_priority
= rtprio
;
694 #ifdef SCHED_RESET_ON_FORK
695 if (pthread_setschedparam(pthread_self(), SCHED_RR
|SCHED_RESET_ON_FORK
, &sp
) == 0) {
696 pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
701 if (pthread_setschedparam(pthread_self(), SCHED_RR
, &sp
) == 0) {
702 pa_log_debug("SCHED_RR worked.");
705 #endif /* HAVE_SCHED_H */
708 /* Try to talk to RealtimeKit */
710 if (!(bus
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
))) {
711 pa_log("Failed to connect to system bus: %s\n", error
.message
);
712 dbus_error_free(&error
);
717 /* We need to disable exit on disconnect because otherwise
718 * dbus_shutdown will kill us. See
719 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
720 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
722 r
= rtkit_make_realtime(bus
, 0, rtprio
);
723 dbus_connection_close(bus
);
724 dbus_connection_unref(bus
);
727 pa_log_debug("RealtimeKit worked.");
740 /* Make the current thread a realtime thread, and acquire the highest
741 * rtprio we can get that is less or equal the specified parameter. If
742 * the thread is already realtime, don't do anything. */
743 int pa_make_realtime(int rtprio
) {
745 #if defined(OS_IS_DARWIN)
746 struct thread_time_constraint_policy ttcpolicy
;
748 size_t size
= sizeof(freq
);
751 ret
= sysctlbyname("hw.cpufrequency", &freq
, &size
, NULL
, 0);
753 pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
757 pa_log_debug("sysctl for hw.cpufrequency: %llu", freq
);
759 /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
760 ttcpolicy
.period
= freq
/ 160;
761 ttcpolicy
.computation
= freq
/ 3300;
762 ttcpolicy
.constraint
= freq
/ 2200;
763 ttcpolicy
.preemptible
= 1;
765 ret
= thread_policy_set(mach_thread_self(),
766 THREAD_TIME_CONSTRAINT_POLICY
,
767 (thread_policy_t
) &ttcpolicy
,
768 THREAD_TIME_CONSTRAINT_POLICY_COUNT
);
770 pa_log_info("Unable to set real-time thread priority (%08x).", ret
);
774 pa_log_info("Successfully acquired real-time thread priority.");
777 #elif defined(_POSIX_PRIORITY_SCHEDULING)
780 if (set_scheduler(rtprio
) >= 0) {
781 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio
);
785 for (p
= rtprio
-1; p
>= 1; p
--)
786 if (set_scheduler(p
) >= 0) {
787 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p
, rtprio
);
790 #elif defined(OS_IS_WIN32)
791 /* Windows only allows realtime scheduling to be set on a per process basis.
792 * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
793 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL
)) {
794 pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
798 pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
803 pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno
));
807 #ifdef HAVE_SYS_RESOURCE_H
808 static int set_nice(int nice_level
) {
814 dbus_error_init(&error
);
817 #ifdef HAVE_SYS_RESOURCE_H
818 if (setpriority(PRIO_PROCESS
, 0, nice_level
) >= 0) {
819 pa_log_debug("setpriority() worked.");
825 /* Try to talk to RealtimeKit */
827 if (!(bus
= dbus_bus_get(DBUS_BUS_SYSTEM
, &error
))) {
828 pa_log("Failed to connect to system bus: %s\n", error
.message
);
829 dbus_error_free(&error
);
834 /* We need to disable exit on disconnect because otherwise
835 * dbus_shutdown will kill us. See
836 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
837 dbus_connection_set_exit_on_disconnect(bus
, FALSE
);
839 r
= rtkit_make_high_priority(bus
, 0, nice_level
);
840 dbus_connection_unref(bus
);
843 pa_log_debug("RealtimeKit worked.");
854 /* Raise the priority of the current process as much as possible that
855 * is <= the specified nice level..*/
856 int pa_raise_priority(int nice_level
) {
858 #ifdef HAVE_SYS_RESOURCE_H
861 if (set_nice(nice_level
) >= 0) {
862 pa_log_info("Successfully gained nice level %i.", nice_level
);
866 for (n
= nice_level
+1; n
< 0; n
++)
867 if (set_nice(n
) >= 0) {
868 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n
, nice_level
);
872 pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno
));
877 if (nice_level
< 0) {
878 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS
)) {
879 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
884 pa_log_info("Successfully gained high priority class.");
891 /* Reset the priority to normal, inverting the changes made by
892 * pa_raise_priority() and pa_make_realtime()*/
893 void pa_reset_priority(void) {
894 #ifdef HAVE_SYS_RESOURCE_H
895 struct sched_param sp
;
897 setpriority(PRIO_PROCESS
, 0, 0);
900 pthread_setschedparam(pthread_self(), SCHED_OTHER
, &sp
);
904 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS
);
908 int pa_match(const char *expr
, const char *v
) {
913 if (regcomp(&re
, expr
, REG_NOSUB
|REG_EXTENDED
) != 0) {
918 if ((k
= regexec(&re
, v
, 0, NULL
, 0)) == 0)
920 else if (k
== REG_NOMATCH
)
933 /* Try to parse a boolean string value.*/
934 int pa_parse_boolean(const char *v
) {
937 /* First we check language independent */
938 if (pa_streq(v
, "1") || v
[0] == 'y' || v
[0] == 'Y' || v
[0] == 't' || v
[0] == 'T' || !strcasecmp(v
, "on"))
940 else if (pa_streq(v
, "0") || v
[0] == 'n' || v
[0] == 'N' || v
[0] == 'f' || v
[0] == 'F' || !strcasecmp(v
, "off"))
943 #ifdef HAVE_LANGINFO_H
946 /* And then we check language dependent */
947 if ((expr
= nl_langinfo(YESEXPR
)))
949 if (pa_match(expr
, v
) > 0)
952 if ((expr
= nl_langinfo(NOEXPR
)))
954 if (pa_match(expr
, v
) > 0)
963 /* Try to parse a volume string to pa_volume_t. The allowed formats are:
964 * db, % and unsigned integer */
965 int pa_parse_volume(const char *v
, pa_volume_t
*volume
) {
979 memcpy(str
, v
, len
+ 1);
981 if (str
[len
- 1] == '%') {
983 if (pa_atou(str
, &i
) == 0) {
984 *volume
= PA_CLAMP_VOLUME((uint64_t) PA_VOLUME_NORM
* i
/ 100);
987 } else if (len
> 2 && (str
[len
- 1] == 'b' || str
[len
- 1] == 'B') &&
988 (str
[len
- 2] == 'd' || str
[len
- 2] == 'D')) {
990 if (pa_atod(str
, &d
) == 0) {
991 *volume
= pa_sw_volume_from_dB(d
);
995 if (pa_atou(v
, &i
) == 0) {
996 *volume
= PA_CLAMP_VOLUME(i
);
1005 /* Split the specified string wherever one of the strings in delimiter
1006 * occurs. Each time it is called returns a newly allocated string
1007 * with pa_xmalloc(). The variable state points to, should be
1008 * initialized to NULL before the first call. */
1009 char *pa_split(const char *c
, const char *delimiter
, const char**state
) {
1010 const char *current
= *state
? *state
: c
;
1016 l
= strcspn(current
, delimiter
);
1022 return pa_xstrndup(current
, l
);
1025 /* Split the specified string wherever one of the strings in delimiter
1026 * occurs. Each time it is called returns a pointer to the substring within the
1027 * string and the length in 'n'. Note that the resultant string cannot be used
1028 * as-is without the length parameter, since it is merely pointing to a point
1029 * within the original string. The variable state points to, should be
1030 * initialized to NULL before the first call. */
1031 const char *pa_split_in_place(const char *c
, const char *delimiter
, int *n
, const char**state
) {
1032 const char *current
= *state
? *state
: c
;
1038 l
= strcspn(current
, delimiter
);
1048 /* Split a string into words. Otherwise similar to pa_split(). */
1049 char *pa_split_spaces(const char *c
, const char **state
) {
1050 const char *current
= *state
? *state
: c
;
1053 if (!*current
|| *c
== 0)
1056 current
+= strspn(current
, WHITESPACE
);
1057 l
= strcspn(current
, WHITESPACE
);
1061 return pa_xstrndup(current
, l
);
1064 PA_STATIC_TLS_DECLARE(signame
, pa_xfree
);
1066 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
1067 const char *pa_sig2str(int sig
) {
1080 char buf
[SIG2STR_MAX
];
1082 if (sig2str(sig
, buf
) == 0) {
1083 pa_xfree(PA_STATIC_TLS_GET(signame
));
1084 t
= pa_sprintf_malloc("SIG%s", buf
);
1085 PA_STATIC_TLS_SET(signame
, t
);
1093 case SIGHUP
: return "SIGHUP";
1095 case SIGINT
: return "SIGINT";
1097 case SIGQUIT
: return "SIGQUIT";
1099 case SIGILL
: return "SIGULL";
1101 case SIGTRAP
: return "SIGTRAP";
1103 case SIGABRT
: return "SIGABRT";
1105 case SIGBUS
: return "SIGBUS";
1107 case SIGFPE
: return "SIGFPE";
1109 case SIGKILL
: return "SIGKILL";
1112 case SIGUSR1
: return "SIGUSR1";
1114 case SIGSEGV
: return "SIGSEGV";
1116 case SIGUSR2
: return "SIGUSR2";
1119 case SIGPIPE
: return "SIGPIPE";
1122 case SIGALRM
: return "SIGALRM";
1124 case SIGTERM
: return "SIGTERM";
1126 case SIGSTKFLT
: return "SIGSTKFLT";
1129 case SIGCHLD
: return "SIGCHLD";
1132 case SIGCONT
: return "SIGCONT";
1135 case SIGSTOP
: return "SIGSTOP";
1138 case SIGTSTP
: return "SIGTSTP";
1141 case SIGTTIN
: return "SIGTTIN";
1144 case SIGTTOU
: return "SIGTTOU";
1147 case SIGURG
: return "SIGURG";
1150 case SIGXCPU
: return "SIGXCPU";
1153 case SIGXFSZ
: return "SIGXFSZ";
1156 case SIGVTALRM
: return "SIGVTALRM";
1159 case SIGPROF
: return "SIGPROF";
1162 case SIGWINCH
: return "SIGWINCH";
1165 case SIGIO
: return "SIGIO";
1168 case SIGPWR
: return "SIGPWR";
1171 case SIGSYS
: return "SIGSYS";
1176 if (sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
1177 pa_xfree(PA_STATIC_TLS_GET(signame
));
1178 t
= pa_sprintf_malloc("SIGRTMIN+%i", sig
- SIGRTMIN
);
1179 PA_STATIC_TLS_SET(signame
, t
);
1188 pa_xfree(PA_STATIC_TLS_GET(signame
));
1189 t
= pa_sprintf_malloc("SIG%i", sig
);
1190 PA_STATIC_TLS_SET(signame
, t
);
1196 /* Check whether the specified GID and the group name match */
1197 static int is_group(gid_t gid
, const char *name
) {
1198 struct group
*group
= NULL
;
1202 if (!(group
= pa_getgrgid_malloc(gid
))) {
1206 pa_log("pa_getgrgid_malloc(%u): %s", gid
, pa_cstrerror(errno
));
1211 r
= pa_streq(name
, group
->gr_name
);
1214 pa_getgrgid_free(group
);
1219 /* Check the current user is member of the specified group */
1220 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1221 GETGROUPS_T
*gids
, tgid
;
1222 long n
= sysconf(_SC_NGROUPS_MAX
);
1227 gids
= pa_xmalloc(sizeof(GETGROUPS_T
) * (size_t) n
);
1229 if ((n
= getgroups((int) n
, gids
)) < 0) {
1230 pa_log("getgroups(): %s", pa_cstrerror(errno
));
1234 for (i
= 0; i
< n
; i
++) {
1236 if ((k
= is_group(gids
[i
], name
)) < 0)
1245 if ((k
= is_group(tgid
= getgid(), name
)) < 0)
1261 /* Check whether the specific user id is a member of the specified group */
1262 int pa_uid_in_group(uid_t uid
, const char *name
) {
1263 struct group
*group
= NULL
;
1268 if (!(group
= pa_getgrnam_malloc(name
))) {
1275 for (i
= group
->gr_mem
; *i
; i
++) {
1276 struct passwd
*pw
= NULL
;
1279 if (!(pw
= pa_getpwnam_malloc(*i
)))
1282 if (pw
->pw_uid
== uid
)
1285 pa_getpwnam_free(pw
);
1292 pa_getgrnam_free(group
);
1297 /* Get the GID of a given group, return (gid_t) -1 on failure. */
1298 gid_t
pa_get_gid_of_group(const char *name
) {
1299 gid_t ret
= (gid_t
) -1;
1300 struct group
*gr
= NULL
;
1303 if (!(gr
= pa_getgrnam_malloc(name
))) {
1312 pa_getgrnam_free(gr
);
1316 int pa_check_in_group(gid_t g
) {
1317 gid_t gids
[NGROUPS_MAX
];
1320 if ((r
= getgroups(NGROUPS_MAX
, gids
)) < 0)
1330 #else /* HAVE_GRP_H */
1332 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1338 int pa_uid_in_group(uid_t uid
, const char *name
) {
1343 gid_t
pa_get_gid_of_group(const char *name
) {
1348 int pa_check_in_group(gid_t g
) {
1355 /* Lock or unlock a file entirely.
1356 (advisory on UNIX, mandatory on Windows) */
1357 int pa_lock_fd(int fd
, int b
) {
1359 struct flock f_lock
;
1361 /* Try a R/W lock first */
1363 f_lock
.l_type
= (short) (b
? F_WRLCK
: F_UNLCK
);
1364 f_lock
.l_whence
= SEEK_SET
;
1368 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1371 /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
1372 if (b
&& errno
== EBADF
) {
1373 f_lock
.l_type
= F_RDLCK
;
1374 if (fcntl(fd
, F_SETLKW
, &f_lock
) >= 0)
1378 pa_log("%slock: %s", !b
? "un" : "", pa_cstrerror(errno
));
1382 HANDLE h
= (HANDLE
) _get_osfhandle(fd
);
1384 if (b
&& LockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1386 if (!b
&& UnlockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1389 pa_log("%slock failed: 0x%08X", !b
? "un" : "", GetLastError());
1391 /* FIXME: Needs to set errno! */
1397 /* Remove trailing newlines from a string */
1398 char* pa_strip_nl(char *s
) {
1401 s
[strcspn(s
, NEWLINE
)] = 0;
1405 char *pa_strip(char *s
) {
1408 /* Drops trailing whitespace. Modifies the string in
1409 * place. Returns pointer to first non-space character */
1411 s
+= strspn(s
, WHITESPACE
);
1413 for (e
= s
; *e
; e
++)
1414 if (!strchr(WHITESPACE
, *e
))
1425 /* Create a temporary lock file and lock it. */
1426 int pa_lock_lockfile(const char *fn
) {
1433 if ((fd
= pa_open_cloexec(fn
, O_CREAT
|O_RDWR
1437 , S_IRUSR
|S_IWUSR
)) < 0) {
1438 pa_log_warn("Failed to create lock file '%s': %s", fn
, pa_cstrerror(errno
));
1442 if (pa_lock_fd(fd
, 1) < 0) {
1443 pa_log_warn("Failed to lock file '%s'.", fn
);
1447 if (fstat(fd
, &st
) < 0) {
1448 pa_log_warn("Failed to fstat() file '%s': %s", fn
, pa_cstrerror(errno
));
1452 /* Check whether the file has been removed meanwhile. When yes,
1453 * restart this loop, otherwise, we're done */
1454 if (st
.st_nlink
>= 1)
1457 if (pa_lock_fd(fd
, 0) < 0) {
1458 pa_log_warn("Failed to unlock file '%s'.", fn
);
1462 if (pa_close(fd
) < 0) {
1463 pa_log_warn("Failed to close file '%s': %s", fn
, pa_cstrerror(errno
));
1474 int saved_errno
= errno
;
1476 errno
= saved_errno
;
1482 /* Unlock a temporary lock file */
1483 int pa_unlock_lockfile(const char *fn
, int fd
) {
1488 if (unlink(fn
) < 0) {
1489 pa_log_warn("Unable to remove lock file '%s': %s", fn
, pa_cstrerror(errno
));
1494 if (pa_lock_fd(fd
, 0) < 0) {
1495 pa_log_warn("Failed to unlock file '%s'.", fn
);
1499 if (pa_close(fd
) < 0) {
1500 pa_log_warn("Failed to close '%s': %s", fn
, pa_cstrerror(errno
));
1507 static char *get_config_home(char *home
) {
1510 t
= getenv("XDG_CONFIG_HOME");
1512 return pa_xstrdup(t
);
1514 return pa_sprintf_malloc("%s" PA_PATH_SEP
".config", home
);
1517 static int check_ours(const char *p
) {
1522 if (stat(p
, &st
) < 0)
1526 if (st
.st_uid
!= getuid())
1533 static char *get_pulse_home(void) {
1534 char *h
, *ret
, *config_home
;
1537 h
= pa_get_home_dir_malloc();
1539 pa_log_error("Failed to get home directory.");
1544 if (t
< 0 && t
!= -ENOENT
) {
1545 pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t
));
1550 /* If the old directory exists, use it. */
1551 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse", h
);
1552 if (access(ret
, F_OK
) >= 0) {
1558 /* Otherwise go for the XDG compliant directory. */
1559 config_home
= get_config_home(h
);
1561 ret
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", config_home
);
1567 char *pa_get_state_dir(void) {
1570 /* The state directory shall contain dynamic data that should be
1571 * kept across reboots, and is private to this user */
1573 if (!(d
= pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1574 if (!(d
= get_pulse_home()))
1577 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1578 * dir then this will break. */
1580 if (pa_make_secure_dir(d
, 0700U, (uid_t
) -1, (gid_t
) -1, TRUE
) < 0) {
1581 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1589 char *pa_get_home_dir_malloc(void) {
1591 size_t allocated
= 128;
1594 homedir
= pa_xmalloc(allocated
);
1596 if (!pa_get_home_dir(homedir
, allocated
)) {
1601 if (strlen(homedir
) < allocated
- 1)
1611 char *pa_get_binary_name_malloc(void) {
1613 size_t allocated
= 128;
1616 t
= pa_xmalloc(allocated
);
1618 if (!pa_get_binary_name(t
, allocated
)) {
1623 if (strlen(t
) < allocated
- 1)
1633 static char* make_random_dir(mode_t m
) {
1634 static const char table
[] =
1635 "abcdefghijklmnopqrstuvwxyz"
1636 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1642 fn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1643 pathlen
= strlen(fn
);
1651 for (i
= pathlen
- 12; i
< pathlen
; i
++)
1652 fn
[i
] = table
[rand() % (sizeof(table
)-1)];
1654 u
= umask((~m
) & 0777);
1661 saved_errno
= errno
;
1663 errno
= saved_errno
;
1668 if (errno
!= EEXIST
) {
1669 pa_log_error("Failed to create random directory %s: %s", fn
, pa_cstrerror(errno
));
1676 static int make_random_dir_and_link(mode_t m
, const char *k
) {
1679 if (!(p
= make_random_dir(m
)))
1683 if (symlink(p
, k
) < 0) {
1684 int saved_errno
= errno
;
1686 if (errno
!= EEXIST
)
1687 pa_log_error("Failed to symlink %s to %s: %s", k
, p
, pa_cstrerror(errno
));
1692 errno
= saved_errno
;
1704 char *pa_get_runtime_dir(void) {
1705 char *d
, *k
= NULL
, *p
= NULL
, *t
= NULL
, *mid
;
1708 /* The runtime directory shall contain dynamic data that needs NOT
1709 * to be kept across reboots and is usually private to the user,
1710 * except in system mode, where it might be accessible by other
1711 * users, too. Since we need POSIX locking and UNIX sockets in
1712 * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
1713 * set create a directory in $HOME and link it to a random subdir
1714 * in /tmp, if it was not explicitly configured. */
1716 m
= pa_in_system_mode() ? 0755U : 0700U;
1718 /* Use the explicitly configured value if it is set */
1719 d
= getenv("PULSE_RUNTIME_PATH");
1722 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, TRUE
) < 0) {
1723 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1727 return pa_xstrdup(d
);
1730 /* Use the XDG standard for the runtime directory. */
1731 d
= getenv("XDG_RUNTIME_DIR");
1733 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"pulse", d
);
1735 if (pa_make_secure_dir(k
, m
, (uid_t
) -1, (gid_t
) -1, TRUE
) < 0) {
1737 pa_log_error("Failed to create secure directory (%s): %s", k
, pa_cstrerror(errno
));
1744 /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
1745 d
= get_pulse_home();
1749 if (pa_make_secure_dir(d
, m
, (uid_t
) -1, (gid_t
) -1, TRUE
) < 0) {
1750 pa_log_error("Failed to create secure directory (%s): %s", d
, pa_cstrerror(errno
));
1755 mid
= pa_machine_id();
1761 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-runtime", d
, mid
);
1766 /* OK, first let's check if the "runtime" symlink already exists */
1771 if (errno
!= ENOENT
) {
1772 pa_log_error("Failed to stat runtime directory %s: %s", k
, pa_cstrerror(errno
));
1777 /* Hmm, so the runtime directory didn't exist yet, so let's
1778 * create one in /tmp and symlink that to it */
1780 if (make_random_dir_and_link(0700, k
) < 0) {
1782 /* Mhmm, maybe another process was quicker than us,
1783 * let's check if that was valid */
1784 if (errno
== EEXIST
)
1790 /* No symlink possible, so let's just create the runtime directly */
1798 /* Make sure that this actually makes sense */
1799 if (!pa_is_path_absolute(p
)) {
1800 pa_log_error("Path %s in link %s is not absolute.", p
, k
);
1805 /* Hmm, so this symlink is still around, make sure nobody fools us */
1809 if (lstat(p
, &st
) < 0) {
1811 if (errno
!= ENOENT
) {
1812 pa_log_error("Failed to stat runtime directory %s: %s", p
, pa_cstrerror(errno
));
1818 if (S_ISDIR(st
.st_mode
) &&
1819 (st
.st_uid
== getuid()) &&
1820 ((st
.st_mode
& 0777) == 0700)) {
1826 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1834 /* Hmm, so the link points to some nonexisting or invalid
1835 * dir. Let's replace it by a new link. We first create a
1836 * temporary link and then rename that to allow concurrent
1837 * execution of this function. */
1839 t
= pa_sprintf_malloc("%s.tmp", k
);
1841 if (make_random_dir_and_link(0700, t
) < 0) {
1843 if (errno
!= EEXIST
) {
1844 pa_log_error("Failed to symlink %s: %s", t
, pa_cstrerror(errno
));
1851 /* Hmm, someone else was quicker then us. Let's give
1852 * him some time to finish, and retry. */
1857 /* OK, we succeeded in creating the temporary symlink, so
1858 * let's rename it */
1859 if (rename(t
, k
) < 0) {
1860 pa_log_error("Failed to rename %s to %s: %s", t
, k
, pa_cstrerror(errno
));
1876 /* Try to open a configuration file. If "env" is specified, open the
1877 * value of the specified environment variable. Otherwise look for a
1878 * file "local" in the home directory or a file "global" in global
1879 * file system. If "result" is non-NULL, a pointer to a newly
1880 * allocated buffer containing the used configuration file is
1882 FILE *pa_open_config_file(const char *global
, const char *local
, const char *env
, char **result
) {
1886 if (env
&& (fn
= getenv(env
))) {
1887 if ((f
= pa_fopen_cloexec(fn
, "r"))) {
1889 *result
= pa_xstrdup(fn
);
1894 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1903 if ((e
= getenv("PULSE_CONFIG_PATH"))) {
1904 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1905 f
= pa_fopen_cloexec(fn
, "r");
1906 } else if ((h
= pa_get_home_dir_malloc())) {
1907 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1908 f
= pa_fopen_cloexec(fn
, "r");
1911 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".config/pulse" PA_PATH_SEP
"%s", h
, local
);
1912 f
= pa_fopen_cloexec(fn
, "r");
1920 *result
= pa_xstrdup(fn
);
1926 if (errno
!= ENOENT
) {
1927 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1939 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
1940 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
1941 pa_win32_get_toplevel(NULL
),
1942 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
1945 gfn
= pa_xstrdup(global
);
1947 if ((f
= pa_fopen_cloexec(gfn
, "r"))) {
1962 char *pa_find_config_file(const char *global
, const char *local
, const char *env
) {
1965 if (env
&& (fn
= getenv(env
))) {
1966 if (access(fn
, R_OK
) == 0)
1967 return pa_xstrdup(fn
);
1969 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1978 if ((e
= getenv("PULSE_CONFIG_PATH")))
1979 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1980 else if ((h
= pa_get_home_dir_malloc())) {
1981 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1986 if (access(fn
, R_OK
) == 0) {
1987 char *r
= pa_xstrdup(fn
);
1992 if (errno
!= ENOENT
) {
1993 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
2005 if (strncmp(global
, PA_DEFAULT_CONFIG_DIR
, strlen(PA_DEFAULT_CONFIG_DIR
)) == 0)
2006 gfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"etc" PA_PATH_SEP
"pulse%s",
2007 pa_win32_get_toplevel(NULL
),
2008 global
+ strlen(PA_DEFAULT_CONFIG_DIR
));
2011 gfn
= pa_xstrdup(global
);
2013 if (access(gfn
, R_OK
) == 0)
2023 /* Format the specified data as a hexademical string */
2024 char *pa_hexstr(const uint8_t* d
, size_t dlength
, char *s
, size_t slength
) {
2025 size_t i
= 0, j
= 0;
2026 const char hex
[] = "0123456789abcdef";
2030 pa_assert(slength
> 0);
2032 while (j
+2 < slength
&& i
< dlength
) {
2033 s
[j
++] = hex
[*d
>> 4];
2034 s
[j
++] = hex
[*d
& 0xF];
2040 s
[j
< slength
? j
: slength
] = 0;
2044 /* Convert a hexadecimal digit to a number or -1 if invalid */
2045 static int hexc(char c
) {
2046 if (c
>= '0' && c
<= '9')
2049 if (c
>= 'A' && c
<= 'F')
2050 return c
- 'A' + 10;
2052 if (c
>= 'a' && c
<= 'f')
2053 return c
- 'a' + 10;
2059 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
2060 size_t pa_parsehex(const char *p
, uint8_t *d
, size_t dlength
) {
2066 while (j
< dlength
&& *p
) {
2069 if ((b
= hexc(*(p
++))) < 0)
2072 d
[j
] = (uint8_t) (b
<< 4);
2077 if ((b
= hexc(*(p
++))) < 0)
2080 d
[j
] |= (uint8_t) b
;
2087 /* Returns nonzero when *s starts with *pfx */
2088 pa_bool_t
pa_startswith(const char *s
, const char *pfx
) {
2096 return strlen(s
) >= l
&& strncmp(s
, pfx
, l
) == 0;
2099 /* Returns nonzero when *s ends with *sfx */
2100 pa_bool_t
pa_endswith(const char *s
, const char *sfx
) {
2109 return l1
>= l2
&& pa_streq(s
+ l1
- l2
, sfx
);
2112 pa_bool_t
pa_is_path_absolute(const char *fn
) {
2118 return strlen(fn
) >= 3 && isalpha(fn
[0]) && fn
[1] == ':' && fn
[2] == '\\';
2122 char *pa_make_path_absolute(const char *p
) {
2128 if (pa_is_path_absolute(p
))
2129 return pa_xstrdup(p
);
2131 if (!(cwd
= pa_getcwd()))
2132 return pa_xstrdup(p
);
2134 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", cwd
, p
);
2139 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
2140 * if fn is non-null and starts with / return fn
2141 * otherwise append fn to the run time path and return it */
2142 static char *get_path(const char *fn
, pa_bool_t prependmid
, pa_bool_t rt
) {
2145 rtp
= rt
? pa_get_runtime_dir() : pa_get_state_dir();
2148 char *r
, *canonical_rtp
;
2150 if (pa_is_path_absolute(fn
)) {
2152 return pa_xstrdup(fn
);
2158 /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
2159 if ((canonical_rtp
= pa_realpath(rtp
))) {
2160 if (strlen(rtp
) >= strlen(canonical_rtp
))
2163 pa_xfree(canonical_rtp
);
2164 canonical_rtp
= rtp
;
2167 canonical_rtp
= rtp
;
2172 if (!(mid
= pa_machine_id())) {
2173 pa_xfree(canonical_rtp
);
2177 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s-%s", canonical_rtp
, mid
, fn
);
2180 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", canonical_rtp
, fn
);
2182 pa_xfree(canonical_rtp
);
2188 char *pa_runtime_path(const char *fn
) {
2189 return get_path(fn
, FALSE
, TRUE
);
2192 char *pa_state_path(const char *fn
, pa_bool_t appendmid
) {
2193 return get_path(fn
, appendmid
, FALSE
);
2196 /* Convert the string s to a signed integer in *ret_i */
2197 int pa_atoi(const char *s
, int32_t *ret_i
) {
2203 if (pa_atol(s
, &l
) < 0)
2206 if ((int32_t) l
!= l
) {
2211 *ret_i
= (int32_t) l
;
2216 /* Convert the string s to an unsigned integer in *ret_u */
2217 int pa_atou(const char *s
, uint32_t *ret_u
) {
2225 l
= strtoul(s
, &x
, 0);
2227 if (!x
|| *x
|| errno
) {
2233 if ((uint32_t) l
!= l
) {
2238 *ret_u
= (uint32_t) l
;
2243 /* Convert the string s to a signed long integer in *ret_l. */
2244 int pa_atol(const char *s
, long *ret_l
) {
2252 l
= strtol(s
, &x
, 0);
2254 if (!x
|| *x
|| errno
) {
2265 #ifdef HAVE_STRTOF_L
2266 static locale_t c_locale
= NULL
;
2268 static void c_locale_destroy(void) {
2269 freelocale(c_locale
);
2273 int pa_atod(const char *s
, double *ret_d
) {
2280 /* This should be locale independent */
2282 #ifdef HAVE_STRTOF_L
2286 if ((c_locale
= newlocale(LC_ALL_MASK
, "C", NULL
)))
2287 atexit(c_locale_destroy
);
2293 f
= strtod_l(s
, &x
, c_locale
);
2301 if (!x
|| *x
|| errno
) {
2312 /* Same as snprintf, but guarantees NUL-termination on every platform */
2313 size_t pa_snprintf(char *str
, size_t size
, const char *format
, ...) {
2318 pa_assert(size
> 0);
2321 va_start(ap
, format
);
2322 ret
= pa_vsnprintf(str
, size
, format
, ap
);
2328 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2329 size_t pa_vsnprintf(char *str
, size_t size
, const char *format
, va_list ap
) {
2333 pa_assert(size
> 0);
2336 ret
= vsnprintf(str
, size
, format
, ap
);
2343 if ((size_t) ret
> size
-1)
2346 return (size_t) ret
;
2349 /* Truncate the specified string, but guarantee that the string
2350 * returned still validates as UTF8 */
2351 char *pa_truncate_utf8(char *c
, size_t l
) {
2353 pa_assert(pa_utf8_valid(c
));
2360 while (l
> 0 && !pa_utf8_valid(c
))
2366 char *pa_getcwd(void) {
2370 char *p
= pa_xmalloc(l
);
2374 if (errno
!= ERANGE
)
2382 void *pa_will_need(const void *p
, size_t l
) {
2383 #ifdef RLIMIT_MEMLOCK
2394 a
= PA_PAGE_ALIGN_PTR(p
);
2395 size
= (size_t) ((const uint8_t*) p
+ l
- (const uint8_t*) a
);
2397 #ifdef HAVE_POSIX_MADVISE
2398 if ((r
= posix_madvise((void*) a
, size
, POSIX_MADV_WILLNEED
)) == 0) {
2399 pa_log_debug("posix_madvise() worked fine!");
2404 /* Most likely the memory was not mmap()ed from a file and thus
2405 * madvise() didn't work, so let's misuse mlock() do page this
2406 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2407 * inviting, the man page of mlock() tells us: "All pages that
2408 * contain a part of the specified address range are guaranteed to
2409 * be resident in RAM when the call returns successfully." */
2411 #ifdef RLIMIT_MEMLOCK
2412 pa_assert_se(getrlimit(RLIMIT_MEMLOCK
, &rlim
) == 0);
2414 if (rlim
.rlim_cur
< PA_PAGE_SIZE
) {
2415 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
));
2420 bs
= PA_PAGE_ALIGN((size_t) rlim
.rlim_cur
);
2422 bs
= PA_PAGE_SIZE
*4;
2425 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r
));
2428 while (size
> 0 && bs
> 0) {
2433 if (mlock(a
, bs
) < 0) {
2434 bs
= PA_PAGE_ALIGN(bs
/ 2);
2438 pa_assert_se(munlock(a
, bs
) == 0);
2440 a
= (const uint8_t*) a
+ bs
;
2446 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno
));
2448 pa_log_debug("mlock() worked fine!");
2453 void pa_close_pipe(int fds
[2]) {
2457 pa_assert_se(pa_close(fds
[0]) == 0);
2460 pa_assert_se(pa_close(fds
[1]) == 0);
2462 fds
[0] = fds
[1] = -1;
2465 char *pa_readlink(const char *p
) {
2466 #ifdef HAVE_READLINK
2475 if ((n
= readlink(p
, c
, l
-1)) < 0) {
2480 if ((size_t) n
< l
-1) {
2493 int pa_close_all(int except_fd
, ...) {
2498 va_start(ap
, except_fd
);
2501 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2506 p
= pa_xnew(int, n
+1);
2508 va_start(ap
, except_fd
);
2511 if (except_fd
>= 0) {
2515 while ((fd
= va_arg(ap
, int)) >= 0)
2522 r
= pa_close_allv(p
);
2528 int pa_close_allv(const int except_fds
[]) {
2537 if ((d
= opendir("/proc/self/fd"))) {
2541 while ((de
= readdir(d
))) {
2547 if (de
->d_name
[0] == '.')
2551 l
= strtol(de
->d_name
, &e
, 10);
2552 if (errno
!= 0 || !e
|| *e
) {
2560 if ((long) fd
!= l
) {
2573 for (i
= 0; except_fds
[i
] >= 0; i
++)
2574 if (except_fds
[i
] == fd
) {
2582 if (pa_close(fd
) < 0) {
2583 saved_errno
= errno
;
2585 errno
= saved_errno
;
2597 if (getrlimit(RLIMIT_NOFILE
, &rl
) >= 0)
2598 maxfd
= (int) rl
.rlim_max
;
2600 maxfd
= sysconf(_SC_OPEN_MAX
);
2602 for (fd
= 3; fd
< maxfd
; fd
++) {
2607 for (i
= 0; except_fds
[i
] >= 0; i
++)
2608 if (except_fds
[i
] == fd
) {
2616 if (pa_close(fd
) < 0 && errno
!= EBADF
)
2619 #endif /* !OS_IS_WIN32 */
2624 int pa_unblock_sigs(int except
, ...) {
2629 va_start(ap
, except
);
2632 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2637 p
= pa_xnew(int, n
+1);
2639 va_start(ap
, except
);
2646 while ((sig
= va_arg(ap
, int)) >= 0)
2653 r
= pa_unblock_sigsv(p
);
2659 int pa_unblock_sigsv(const int except
[]) {
2664 if (sigemptyset(&ss
) < 0)
2667 for (i
= 0; except
[i
] > 0; i
++)
2668 if (sigaddset(&ss
, except
[i
]) < 0)
2671 return sigprocmask(SIG_SETMASK
, &ss
, NULL
);
2677 int pa_reset_sigs(int except
, ...) {
2682 va_start(ap
, except
);
2685 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2690 p
= pa_xnew(int, n
+1);
2692 va_start(ap
, except
);
2699 while ((sig
= va_arg(ap
, int)) >= 0)
2706 r
= pa_reset_sigsv(p
);
2712 int pa_reset_sigsv(const int except
[]) {
2716 for (sig
= 1; sig
< NSIG
; sig
++) {
2717 pa_bool_t reset
= TRUE
;
2728 for (i
= 0; except
[i
] > 0; i
++) {
2729 if (sig
== except
[i
]) {
2738 struct sigaction sa
;
2740 memset(&sa
, 0, sizeof(sa
));
2741 sa
.sa_handler
= SIG_DFL
;
2743 /* On Linux the first two RT signals are reserved by
2744 * glibc, and sigaction() will return EINVAL for them. */
2745 if ((sigaction(sig
, &sa
, NULL
) < 0))
2746 if (errno
!= EINVAL
)
2755 void pa_set_env(const char *key
, const char *value
) {
2759 /* This is not thread-safe */
2762 SetEnvironmentVariable(key
, value
);
2764 setenv(key
, value
, 1);
2768 void pa_set_env_and_record(const char *key
, const char *value
) {
2772 /* This is not thread-safe */
2774 pa_set_env(key
, value
);
2775 recorded_env
= pa_strlist_prepend(recorded_env
, key
);
2778 void pa_unset_env_recorded(void) {
2780 /* This is not thread-safe */
2785 recorded_env
= pa_strlist_pop(recorded_env
, &s
);
2791 SetEnvironmentVariable(s
, NULL
);
2799 pa_bool_t
pa_in_system_mode(void) {
2802 if (!(e
= getenv("PULSE_SYSTEM")))
2808 /* Checks a whitespace-separated list of words in haystack for needle */
2809 pa_bool_t
pa_str_in_list_spaces(const char *haystack
, const char *needle
) {
2811 const char *state
= NULL
;
2813 if (!haystack
|| !needle
)
2816 while ((s
= pa_split_spaces(haystack
, &state
))) {
2817 if (pa_streq(needle
, s
)) {
2828 char *pa_get_user_name_malloc(void) {
2832 #ifdef _SC_LOGIN_NAME_MAX
2833 k
= (ssize_t
) sysconf(_SC_LOGIN_NAME_MAX
);
2839 u
= pa_xnew(char, k
+1);
2841 if (!(pa_get_user_name(u
, k
))) {
2849 char *pa_get_host_name_malloc(void) {
2858 if (!pa_get_host_name(c
, l
)) {
2860 if (errno
!= EINVAL
&& errno
!= ENAMETOOLONG
)
2863 } else if (strlen(c
) < l
-1) {
2871 u
= pa_utf8_filter(c
);
2876 /* Hmm, the hostname is as long the space we offered the
2877 * function, we cannot know if it fully fit in, so let's play
2878 * safe and retry. */
2887 char *pa_machine_id(void) {
2891 /* The returned value is supposed be some kind of ascii identifier
2892 * that is unique and stable across reboots. */
2894 /* First we try the /etc/machine-id, which is the best option we
2895 * have, since it fits perfectly our needs and is not as volatile
2896 * as the hostname which might be set from dhcp. */
2898 if ((f
= pa_fopen_cloexec(PA_MACHINE_ID
, "r")) ||
2899 (f
= pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK
, "r"))) {
2900 char ln
[34] = "", *r
;
2902 r
= fgets(ln
, sizeof(ln
)-1, f
);
2908 return pa_utf8_filter(ln
);
2911 if ((h
= pa_get_host_name_malloc()))
2915 /* If no hostname was set we use the POSIX hostid. It's usually
2916 * the IPv4 address. Might not be that stable. */
2917 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
2923 char *pa_session_id(void) {
2926 e
= getenv("XDG_SESSION_ID");
2930 return pa_utf8_filter(e
);
2933 char *pa_uname_string(void) {
2937 pa_assert_se(uname(&u
) >= 0);
2939 return pa_sprintf_malloc("%s %s %s %s", u
.sysname
, u
.machine
, u
.release
, u
.version
);
2945 i
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
2946 pa_assert_se(GetVersionEx(&i
));
2948 return pa_sprintf_malloc("Windows %d.%d (%d) %s", i
.dwMajorVersion
, i
.dwMinorVersion
, i
.dwBuildNumber
, i
.szCSDVersion
);
2952 #ifdef HAVE_VALGRIND_MEMCHECK_H
2953 pa_bool_t
pa_in_valgrind(void) {
2956 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
2957 * here instead of really checking whether we run in valgrind or
2961 b
= getenv("VALGRIND") ? 2 : 1;
2967 unsigned pa_gcd(unsigned a
, unsigned b
) {
2978 void pa_reduce(unsigned *num
, unsigned *den
) {
2980 unsigned gcd
= pa_gcd(*num
, *den
);
2988 pa_assert(pa_gcd(*num
, *den
) == 1);
2991 unsigned pa_ncpus(void) {
2994 #ifdef _SC_NPROCESSORS_CONF
2995 ncpus
= sysconf(_SC_NPROCESSORS_CONF
);
3000 return ncpus
<= 0 ? 1 : (unsigned) ncpus
;
3003 char *pa_replace(const char*s
, const char*a
, const char *b
) {
3012 sb
= pa_strbuf_new();
3017 if (!(p
= strstr(s
, a
)))
3020 pa_strbuf_putsn(sb
, s
, p
-s
);
3021 pa_strbuf_puts(sb
, b
);
3025 pa_strbuf_puts(sb
, s
);
3027 return pa_strbuf_tostring_free(sb
);
3030 char *pa_escape(const char *p
, const char *chars
) {
3033 pa_strbuf
*buf
= pa_strbuf_new();
3035 for (s
= p
; *s
; ++s
) {
3037 pa_strbuf_putc(buf
, '\\');
3039 for (c
= chars
; *c
; ++c
) {
3041 pa_strbuf_putc(buf
, '\\');
3046 pa_strbuf_putc(buf
, *s
);
3049 return pa_strbuf_tostring_free(buf
);
3052 char *pa_unescape(char *p
) {
3054 pa_bool_t escaped
= FALSE
;
3056 for (s
= p
, d
= p
; *s
; s
++) {
3057 if (!escaped
&& *s
== '\\') {
3071 char *pa_realpath(const char *path
) {
3075 /* We want only absolute paths */
3076 if (path
[0] != '/') {
3081 #if defined(__GLIBC__)
3085 if (!(r
= realpath(path
, NULL
)))
3088 /* We copy this here in case our pa_xmalloc() is not
3089 * implemented on top of libc malloc() */
3093 #elif defined(PATH_MAX)
3096 path_buf
= pa_xmalloc(PATH_MAX
);
3098 #if defined(OS_IS_WIN32)
3099 if (!(t
= _fullpath(path_buf
, path
, _MAX_PATH
))) {
3104 if (!(t
= realpath(path
, path_buf
))) {
3111 #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."
3117 void pa_disable_sigpipe(void) {
3120 struct sigaction sa
;
3124 if (sigaction(SIGPIPE
, NULL
, &sa
) < 0) {
3125 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3129 sa
.sa_handler
= SIG_IGN
;
3131 if (sigaction(SIGPIPE
, &sa
, NULL
) < 0) {
3132 pa_log("sigaction(): %s", pa_cstrerror(errno
));
3138 void pa_xfreev(void**a
) {
3144 for (p
= a
; *p
; p
++)
3150 char **pa_split_spaces_strv(const char *s
) {
3152 unsigned i
= 0, n
= 8;
3153 const char *state
= NULL
;
3155 t
= pa_xnew(char*, n
);
3156 while ((e
= pa_split_spaces(s
, &state
))) {
3161 t
= pa_xrenew(char*, t
, n
);
3174 char* pa_maybe_prefix_path(const char *path
, const char *prefix
) {
3177 if (pa_is_path_absolute(path
))
3178 return pa_xstrdup(path
);
3180 return pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", prefix
, path
);
3183 size_t pa_pipe_buf(int fd
) {
3188 if ((n
= fpathconf(fd
, _PC_PIPE_BUF
)) >= 0)
3199 void pa_reset_personality(void) {
3202 if (personality(PER_LINUX
) < 0)
3203 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno
));
3208 #if defined(__linux__) && !defined(__OPTIMIZE__)
3210 pa_bool_t
pa_run_from_build_tree(void) {
3212 pa_bool_t b
= FALSE
;
3214 if ((rp
= pa_readlink("/proc/self/exe"))) {
3215 b
= pa_startswith(rp
, PA_BUILDDIR
);
3224 const char *pa_get_temp_dir(void) {
3227 if ((t
= getenv("TMPDIR")) &&
3228 pa_is_path_absolute(t
))
3231 if ((t
= getenv("TMP")) &&
3232 pa_is_path_absolute(t
))
3235 if ((t
= getenv("TEMP")) &&
3236 pa_is_path_absolute(t
))
3239 if ((t
= getenv("TEMPDIR")) &&
3240 pa_is_path_absolute(t
))
3246 int pa_open_cloexec(const char *fn
, int flags
, mode_t mode
) {
3254 if ((fd
= open(fn
, flags
|O_CLOEXEC
, mode
)) >= 0)
3257 if (errno
!= EINVAL
)
3261 if ((fd
= open(fn
, flags
, mode
)) < 0)
3265 /* Some implementations might simply ignore O_CLOEXEC if it is not
3266 * understood, make sure FD_CLOEXEC is enabled anyway */
3268 pa_make_fd_cloexec(fd
);
3272 int pa_socket_cloexec(int domain
, int type
, int protocol
) {
3276 if ((fd
= socket(domain
, type
| SOCK_CLOEXEC
, protocol
)) >= 0)
3279 if (errno
!= EINVAL
)
3283 if ((fd
= socket(domain
, type
, protocol
)) < 0)
3287 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3288 * not understood, make sure FD_CLOEXEC is enabled anyway */
3290 pa_make_fd_cloexec(fd
);
3294 int pa_pipe_cloexec(int pipefd
[2]) {
3298 if ((r
= pipe2(pipefd
, O_CLOEXEC
)) >= 0)
3301 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3306 if ((r
= pipe(pipefd
)) < 0)
3310 pa_make_fd_cloexec(pipefd
[0]);
3311 pa_make_fd_cloexec(pipefd
[1]);
3316 int pa_accept_cloexec(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
) {
3320 if ((fd
= accept4(sockfd
, addr
, addrlen
, SOCK_CLOEXEC
)) >= 0)
3323 if (errno
!= EINVAL
&& errno
!= ENOSYS
)
3328 if ((fd
= accept(sockfd
, addr
, addrlen
)) < 0)
3332 pa_make_fd_cloexec(fd
);
3336 FILE* pa_fopen_cloexec(const char *path
, const char *mode
) {
3340 m
= pa_sprintf_malloc("%se", mode
);
3343 if ((f
= fopen(path
, m
))) {
3350 if (errno
!= EINVAL
)
3353 if (!(f
= fopen(path
, mode
)))
3357 pa_make_fd_cloexec(fileno(f
));
3361 void pa_nullify_stdfds(void) {
3364 pa_close(STDIN_FILENO
);
3365 pa_close(STDOUT_FILENO
);
3366 pa_close(STDERR_FILENO
);
3368 pa_assert_se(open("/dev/null", O_RDONLY
) == STDIN_FILENO
);
3369 pa_assert_se(open("/dev/null", O_WRONLY
) == STDOUT_FILENO
);
3370 pa_assert_se(open("/dev/null", O_WRONLY
) == STDERR_FILENO
);
3377 char *pa_read_line_from_file(const char *fn
) {
3379 char ln
[256] = "", *r
;
3381 if (!(f
= pa_fopen_cloexec(fn
, "r")))
3384 r
= fgets(ln
, sizeof(ln
)-1, f
);
3393 return pa_xstrdup(ln
);
3396 pa_bool_t
pa_running_in_vm(void) {
3398 #if defined(__i386__) || defined(__x86_64__)
3400 /* Both CPUID and DMI are x86 specific interfaces... */
3402 uint32_t eax
= 0x40000000;
3409 const char *const dmi_vendors
[] = {
3410 "/sys/class/dmi/id/sys_vendor",
3411 "/sys/class/dmi/id/board_vendor",
3412 "/sys/class/dmi/id/bios_vendor"
3417 for (i
= 0; i
< PA_ELEMENTSOF(dmi_vendors
); i
++) {
3420 if ((s
= pa_read_line_from_file(dmi_vendors
[i
]))) {
3422 if (pa_startswith(s
, "QEMU") ||
3423 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3424 pa_startswith(s
, "VMware") ||
3425 pa_startswith(s
, "VMW") ||
3426 pa_startswith(s
, "Microsoft Corporation") ||
3427 pa_startswith(s
, "innotek GmbH") ||
3428 pa_startswith(s
, "Xen")) {
3440 /* http://lwn.net/Articles/301888/ */
3443 __asm__
__volatile__ (
3444 /* ebx/rbx is being used for PIC! */
3445 " push %%"PA_REG_b
" \n\t"
3447 " mov %%ebx, %1 \n\t"
3448 " pop %%"PA_REG_b
" \n\t"
3450 : "=a" (eax
), "=r" (sig
.sig32
[0]), "=c" (sig
.sig32
[1]), "=d" (sig
.sig32
[2])
3454 if (pa_streq(sig
.text
, "XenVMMXenVMM") ||
3455 pa_streq(sig
.text
, "KVMKVMKVM") ||
3456 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3457 pa_streq(sig
.text
, "VMwareVMware") ||
3458 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3459 pa_streq(sig
.text
, "Microsoft Hv"))