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
39 #include <sys/types.h>
54 #ifdef HAVE_SYS_RESOURCE_H
55 #include <sys/resource.h>
58 #ifdef HAVE_SYS_CAPABILITY_H
59 #include <sys/capability.h>
62 #ifdef HAVE_SYS_MMAN_H
86 #ifdef HAVE_LIBSAMPLERATE
87 #include <samplerate.h>
90 #include <pulse/xmalloc.h>
91 #include <pulse/util.h>
92 #include <pulse/utf8.h>
94 #include <pulsecore/core-error.h>
95 #include <pulsecore/winsock.h>
96 #include <pulsecore/log.h>
97 #include <pulsecore/macro.h>
98 #include <pulsecore/thread.h>
100 #include "core-util.h"
102 /* Not all platforms have this */
104 #define MSG_NOSIGNAL 0
109 #define PULSE_ROOTENV "PULSE_ROOT"
111 int pa_set_root(HANDLE handle
) {
112 char library_path
[MAX_PATH
+ sizeof(PULSE_ROOTENV
) + 1], *sep
;
114 strcpy(library_path
, PULSE_ROOTENV
"=");
116 if (!GetModuleFileName(handle
, library_path
+ sizeof(PULSE_ROOTENV
), MAX_PATH
))
119 sep
= strrchr(library_path
, PA_PATH_SEP_CHAR
);
123 if (_putenv(library_path
) < 0)
131 /** Make a file descriptor nonblock. Doesn't do any error checking */
132 void pa_make_fd_nonblock(int fd
) {
138 pa_assert_se((v
= fcntl(fd
, F_GETFL
)) >= 0);
140 if (!(v
& O_NONBLOCK
))
141 pa_assert_se(fcntl(fd
, F_SETFL
, v
|O_NONBLOCK
) >= 0);
143 #elif defined(OS_IS_WIN32)
145 if (ioctlsocket(fd
, FIONBIO
, &arg
) < 0) {
146 pa_assert_se(WSAGetLastError() == WSAENOTSOCK
);
147 pa_log_warn("Only sockets can be made non-blocking!");
150 pa_log_warn("Non-blocking I/O not supported.!");
155 /* Set the FD_CLOEXEC flag for a fd */
156 void pa_make_fd_cloexec(int fd
) {
162 pa_assert_se((v
= fcntl(fd
, F_GETFD
, 0)) >= 0);
164 if (!(v
& FD_CLOEXEC
))
165 pa_assert_se(fcntl(fd
, F_SETFD
, v
|FD_CLOEXEC
) >= 0);
170 /** Creates a directory securely */
171 int pa_make_secure_dir(const char* dir
, mode_t m
, uid_t uid
, gid_t gid
) {
182 u
= umask((~m
) & 0777);
188 if (r
< 0 && errno
!= EEXIST
)
192 if (uid
== (uid_t
)-1)
194 if (gid
== (gid_t
)-1)
196 (void) chown(dir
, uid
, gid
);
204 if (lstat(dir
, &st
) < 0)
206 if (stat(dir
, &st
) < 0)
211 if (!S_ISDIR(st
.st_mode
) ||
212 (st
.st_uid
!= uid
) ||
213 (st
.st_gid
!= gid
) ||
214 ((st
.st_mode
& 0777) != m
)) {
219 pa_log_warn("Secure directory creation not supported on Win32.");
229 /* Return a newly allocated sting containing the parent directory of the specified file */
230 char *pa_parent_dir(const char *fn
) {
231 char *slash
, *dir
= pa_xstrdup(fn
);
233 if ((slash
= (char*) pa_path_get_filename(dir
)) == dir
) {
242 /* Creates a the parent directory of the specified path securely */
243 int pa_make_secure_parent_dir(const char *fn
, mode_t m
, uid_t uid
, gid_t gid
) {
247 if (!(dir
= pa_parent_dir(fn
)))
250 if (pa_make_secure_dir(dir
, m
, uid
, gid
) < 0)
260 /** Platform independent read function. Necessary since not all
261 * systems treat all file descriptors equal. If type is
262 * non-NULL it is used to cache the type of the fd. This is
263 * useful for making sure that only a single syscall is executed per
264 * function call. The variable pointed to should be initialized to 0
266 ssize_t
pa_read(int fd
, void *buf
, size_t count
, int *type
) {
270 if (!type
|| *type
== 0) {
273 if ((r
= recv(fd
, buf
, count
, 0)) >= 0)
276 if (WSAGetLastError() != WSAENOTSOCK
) {
277 errno
= WSAGetLastError();
287 return read(fd
, buf
, count
);
290 /** Similar to pa_read(), but handles writes */
291 ssize_t
pa_write(int fd
, const void *buf
, size_t count
, int *type
) {
293 if (!type
|| *type
== 0) {
296 if ((r
= send(fd
, buf
, count
, MSG_NOSIGNAL
)) >= 0)
300 if (WSAGetLastError() != WSAENOTSOCK
) {
301 errno
= WSAGetLastError();
305 if (errno
!= ENOTSOCK
)
313 return write(fd
, buf
, count
);
316 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
317 * unless EOF is reached or an error occured */
318 ssize_t
pa_loop_read(int fd
, void*data
, size_t size
, int *type
) {
334 if ((r
= pa_read(fd
, data
, size
, type
)) < 0)
341 data
= (uint8_t*) data
+ r
;
348 /** Similar to pa_loop_read(), but wraps write() */
349 ssize_t
pa_loop_write(int fd
, const void*data
, size_t size
, int *type
) {
365 if ((r
= pa_write(fd
, data
, size
, type
)) < 0)
372 data
= (const uint8_t*) data
+ r
;
379 /** Platform independent read function. Necessary since not all
380 * systems treat all file descriptors equal. */
381 int pa_close(int fd
) {
386 if ((ret
= closesocket(fd
)) == 0)
389 if (WSAGetLastError() != WSAENOTSOCK
) {
390 errno
= WSAGetLastError();
398 /* Print a warning messages in case that the given signal is not
399 * blocked or trapped */
400 void pa_check_signal_is_blocked(int sig
) {
401 #ifdef HAVE_SIGACTION
405 /* If POSIX threads are supported use thread-aware
406 * pthread_sigmask() function, to check if the signal is
407 * blocked. Otherwise fall back to sigprocmask() */
410 if (pthread_sigmask(SIG_SETMASK
, NULL
, &set
) < 0) {
412 if (sigprocmask(SIG_SETMASK
, NULL
, &set
) < 0) {
413 pa_log("sigprocmask(): %s", pa_cstrerror(errno
));
420 if (sigismember(&set
, sig
))
423 /* Check whether the signal is trapped */
425 if (sigaction(sig
, NULL
, &sa
) < 0) {
426 pa_log("sigaction(): %s", pa_cstrerror(errno
));
430 if (sa
.sa_handler
!= SIG_DFL
)
433 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig
));
434 #else /* HAVE_SIGACTION */
435 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig
));
439 /* The following function is based on an example from the GNU libc
440 * documentation. This function is similar to GNU's asprintf(). */
441 char *pa_sprintf_malloc(const char *format
, ...) {
451 c
= pa_xrealloc(c
, size
);
453 va_start(ap
, format
);
454 r
= vsnprintf(c
, size
, format
, ap
);
459 if (r
> -1 && r
< size
)
462 if (r
> -1) /* glibc 2.1 */
469 /* Same as the previous function, but use a va_list instead of an
471 char *pa_vsprintf_malloc(const char *format
, va_list ap
) {
481 c
= pa_xrealloc(c
, size
);
484 r
= vsnprintf(c
, size
, format
, aq
);
489 if (r
> -1 && r
< size
)
492 if (r
> -1) /* glibc 2.1 */
499 /* Similar to OpenBSD's strlcpy() function */
500 char *pa_strlcpy(char *b
, const char *s
, size_t l
) {
510 /* Make the current thread a realtime thread, and acquire the highest
511 * rtprio we can get that is less or equal the specified parameter. If
512 * the thread is already realtime, don't do anything. */
513 int pa_make_realtime(int rtprio
) {
515 #ifdef _POSIX_PRIORITY_SCHEDULING
516 struct sched_param sp
;
519 memset(&sp
, 0, sizeof(sp
));
522 if ((r
= pthread_getschedparam(pthread_self(), &policy
, &sp
)) != 0) {
523 pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r
));
527 if (policy
== SCHED_FIFO
&& sp
.sched_priority
>= rtprio
) {
528 pa_log_info("Thread already being scheduled with SCHED_FIFO with priority %i.", sp
.sched_priority
);
532 sp
.sched_priority
= rtprio
;
533 if ((r
= pthread_setschedparam(pthread_self(), SCHED_FIFO
, &sp
)) != 0) {
535 while (sp
.sched_priority
> 1) {
536 sp
.sched_priority
--;
538 if ((r
= pthread_setschedparam(pthread_self(), SCHED_FIFO
, &sp
)) == 0) {
539 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i, which is lower than the requested %i.", sp
.sched_priority
, rtprio
);
544 pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r
));
548 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp
.sched_priority
);
555 /* This is merely used for giving the user a hint. This is not correct
556 * for anything security related */
557 pa_bool_t
pa_can_realtime(void) {
562 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
566 if (getrlimit(RLIMIT_RTPRIO
, &rl
) >= 0)
567 if (rl
.rlim_cur
> 0 || rl
.rlim_cur
== RLIM_INFINITY
)
572 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
576 if ((cap
= cap_get_proc())) {
577 cap_flag_value_t flag
= CAP_CLEAR
;
579 if (cap_get_flag(cap
, CAP_SYS_NICE
, CAP_EFFECTIVE
, &flag
) >= 0)
580 if (flag
== CAP_SET
) {
593 /* This is merely used for giving the user a hint. This is not correct
594 * for anything security related */
595 pa_bool_t
pa_can_high_priority(void) {
600 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
604 if (getrlimit(RLIMIT_NICE
, &rl
) >= 0)
605 if (rl
.rlim_cur
>= 21 || rl
.rlim_cur
== RLIM_INFINITY
)
610 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
614 if ((cap
= cap_get_proc())) {
615 cap_flag_value_t flag
= CAP_CLEAR
;
617 if (cap_get_flag(cap
, CAP_SYS_NICE
, CAP_EFFECTIVE
, &flag
) >= 0)
618 if (flag
== CAP_SET
) {
631 /* Raise the priority of the current process as much as possible that
632 * is <= the specified nice level..*/
633 int pa_raise_priority(int nice_level
) {
635 #ifdef HAVE_SYS_RESOURCE_H
636 if (setpriority(PRIO_PROCESS
, 0, nice_level
) < 0) {
639 for (n
= nice_level
+1; n
< 0; n
++) {
641 if (setpriority(PRIO_PROCESS
, 0, n
) == 0) {
642 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n
, nice_level
);
647 pa_log_warn("setpriority(): %s", pa_cstrerror(errno
));
651 pa_log_info("Successfully gained nice level %i.", nice_level
);
655 if (nice_level
< 0) {
656 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS
)) {
657 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
660 pa_log_info("Successfully gained high priority class.");
667 /* Reset the priority to normal, inverting the changes made by
668 * pa_raise_priority() and pa_make_realtime()*/
669 void pa_reset_priority(void) {
670 #ifdef HAVE_SYS_RESOURCE_H
671 struct sched_param sp
;
673 setpriority(PRIO_PROCESS
, 0, 0);
675 memset(&sp
, 0, sizeof(sp
));
676 pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_OTHER
, &sp
) == 0);
680 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS
);
684 static int match(const char *expr
, const char *v
) {
688 if (regcomp(&re
, expr
, REG_NOSUB
|REG_EXTENDED
) != 0) {
693 if ((k
= regexec(&re
, v
, 0, NULL
, 0)) == 0)
695 else if (k
== REG_NOMATCH
)
702 /* Try to parse a boolean string value.*/
703 int pa_parse_boolean(const char *v
) {
708 /* First we check language independant */
709 if (!strcmp(v
, "1") || v
[0] == 'y' || v
[0] == 'Y' || v
[0] == 't' || v
[0] == 'T' || !strcasecmp(v
, "on"))
711 else if (!strcmp(v
, "0") || v
[0] == 'n' || v
[0] == 'N' || v
[0] == 'f' || v
[0] == 'F' || !strcasecmp(v
, "off"))
714 /* And then we check language dependant */
715 if ((expr
= nl_langinfo(YESEXPR
)))
717 if ((r
= match(expr
, v
)) > 0)
720 if ((expr
= nl_langinfo(NOEXPR
)))
722 if ((r
= match(expr
, v
)) > 0)
729 /* Split the specified string wherever one of the strings in delimiter
730 * occurs. Each time it is called returns a newly allocated string
731 * with pa_xmalloc(). The variable state points to, should be
732 * initiallized to NULL before the first call. */
733 char *pa_split(const char *c
, const char *delimiter
, const char**state
) {
734 const char *current
= *state
? *state
: c
;
740 l
= strcspn(current
, delimiter
);
746 return pa_xstrndup(current
, l
);
749 /* What is interpreted as whitespace? */
750 #define WHITESPACE " \t\n"
752 /* Split a string into words. Otherwise similar to pa_split(). */
753 char *pa_split_spaces(const char *c
, const char **state
) {
754 const char *current
= *state
? *state
: c
;
757 if (!*current
|| *c
== 0)
760 current
+= strspn(current
, WHITESPACE
);
761 l
= strcspn(current
, WHITESPACE
);
765 return pa_xstrndup(current
, l
);
768 PA_STATIC_TLS_DECLARE(signame
, pa_xfree
);
770 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
771 const char *pa_sig2str(int sig
) {
784 char buf
[SIG2STR_MAX
];
786 if (sig2str(sig
, buf
) == 0) {
787 pa_xfree(PA_STATIC_TLS_GET(signame
));
788 t
= pa_sprintf_malloc("SIG%s", buf
);
789 PA_STATIC_TLS_SET(signame
, t
);
797 case SIGHUP
: return "SIGHUP";
799 case SIGINT
: return "SIGINT";
801 case SIGQUIT
: return "SIGQUIT";
803 case SIGILL
: return "SIGULL";
805 case SIGTRAP
: return "SIGTRAP";
807 case SIGABRT
: return "SIGABRT";
809 case SIGBUS
: return "SIGBUS";
811 case SIGFPE
: return "SIGFPE";
813 case SIGKILL
: return "SIGKILL";
816 case SIGUSR1
: return "SIGUSR1";
818 case SIGSEGV
: return "SIGSEGV";
820 case SIGUSR2
: return "SIGUSR2";
823 case SIGPIPE
: return "SIGPIPE";
826 case SIGALRM
: return "SIGALRM";
828 case SIGTERM
: return "SIGTERM";
830 case SIGSTKFLT
: return "SIGSTKFLT";
833 case SIGCHLD
: return "SIGCHLD";
836 case SIGCONT
: return "SIGCONT";
839 case SIGSTOP
: return "SIGSTOP";
842 case SIGTSTP
: return "SIGTSTP";
845 case SIGTTIN
: return "SIGTTIN";
848 case SIGTTOU
: return "SIGTTOU";
851 case SIGURG
: return "SIGURG";
854 case SIGXCPU
: return "SIGXCPU";
857 case SIGXFSZ
: return "SIGXFSZ";
860 case SIGVTALRM
: return "SIGVTALRM";
863 case SIGPROF
: return "SIGPROF";
866 case SIGWINCH
: return "SIGWINCH";
869 case SIGIO
: return "SIGIO";
872 case SIGPWR
: return "SIGPWR";
875 case SIGSYS
: return "SIGSYS";
880 if (sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
881 pa_xfree(PA_STATIC_TLS_GET(signame
));
882 t
= pa_sprintf_malloc("SIGRTMIN+%i", sig
- SIGRTMIN
);
883 PA_STATIC_TLS_SET(signame
, t
);
892 pa_xfree(PA_STATIC_TLS_GET(signame
));
893 t
= pa_sprintf_malloc("SIG%i", sig
);
894 PA_STATIC_TLS_SET(signame
, t
);
900 /* Check whether the specified GID and the group name match */
901 static int is_group(gid_t gid
, const char *name
) {
902 struct group group
, *result
= NULL
;
907 #ifdef HAVE_GETGRGID_R
908 #ifdef _SC_GETGR_R_SIZE_MAX
909 n
= sysconf(_SC_GETGR_R_SIZE_MAX
);
914 data
= pa_xmalloc(n
);
916 if (getgrgid_r(gid
, &group
, data
, n
, &result
) < 0 || !result
) {
917 pa_log("getgrgid_r(%u): %s", (unsigned)gid
, pa_cstrerror(errno
));
921 r
= strcmp(name
, result
->gr_name
) == 0;
926 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not
927 * support getgrgid_r. */
928 if ((result
= getgrgid(gid
)) == NULL
) {
929 pa_log("getgrgid(%u): %s", gid
, pa_cstrerror(errno
));
933 r
= strcmp(name
, result
->gr_name
) == 0;
941 /* Check the current user is member of the specified group */
942 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
943 GETGROUPS_T
*gids
, tgid
;
944 int n
= sysconf(_SC_NGROUPS_MAX
);
949 gids
= pa_xmalloc(sizeof(GETGROUPS_T
)*n
);
951 if ((n
= getgroups(n
, gids
)) < 0) {
952 pa_log("getgroups(): %s", pa_cstrerror(errno
));
956 for (i
= 0; i
< n
; i
++) {
957 if (is_group(gids
[i
], name
) > 0) {
964 if (is_group(tgid
= getgid(), name
) > 0) {
978 /* Check whether the specifc user id is a member of the specified group */
979 int pa_uid_in_group(uid_t uid
, const char *name
) {
982 struct group grbuf
, *gr
;
986 g_n
= sysconf(_SC_GETGR_R_SIZE_MAX
);
987 g_buf
= pa_xmalloc(g_n
);
989 p_n
= sysconf(_SC_GETPW_R_SIZE_MAX
);
990 p_buf
= pa_xmalloc(p_n
);
992 if (getgrnam_r(name
, &grbuf
, g_buf
, (size_t) g_n
, &gr
) != 0 || !gr
)
996 for (i
= gr
->gr_mem
; *i
; i
++) {
997 struct passwd pwbuf
, *pw
;
999 if (getpwnam_r(*i
, &pwbuf
, p_buf
, (size_t) p_n
, &pw
) != 0 || !pw
)
1002 if (pw
->pw_uid
== uid
) {
1015 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
1016 gid_t
pa_get_gid_of_group(const char *name
) {
1017 gid_t ret
= (gid_t
) -1;
1020 struct group grbuf
, *gr
;
1022 g_n
= sysconf(_SC_GETGR_R_SIZE_MAX
);
1023 g_buf
= pa_xmalloc(g_n
);
1025 if (getgrnam_r(name
, &grbuf
, g_buf
, (size_t) g_n
, &gr
) != 0 || !gr
)
1035 int pa_check_in_group(gid_t g
) {
1036 gid_t gids
[NGROUPS_MAX
];
1039 if ((r
= getgroups(NGROUPS_MAX
, gids
)) < 0)
1049 #else /* HAVE_GRP_H */
1051 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1056 int pa_uid_in_group(uid_t uid
, const char *name
) {
1060 gid_t
pa_get_gid_of_group(const char *name
) {
1064 int pa_check_in_group(gid_t g
) {
1070 /* Lock or unlock a file entirely.
1071 (advisory on UNIX, mandatory on Windows) */
1072 int pa_lock_fd(int fd
, int b
) {
1076 /* Try a R/W lock first */
1078 flock
.l_type
= b
? F_WRLCK
: F_UNLCK
;
1079 flock
.l_whence
= SEEK_SET
;
1083 if (fcntl(fd
, F_SETLKW
, &flock
) >= 0)
1086 /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
1087 if (b
&& errno
== EBADF
) {
1088 flock
.l_type
= F_RDLCK
;
1089 if (fcntl(fd
, F_SETLKW
, &flock
) >= 0)
1093 pa_log("%slock: %s", !b
? "un" : "", pa_cstrerror(errno
));
1097 HANDLE h
= (HANDLE
)_get_osfhandle(fd
);
1099 if (b
&& LockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1101 if (!b
&& UnlockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1104 pa_log("%slock failed: 0x%08X", !b
? "un" : "", GetLastError());
1110 /* Remove trailing newlines from a string */
1111 char* pa_strip_nl(char *s
) {
1114 s
[strcspn(s
, "\r\n")] = 0;
1118 /* Create a temporary lock file and lock it. */
1119 int pa_lock_lockfile(const char *fn
) {
1126 if ((fd
= open(fn
, O_CREAT
|O_RDWR
1133 , S_IRUSR
|S_IWUSR
)) < 0) {
1134 pa_log_warn("Failed to create lock file '%s': %s", fn
, pa_cstrerror(errno
));
1138 if (pa_lock_fd(fd
, 1) < 0) {
1139 pa_log_warn("Failed to lock file '%s'.", fn
);
1143 if (fstat(fd
, &st
) < 0) {
1144 pa_log_warn("Failed to fstat() file '%s': %s", fn
, pa_cstrerror(errno
));
1148 /* Check wheter the file has been removed meanwhile. When yes,
1149 * restart this loop, otherwise, we're done */
1150 if (st
.st_nlink
>= 1)
1153 if (pa_lock_fd(fd
, 0) < 0) {
1154 pa_log_warn("Failed to unlock file '%s'.", fn
);
1158 if (pa_close(fd
) < 0) {
1159 pa_log_warn("Failed to close file '%s': %s", fn
, pa_cstrerror(errno
));
1177 /* Unlock a temporary lcok file */
1178 int pa_unlock_lockfile(const char *fn
, int fd
) {
1183 if (unlink(fn
) < 0) {
1184 pa_log_warn("Unable to remove lock file '%s': %s", fn
, pa_cstrerror(errno
));
1189 if (pa_lock_fd(fd
, 0) < 0) {
1190 pa_log_warn("Failed to unlock file '%s'.", fn
);
1194 if (pa_close(fd
) < 0) {
1195 pa_log_warn("Failed to close '%s': %s", fn
, pa_cstrerror(errno
));
1202 static char *get_pulse_home(void) {
1206 if (!pa_get_home_dir(h
, sizeof(h
))) {
1207 pa_log_error("Failed to get home directory.");
1211 if (stat(h
, &st
) < 0) {
1212 pa_log_error("Failed to stat home directory %s: %s", h
, pa_cstrerror(errno
));
1216 if (st
.st_uid
!= getuid()) {
1217 pa_log_error("Home directory %s not ours.", h
);
1221 return pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse", h
);
1224 char *pa_get_state_dir(void) {
1227 /* The state directory shall contain dynamic data that should be
1228 * kept across reboots, and is private to this user */
1230 if (!(d
= pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1231 if (!(d
= get_pulse_home()))
1234 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1235 * dir then this will break. */
1237 if (pa_make_secure_dir(d
, 0700, (pid_t
) -1, (pid_t
) -1) < 0) {
1238 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno
));
1246 static char* make_random_dir(mode_t m
) {
1247 static const char table
[] =
1248 "abcdefghijklmnopqrstuvwxyz"
1249 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1252 char fn
[24] = "/tmp/pulse-";
1254 fn
[sizeof(fn
)-1] = 0;
1262 for (i
= 11; i
< sizeof(fn
)-1; i
++)
1263 fn
[i
] = table
[rand() % (sizeof(table
)-1)];
1265 u
= umask((~m
) & 0777);
1267 saved_errno
= errno
;
1271 return pa_xstrdup(fn
);
1273 errno
= saved_errno
;
1275 if (errno
!= EEXIST
) {
1276 pa_log_error("Failed to create random directory %s: %s", fn
, pa_cstrerror(errno
));
1282 static int make_random_dir_and_link(mode_t m
, const char *k
) {
1285 if (!(p
= make_random_dir(m
)))
1288 if (symlink(p
, k
) < 0) {
1289 int saved_errno
= errno
;
1291 if (errno
!= EEXIST
)
1292 pa_log_error("Failed to symlink %s to %s: %s", k
, p
, pa_cstrerror(errno
));
1297 errno
= saved_errno
;
1304 char *pa_get_runtime_dir(void) {
1305 char *d
, *k
= NULL
, *p
= NULL
, *t
= NULL
, *mid
;
1308 /* The runtime directory shall contain dynamic data that needs NOT
1309 * to be kept accross reboots and is usuallly private to the user,
1310 * except in system mode, where it might be accessible by other
1311 * users, too. Since we need POSIX locking and UNIX sockets in
1312 * this directory, we link it to a random subdir in /tmp, if it
1313 * was not explicitly configured. */
1315 if ((d
= getenv("PULSE_RUNTIME_PATH"))) {
1318 m
= pa_in_system_mode() ? 0755 : 0700;
1320 if (pa_make_secure_dir(d
, m
, (pid_t
) -1, (pid_t
) -1) < 0) {
1321 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno
));
1325 return pa_xstrdup(d
);
1328 if (!(d
= get_pulse_home()))
1331 if (!(mid
= pa_machine_id())) {
1336 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s:runtime", d
, mid
);
1341 /* OK, first let's check if the "runtime" symlink is already
1344 if (!(p
= pa_readlink(k
))) {
1346 if (errno
!= ENOENT
) {
1347 pa_log_error("Failed to stat runtime directory %s: %s", k
, pa_cstrerror(errno
));
1351 /* Hmm, so the runtime directory didn't exist yet, so let's
1352 * create one in /tmp and symlink that to it */
1354 if (make_random_dir_and_link(0700, k
) < 0) {
1356 /* Mhmm, maybe another process was quicker than us,
1357 * let's check if that was valid */
1358 if (errno
== EEXIST
)
1367 /* Make sure that this actually makes sense */
1368 if (!pa_is_path_absolute(p
)) {
1369 pa_log_error("Path %s in link %s is not absolute.", p
, k
);
1373 /* Hmm, so this symlink is still around, make sure nobody fools
1376 if (lstat(p
, &st
) < 0) {
1378 if (errno
!= ENOENT
) {
1379 pa_log_error("Failed to stat runtime directory %s: %s", p
, pa_cstrerror(errno
));
1385 if (S_ISDIR(st
.st_mode
) &&
1386 (st
.st_uid
== getuid()) &&
1387 ((st
.st_mode
& 0777) == 0700)) {
1393 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1399 /* Hmm, so the link points to some nonexisting or invalid
1400 * dir. Let's replace it by a new link. We first create a
1401 * temporary link and then rename that to allow concurrent
1402 * execution of this function. */
1404 t
= pa_sprintf_malloc("%s.tmp", k
);
1406 if (make_random_dir_and_link(0700, t
) < 0) {
1408 if (errno
!= EEXIST
) {
1409 pa_log_error("Failed to symlink %s: %s", t
, pa_cstrerror(errno
));
1416 /* Hmm, someone lese was quicker then us. Let's give
1417 * him some time to finish, and retry. */
1422 /* OK, we succeeded in creating the temporary symlink, so
1423 * let's rename it */
1424 if (rename(t
, k
) < 0) {
1425 pa_log_error("Failed to rename %s to %s: %s", t
, k
, pa_cstrerror(errno
));
1441 /* Try to open a configuration file. If "env" is specified, open the
1442 * value of the specified environment variable. Otherwise look for a
1443 * file "local" in the home directory or a file "global" in global
1444 * file system. If "result" is non-NULL, a pointer to a newly
1445 * allocated buffer containing the used configuration file is
1447 FILE *pa_open_config_file(const char *global
, const char *local
, const char *env
, char **result
) {
1452 if (!getenv(PULSE_ROOTENV
))
1456 if (env
&& (fn
= getenv(env
))) {
1460 if (!ExpandEnvironmentStrings(fn
, buf
, PATH_MAX
))
1465 if ((f
= fopen(fn
, "r"))) {
1467 *result
= pa_xstrdup(fn
);
1472 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1482 if ((e
= getenv("PULSE_CONFIG_PATH")))
1483 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1484 else if (pa_get_home_dir(h
, sizeof(h
)))
1485 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1490 if (!ExpandEnvironmentStrings(lfn
, buf
, PATH_MAX
)) {
1497 if ((f
= fopen(fn
, "r"))) {
1499 *result
= pa_xstrdup(fn
);
1505 if (errno
!= ENOENT
) {
1506 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1518 if (!ExpandEnvironmentStrings(global
, buf
, PATH_MAX
))
1523 if ((f
= fopen(global
, "r"))) {
1526 *result
= pa_xstrdup(global
);
1536 char *pa_find_config_file(const char *global
, const char *local
, const char *env
) {
1541 if (!getenv(PULSE_ROOTENV
))
1545 if (env
&& (fn
= getenv(env
))) {
1548 if (!ExpandEnvironmentStrings(fn
, buf
, PATH_MAX
))
1553 if (access(fn
, R_OK
) == 0)
1554 return pa_xstrdup(fn
);
1556 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1565 if ((e
= getenv("PULSE_CONFIG_PATH")))
1566 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1567 else if (pa_get_home_dir(h
, sizeof(h
)))
1568 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1573 if (!ExpandEnvironmentStrings(lfn
, buf
, PATH_MAX
)) {
1580 if (access(fn
, R_OK
) == 0) {
1581 char *r
= pa_xstrdup(fn
);
1586 if (errno
!= ENOENT
) {
1587 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1597 if (!ExpandEnvironmentStrings(global
, buf
, PATH_MAX
))
1602 if (access(global
, R_OK
) == 0)
1603 return pa_xstrdup(global
);
1610 /* Format the specified data as a hexademical string */
1611 char *pa_hexstr(const uint8_t* d
, size_t dlength
, char *s
, size_t slength
) {
1612 size_t i
= 0, j
= 0;
1613 const char hex
[] = "0123456789abcdef";
1617 pa_assert(slength
> 0);
1619 while (i
< dlength
&& j
+3 <= slength
) {
1620 s
[j
++] = hex
[*d
>> 4];
1621 s
[j
++] = hex
[*d
& 0xF];
1627 s
[j
< slength
? j
: slength
] = 0;
1631 /* Convert a hexadecimal digit to a number or -1 if invalid */
1632 static int hexc(char c
) {
1633 if (c
>= '0' && c
<= '9')
1636 if (c
>= 'A' && c
<= 'F')
1637 return c
- 'A' + 10;
1639 if (c
>= 'a' && c
<= 'f')
1640 return c
- 'a' + 10;
1645 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1646 size_t pa_parsehex(const char *p
, uint8_t *d
, size_t dlength
) {
1652 while (j
< dlength
&& *p
) {
1655 if ((b
= hexc(*(p
++))) < 0)
1658 d
[j
] = (uint8_t) (b
<< 4);
1663 if ((b
= hexc(*(p
++))) < 0)
1666 d
[j
] |= (uint8_t) b
;
1673 /* Returns nonzero when *s starts with *pfx */
1674 pa_bool_t
pa_startswith(const char *s
, const char *pfx
) {
1682 return strlen(s
) >= l
&& strncmp(s
, pfx
, l
) == 0;
1685 /* Returns nonzero when *s ends with *sfx */
1686 pa_bool_t
pa_endswith(const char *s
, const char *sfx
) {
1695 return l1
>= l2
&& strcmp(s
+l1
-l2
, sfx
) == 0;
1698 pa_bool_t
pa_is_path_absolute(const char *fn
) {
1704 return strlen(fn
) >= 3 && isalpha(fn
[0]) && fn
[1] == ':' && fn
[2] == '\\';
1708 char *pa_make_path_absolute(const char *p
) {
1714 if (pa_is_path_absolute(p
))
1715 return pa_xstrdup(p
);
1717 if (!(cwd
= pa_getcwd()))
1718 return pa_xstrdup(p
);
1720 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", cwd
, p
);
1725 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
1726 * if fn is non-null and starts with / return fn
1727 * otherwise append fn to the run time path and return it */
1728 static char *get_path(const char *fn
, pa_bool_t prependmid
, pa_bool_t rt
) {
1731 if (pa_is_path_absolute(fn
))
1732 return pa_xstrdup(fn
);
1734 rtp
= rt
? pa_get_runtime_dir() : pa_get_state_dir();
1745 if (!(mid
= pa_machine_id())) {
1750 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s:%s", rtp
, mid
, fn
);
1753 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", rtp
, fn
);
1761 char *pa_runtime_path(const char *fn
) {
1762 return get_path(fn
, FALSE
, TRUE
);
1765 char *pa_state_path(const char *fn
, pa_bool_t appendmid
) {
1766 return get_path(fn
, appendmid
, FALSE
);
1769 /* Convert the string s to a signed integer in *ret_i */
1770 int pa_atoi(const char *s
, int32_t *ret_i
) {
1778 l
= strtol(s
, &x
, 0);
1780 if (!x
|| *x
|| errno
!= 0)
1783 if ((int32_t) l
!= l
)
1786 *ret_i
= (int32_t) l
;
1791 /* Convert the string s to an unsigned integer in *ret_u */
1792 int pa_atou(const char *s
, uint32_t *ret_u
) {
1800 l
= strtoul(s
, &x
, 0);
1802 if (!x
|| *x
|| errno
!= 0)
1805 if ((uint32_t) l
!= l
)
1808 *ret_u
= (uint32_t) l
;
1813 #ifdef HAVE_STRTOF_L
1814 static locale_t c_locale
= NULL
;
1816 static void c_locale_destroy(void) {
1817 freelocale(c_locale
);
1821 int pa_atod(const char *s
, double *ret_d
) {
1829 /* This should be locale independent */
1831 #ifdef HAVE_STRTOF_L
1835 if ((c_locale
= newlocale(LC_ALL_MASK
, "C", NULL
)))
1836 atexit(c_locale_destroy
);
1842 f
= strtod_l(s
, &x
, c_locale
);
1850 if (!x
|| *x
|| errno
!= 0)
1858 /* Same as snprintf, but guarantees NUL-termination on every platform */
1859 int pa_snprintf(char *str
, size_t size
, const char *format
, ...) {
1864 pa_assert(size
> 0);
1867 va_start(ap
, format
);
1868 ret
= pa_vsnprintf(str
, size
, format
, ap
);
1874 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
1875 int pa_vsnprintf(char *str
, size_t size
, const char *format
, va_list ap
) {
1879 pa_assert(size
> 0);
1882 ret
= vsnprintf(str
, size
, format
, ap
);
1889 return PA_MIN((int) size
-1, ret
);
1892 /* Truncate the specified string, but guarantee that the string
1893 * returned still validates as UTF8 */
1894 char *pa_truncate_utf8(char *c
, size_t l
) {
1896 pa_assert(pa_utf8_valid(c
));
1903 while (l
> 0 && !pa_utf8_valid(c
))
1909 char *pa_getcwd(void) {
1913 char *p
= pa_xnew(char, l
);
1917 if (errno
!= ERANGE
)
1925 void *pa_will_need(const void *p
, size_t l
) {
1926 #ifdef RLIMIT_MEMLOCK
1937 a
= PA_PAGE_ALIGN_PTR(p
);
1938 size
= (const uint8_t*) p
+ l
- (const uint8_t*) a
;
1940 #ifdef HAVE_POSIX_MADVISE
1941 if ((r
= posix_madvise((void*) a
, size
, POSIX_MADV_WILLNEED
)) == 0) {
1942 pa_log_debug("posix_madvise() worked fine!");
1947 /* Most likely the memory was not mmap()ed from a file and thus
1948 * madvise() didn't work, so let's misuse mlock() do page this
1949 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
1950 * inviting, the man page of mlock() tells us: "All pages that
1951 * contain a part of the specified address range are guaranteed to
1952 * be resident in RAM when the call returns successfully." */
1954 #ifdef RLIMIT_MEMLOCK
1955 pa_assert_se(getrlimit(RLIMIT_MEMLOCK
, &rlim
) == 0);
1957 if (rlim
.rlim_cur
< PA_PAGE_SIZE
) {
1958 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
));
1962 bs
= PA_PAGE_ALIGN(rlim
.rlim_cur
);
1964 bs
= PA_PAGE_SIZE
*4;
1967 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r
));
1970 while (size
> 0 && bs
> 0) {
1975 if (mlock(a
, bs
) < 0) {
1976 bs
= PA_PAGE_ALIGN(bs
/ 2);
1980 pa_assert_se(munlock(a
, bs
) == 0);
1982 a
= (const uint8_t*) a
+ bs
;
1988 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno
));
1990 pa_log_debug("mlock() worked fine!");
1995 void pa_close_pipe(int fds
[2]) {
1999 pa_assert_se(pa_close(fds
[0]) == 0);
2002 pa_assert_se(pa_close(fds
[1]) == 0);
2004 fds
[0] = fds
[1] = -1;
2007 char *pa_readlink(const char *p
) {
2014 c
= pa_xnew(char, l
);
2016 if ((n
= readlink(p
, c
, l
-1)) < 0) {
2021 if ((size_t) n
< l
-1) {
2031 int pa_close_all(int except_fd
, ...) {
2036 va_start(ap
, except_fd
);
2039 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2044 p
= pa_xnew(int, n
+1);
2046 va_start(ap
, except_fd
);
2049 if (except_fd
>= 0) {
2053 while ((fd
= va_arg(ap
, int)) >= 0)
2060 r
= pa_close_allv(p
);
2066 int pa_close_allv(const int except_fds
[]) {
2075 if ((d
= opendir("/proc/self/fd"))) {
2079 while ((de
= readdir(d
))) {
2085 if (de
->d_name
[0] == '.')
2089 l
= strtol(de
->d_name
, &e
, 10);
2090 if (errno
!= 0 || !e
|| *e
) {
2098 if ((long) fd
!= l
) {
2111 for (i
= 0; except_fds
[i
] >= 0; i
++)
2112 if (except_fds
[i
] == fd
) {
2120 if (pa_close(fd
) < 0) {
2121 saved_errno
= errno
;
2123 errno
= saved_errno
;
2135 if (getrlimit(RLIMIT_NOFILE
, &rl
) < 0)
2138 for (fd
= 3; fd
< (int) rl
.rlim_max
; fd
++) {
2143 for (i
= 0; except_fds
[i
] >= 0; i
++)
2144 if (except_fds
[i
] == fd
) {
2152 if (pa_close(fd
) < 0 && errno
!= EBADF
)
2159 int pa_unblock_sigs(int except
, ...) {
2164 va_start(ap
, except
);
2167 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2172 p
= pa_xnew(int, n
+1);
2174 va_start(ap
, except
);
2181 while ((sig
= va_arg(ap
, int)) >= 0)
2188 r
= pa_unblock_sigsv(p
);
2194 int pa_unblock_sigsv(const int except
[]) {
2198 if (sigemptyset(&ss
) < 0)
2201 for (i
= 0; except
[i
] > 0; i
++)
2202 if (sigaddset(&ss
, except
[i
]) < 0)
2205 return sigprocmask(SIG_SETMASK
, &ss
, NULL
);
2208 int pa_reset_sigs(int except
, ...) {
2213 va_start(ap
, except
);
2216 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2221 p
= pa_xnew(int, n
+1);
2223 va_start(ap
, except
);
2230 while ((sig
= va_arg(ap
, int)) >= 0)
2237 r
= pa_reset_sigsv(p
);
2243 int pa_reset_sigsv(const int except
[]) {
2246 for (sig
= 1; sig
< _NSIG
; sig
++) {
2247 pa_bool_t reset
= TRUE
;
2258 for (i
= 0; except
[i
] > 0; i
++) {
2259 if (sig
== except
[i
]) {
2268 struct sigaction sa
;
2270 memset(&sa
, 0, sizeof(sa
));
2271 sa
.sa_handler
= SIG_DFL
;
2273 /* On Linux the first two RT signals are reserved by
2274 * glibc, and sigaction() will return EINVAL for them. */
2275 if ((sigaction(sig
, &sa
, NULL
) < 0))
2276 if (errno
!= EINVAL
)
2284 void pa_set_env(const char *key
, const char *value
) {
2288 putenv(pa_sprintf_malloc("%s=%s", key
, value
));
2291 pa_bool_t
pa_in_system_mode(void) {
2294 if (!(e
= getenv("PULSE_SYSTEM")))
2300 char *pa_machine_id(void) {
2304 if ((f
= fopen(PA_MACHINE_ID
, "r"))) {
2305 char ln
[34] = "", *r
;
2307 r
= fgets(ln
, sizeof(ln
)-1, f
);
2311 return pa_xstrdup(pa_strip_nl(ln
));
2319 c
= pa_xnew(char, l
);
2321 if (!pa_get_host_name(c
, l
)) {
2323 if (errno
== EINVAL
|| errno
== ENAMETOOLONG
) {
2332 if (strlen(c
) < l
-1)
2335 /* Hmm, the hostname is as long the space we offered the
2336 * function, we cannot know if it fully fit in, so let's play
2337 * safe and retry. */