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>
52 #ifdef HAVE_SYS_RESOURCE_H
53 #include <sys/resource.h>
56 #ifdef HAVE_SYS_CAPABILITY_H
57 #include <sys/capability.h>
60 #ifdef HAVE_SYS_MMAN_H
84 #ifdef HAVE_LIBSAMPLERATE
85 #include <samplerate.h>
88 #include <pulse/xmalloc.h>
89 #include <pulse/util.h>
90 #include <pulse/utf8.h>
92 #include <pulsecore/core-error.h>
93 #include <pulsecore/winsock.h>
94 #include <pulsecore/log.h>
95 #include <pulsecore/macro.h>
96 #include <pulsecore/thread.h>
98 #include "core-util.h"
100 /* Not all platforms have this */
102 #define MSG_NOSIGNAL 0
107 #define PULSE_ROOTENV "PULSE_ROOT"
109 int pa_set_root(HANDLE handle
) {
110 char library_path
[MAX_PATH
+ sizeof(PULSE_ROOTENV
) + 1], *sep
;
112 strcpy(library_path
, PULSE_ROOTENV
"=");
114 if (!GetModuleFileName(handle
, library_path
+ sizeof(PULSE_ROOTENV
), MAX_PATH
))
117 sep
= strrchr(library_path
, PA_PATH_SEP_CHAR
);
121 if (_putenv(library_path
) < 0)
129 /** Make a file descriptor nonblock. Doesn't do any error checking */
130 void pa_make_fd_nonblock(int fd
) {
136 pa_assert_se((v
= fcntl(fd
, F_GETFL
)) >= 0);
138 if (!(v
& O_NONBLOCK
))
139 pa_assert_se(fcntl(fd
, F_SETFL
, v
|O_NONBLOCK
) >= 0);
141 #elif defined(OS_IS_WIN32)
143 if (ioctlsocket(fd
, FIONBIO
, &arg
) < 0) {
144 pa_assert_se(WSAGetLastError() == WSAENOTSOCK
);
145 pa_log_warn("Only sockets can be made non-blocking!");
148 pa_log_warn("Non-blocking I/O not supported.!");
153 /* Set the FD_CLOEXEC flag for a fd */
154 void pa_make_fd_cloexec(int fd
) {
160 pa_assert_se((v
= fcntl(fd
, F_GETFD
, 0)) >= 0);
162 if (!(v
& FD_CLOEXEC
))
163 pa_assert_se(fcntl(fd
, F_SETFD
, v
|FD_CLOEXEC
) >= 0);
168 /** Creates a directory securely */
169 int pa_make_secure_dir(const char* dir
, mode_t m
, uid_t uid
, gid_t gid
) {
180 u
= umask((~m
) & 0777);
186 if (r
< 0 && errno
!= EEXIST
)
190 if (uid
== (uid_t
)-1)
192 if (gid
== (gid_t
)-1)
194 (void) chown(dir
, uid
, gid
);
202 if (lstat(dir
, &st
) < 0)
204 if (stat(dir
, &st
) < 0)
209 if (!S_ISDIR(st
.st_mode
) ||
210 (st
.st_uid
!= uid
) ||
211 (st
.st_gid
!= gid
) ||
212 ((st
.st_mode
& 0777) != m
)) {
217 pa_log_warn("Secure directory creation not supported on Win32.");
227 /* Return a newly allocated sting containing the parent directory of the specified file */
228 char *pa_parent_dir(const char *fn
) {
229 char *slash
, *dir
= pa_xstrdup(fn
);
231 if ((slash
= (char*) pa_path_get_filename(dir
)) == dir
) {
240 /* Creates a the parent directory of the specified path securely */
241 int pa_make_secure_parent_dir(const char *fn
, mode_t m
, uid_t uid
, gid_t gid
) {
245 if (!(dir
= pa_parent_dir(fn
)))
248 if (pa_make_secure_dir(dir
, m
, uid
, gid
) < 0)
258 /** Platform independent read function. Necessary since not all
259 * systems treat all file descriptors equal. If type is
260 * non-NULL it is used to cache the type of the fd. This is
261 * useful for making sure that only a single syscall is executed per
262 * function call. The variable pointed to should be initialized to 0
264 ssize_t
pa_read(int fd
, void *buf
, size_t count
, int *type
) {
268 if (!type
|| *type
== 0) {
271 if ((r
= recv(fd
, buf
, count
, 0)) >= 0)
274 if (WSAGetLastError() != WSAENOTSOCK
) {
275 errno
= WSAGetLastError();
285 return read(fd
, buf
, count
);
288 /** Similar to pa_read(), but handles writes */
289 ssize_t
pa_write(int fd
, const void *buf
, size_t count
, int *type
) {
291 if (!type
|| *type
== 0) {
294 if ((r
= send(fd
, buf
, count
, MSG_NOSIGNAL
)) >= 0)
298 if (WSAGetLastError() != WSAENOTSOCK
) {
299 errno
= WSAGetLastError();
303 if (errno
!= ENOTSOCK
)
311 return write(fd
, buf
, count
);
314 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
315 * unless EOF is reached or an error occured */
316 ssize_t
pa_loop_read(int fd
, void*data
, size_t size
, int *type
) {
332 if ((r
= pa_read(fd
, data
, size
, type
)) < 0)
339 data
= (uint8_t*) data
+ r
;
346 /** Similar to pa_loop_read(), but wraps write() */
347 ssize_t
pa_loop_write(int fd
, const void*data
, size_t size
, int *type
) {
363 if ((r
= pa_write(fd
, data
, size
, type
)) < 0)
370 data
= (const uint8_t*) data
+ r
;
377 /** Platform independent read function. Necessary since not all
378 * systems treat all file descriptors equal. */
379 int pa_close(int fd
) {
384 if ((ret
= closesocket(fd
)) == 0)
387 if (WSAGetLastError() != WSAENOTSOCK
) {
388 errno
= WSAGetLastError();
396 /* Print a warning messages in case that the given signal is not
397 * blocked or trapped */
398 void pa_check_signal_is_blocked(int sig
) {
399 #ifdef HAVE_SIGACTION
403 /* If POSIX threads are supported use thread-aware
404 * pthread_sigmask() function, to check if the signal is
405 * blocked. Otherwise fall back to sigprocmask() */
408 if (pthread_sigmask(SIG_SETMASK
, NULL
, &set
) < 0) {
410 if (sigprocmask(SIG_SETMASK
, NULL
, &set
) < 0) {
411 pa_log("sigprocmask(): %s", pa_cstrerror(errno
));
418 if (sigismember(&set
, sig
))
421 /* Check whether the signal is trapped */
423 if (sigaction(sig
, NULL
, &sa
) < 0) {
424 pa_log("sigaction(): %s", pa_cstrerror(errno
));
428 if (sa
.sa_handler
!= SIG_DFL
)
431 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig
));
432 #else /* HAVE_SIGACTION */
433 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig
));
437 /* The following function is based on an example from the GNU libc
438 * documentation. This function is similar to GNU's asprintf(). */
439 char *pa_sprintf_malloc(const char *format
, ...) {
449 c
= pa_xrealloc(c
, size
);
451 va_start(ap
, format
);
452 r
= vsnprintf(c
, size
, format
, ap
);
457 if (r
> -1 && r
< size
)
460 if (r
> -1) /* glibc 2.1 */
467 /* Same as the previous function, but use a va_list instead of an
469 char *pa_vsprintf_malloc(const char *format
, va_list ap
) {
479 c
= pa_xrealloc(c
, size
);
482 r
= vsnprintf(c
, size
, format
, aq
);
487 if (r
> -1 && r
< size
)
490 if (r
> -1) /* glibc 2.1 */
497 /* Similar to OpenBSD's strlcpy() function */
498 char *pa_strlcpy(char *b
, const char *s
, size_t l
) {
508 /* Make the current thread a realtime thread, and acquire the highest
509 * rtprio we can get that is less or equal the specified parameter. If
510 * the thread is already realtime, don't do anything. */
511 int pa_make_realtime(int rtprio
) {
513 #ifdef _POSIX_PRIORITY_SCHEDULING
514 struct sched_param sp
;
517 memset(&sp
, 0, sizeof(sp
));
520 if ((r
= pthread_getschedparam(pthread_self(), &policy
, &sp
)) != 0) {
521 pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r
));
525 if (policy
== SCHED_FIFO
&& sp
.sched_priority
>= rtprio
) {
526 pa_log_info("Thread already being scheduled with SCHED_FIFO with priority %i.", sp
.sched_priority
);
530 sp
.sched_priority
= rtprio
;
531 if ((r
= pthread_setschedparam(pthread_self(), SCHED_FIFO
, &sp
)) != 0) {
533 while (sp
.sched_priority
> 1) {
534 sp
.sched_priority
--;
536 if ((r
= pthread_setschedparam(pthread_self(), SCHED_FIFO
, &sp
)) == 0) {
537 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i, which is lower than the requested %i.", sp
.sched_priority
, rtprio
);
542 pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r
));
546 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp
.sched_priority
);
553 /* This is merely used for giving the user a hint. This is not correct
554 * for anything security related */
555 pa_bool_t
pa_can_realtime(void) {
560 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
564 if (getrlimit(RLIMIT_RTPRIO
, &rl
) >= 0)
565 if (rl
.rlim_cur
> 0 || rl
.rlim_cur
== RLIM_INFINITY
)
570 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
574 if ((cap
= cap_get_proc())) {
575 cap_flag_value_t flag
= CAP_CLEAR
;
577 if (cap_get_flag(cap
, CAP_SYS_NICE
, CAP_EFFECTIVE
, &flag
) >= 0)
578 if (flag
== CAP_SET
) {
591 /* This is merely used for giving the user a hint. This is not correct
592 * for anything security related */
593 pa_bool_t
pa_can_high_priority(void) {
598 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
602 if (getrlimit(RLIMIT_NICE
, &rl
) >= 0)
603 if (rl
.rlim_cur
>= 21 || rl
.rlim_cur
== RLIM_INFINITY
)
608 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
612 if ((cap
= cap_get_proc())) {
613 cap_flag_value_t flag
= CAP_CLEAR
;
615 if (cap_get_flag(cap
, CAP_SYS_NICE
, CAP_EFFECTIVE
, &flag
) >= 0)
616 if (flag
== CAP_SET
) {
629 /* Raise the priority of the current process as much as possible that
630 * is <= the specified nice level..*/
631 int pa_raise_priority(int nice_level
) {
633 #ifdef HAVE_SYS_RESOURCE_H
634 if (setpriority(PRIO_PROCESS
, 0, nice_level
) < 0) {
637 for (n
= nice_level
+1; n
< 0; n
++) {
639 if (setpriority(PRIO_PROCESS
, 0, n
) == 0) {
640 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n
, nice_level
);
645 pa_log_warn("setpriority(): %s", pa_cstrerror(errno
));
649 pa_log_info("Successfully gained nice level %i.", nice_level
);
653 if (nice_level
< 0) {
654 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS
)) {
655 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
658 pa_log_info("Successfully gained high priority class.");
665 /* Reset the priority to normal, inverting the changes made by
666 * pa_raise_priority() and pa_make_realtime()*/
667 void pa_reset_priority(void) {
668 #ifdef HAVE_SYS_RESOURCE_H
669 struct sched_param sp
;
671 setpriority(PRIO_PROCESS
, 0, 0);
673 memset(&sp
, 0, sizeof(sp
));
674 pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_OTHER
, &sp
) == 0);
678 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS
);
682 /* Try to parse a boolean string value.*/
683 int pa_parse_boolean(const char *v
) {
686 if (!strcmp(v
, "1") || v
[0] == 'y' || v
[0] == 'Y' || v
[0] == 't' || v
[0] == 'T' || !strcasecmp(v
, "on"))
688 else if (!strcmp(v
, "0") || v
[0] == 'n' || v
[0] == 'N' || v
[0] == 'f' || v
[0] == 'F' || !strcasecmp(v
, "off"))
694 /* Split the specified string wherever one of the strings in delimiter
695 * occurs. Each time it is called returns a newly allocated string
696 * with pa_xmalloc(). The variable state points to, should be
697 * initiallized to NULL before the first call. */
698 char *pa_split(const char *c
, const char *delimiter
, const char**state
) {
699 const char *current
= *state
? *state
: c
;
705 l
= strcspn(current
, delimiter
);
711 return pa_xstrndup(current
, l
);
714 /* What is interpreted as whitespace? */
715 #define WHITESPACE " \t\n"
717 /* Split a string into words. Otherwise similar to pa_split(). */
718 char *pa_split_spaces(const char *c
, const char **state
) {
719 const char *current
= *state
? *state
: c
;
722 if (!*current
|| *c
== 0)
725 current
+= strspn(current
, WHITESPACE
);
726 l
= strcspn(current
, WHITESPACE
);
730 return pa_xstrndup(current
, l
);
733 PA_STATIC_TLS_DECLARE(signame
, pa_xfree
);
735 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
736 const char *pa_sig2str(int sig
) {
749 char buf
[SIG2STR_MAX
];
751 if (sig2str(sig
, buf
) == 0) {
752 pa_xfree(PA_STATIC_TLS_GET(signame
));
753 t
= pa_sprintf_malloc("SIG%s", buf
);
754 PA_STATIC_TLS_SET(signame
, t
);
762 case SIGHUP
: return "SIGHUP";
764 case SIGINT
: return "SIGINT";
766 case SIGQUIT
: return "SIGQUIT";
768 case SIGILL
: return "SIGULL";
770 case SIGTRAP
: return "SIGTRAP";
772 case SIGABRT
: return "SIGABRT";
774 case SIGBUS
: return "SIGBUS";
776 case SIGFPE
: return "SIGFPE";
778 case SIGKILL
: return "SIGKILL";
781 case SIGUSR1
: return "SIGUSR1";
783 case SIGSEGV
: return "SIGSEGV";
785 case SIGUSR2
: return "SIGUSR2";
788 case SIGPIPE
: return "SIGPIPE";
791 case SIGALRM
: return "SIGALRM";
793 case SIGTERM
: return "SIGTERM";
795 case SIGSTKFLT
: return "SIGSTKFLT";
798 case SIGCHLD
: return "SIGCHLD";
801 case SIGCONT
: return "SIGCONT";
804 case SIGSTOP
: return "SIGSTOP";
807 case SIGTSTP
: return "SIGTSTP";
810 case SIGTTIN
: return "SIGTTIN";
813 case SIGTTOU
: return "SIGTTOU";
816 case SIGURG
: return "SIGURG";
819 case SIGXCPU
: return "SIGXCPU";
822 case SIGXFSZ
: return "SIGXFSZ";
825 case SIGVTALRM
: return "SIGVTALRM";
828 case SIGPROF
: return "SIGPROF";
831 case SIGWINCH
: return "SIGWINCH";
834 case SIGIO
: return "SIGIO";
837 case SIGPWR
: return "SIGPWR";
840 case SIGSYS
: return "SIGSYS";
845 if (sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
846 pa_xfree(PA_STATIC_TLS_GET(signame
));
847 t
= pa_sprintf_malloc("SIGRTMIN+%i", sig
- SIGRTMIN
);
848 PA_STATIC_TLS_SET(signame
, t
);
857 pa_xfree(PA_STATIC_TLS_GET(signame
));
858 t
= pa_sprintf_malloc("SIG%i", sig
);
859 PA_STATIC_TLS_SET(signame
, t
);
865 /* Check whether the specified GID and the group name match */
866 static int is_group(gid_t gid
, const char *name
) {
867 struct group group
, *result
= NULL
;
872 #ifdef HAVE_GETGRGID_R
873 #ifdef _SC_GETGR_R_SIZE_MAX
874 n
= sysconf(_SC_GETGR_R_SIZE_MAX
);
879 data
= pa_xmalloc(n
);
881 if (getgrgid_r(gid
, &group
, data
, n
, &result
) < 0 || !result
) {
882 pa_log("getgrgid_r(%u): %s", (unsigned)gid
, pa_cstrerror(errno
));
886 r
= strcmp(name
, result
->gr_name
) == 0;
891 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not
892 * support getgrgid_r. */
893 if ((result
= getgrgid(gid
)) == NULL
) {
894 pa_log("getgrgid(%u): %s", gid
, pa_cstrerror(errno
));
898 r
= strcmp(name
, result
->gr_name
) == 0;
906 /* Check the current user is member of the specified group */
907 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
908 GETGROUPS_T
*gids
, tgid
;
909 int n
= sysconf(_SC_NGROUPS_MAX
);
914 gids
= pa_xmalloc(sizeof(GETGROUPS_T
)*n
);
916 if ((n
= getgroups(n
, gids
)) < 0) {
917 pa_log("getgroups(): %s", pa_cstrerror(errno
));
921 for (i
= 0; i
< n
; i
++) {
922 if (is_group(gids
[i
], name
) > 0) {
929 if (is_group(tgid
= getgid(), name
) > 0) {
943 /* Check whether the specifc user id is a member of the specified group */
944 int pa_uid_in_group(uid_t uid
, const char *name
) {
947 struct group grbuf
, *gr
;
951 g_n
= sysconf(_SC_GETGR_R_SIZE_MAX
);
952 g_buf
= pa_xmalloc(g_n
);
954 p_n
= sysconf(_SC_GETPW_R_SIZE_MAX
);
955 p_buf
= pa_xmalloc(p_n
);
957 if (getgrnam_r(name
, &grbuf
, g_buf
, (size_t) g_n
, &gr
) != 0 || !gr
)
961 for (i
= gr
->gr_mem
; *i
; i
++) {
962 struct passwd pwbuf
, *pw
;
964 if (getpwnam_r(*i
, &pwbuf
, p_buf
, (size_t) p_n
, &pw
) != 0 || !pw
)
967 if (pw
->pw_uid
== uid
) {
980 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
981 gid_t
pa_get_gid_of_group(const char *name
) {
982 gid_t ret
= (gid_t
) -1;
985 struct group grbuf
, *gr
;
987 g_n
= sysconf(_SC_GETGR_R_SIZE_MAX
);
988 g_buf
= pa_xmalloc(g_n
);
990 if (getgrnam_r(name
, &grbuf
, g_buf
, (size_t) g_n
, &gr
) != 0 || !gr
)
1000 int pa_check_in_group(gid_t g
) {
1001 gid_t gids
[NGROUPS_MAX
];
1004 if ((r
= getgroups(NGROUPS_MAX
, gids
)) < 0)
1014 #else /* HAVE_GRP_H */
1016 int pa_own_uid_in_group(const char *name
, gid_t
*gid
) {
1021 int pa_uid_in_group(uid_t uid
, const char *name
) {
1025 gid_t
pa_get_gid_of_group(const char *name
) {
1029 int pa_check_in_group(gid_t g
) {
1035 /* Lock or unlock a file entirely.
1036 (advisory on UNIX, mandatory on Windows) */
1037 int pa_lock_fd(int fd
, int b
) {
1041 /* Try a R/W lock first */
1043 flock
.l_type
= b
? F_WRLCK
: F_UNLCK
;
1044 flock
.l_whence
= SEEK_SET
;
1048 if (fcntl(fd
, F_SETLKW
, &flock
) >= 0)
1051 /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
1052 if (b
&& errno
== EBADF
) {
1053 flock
.l_type
= F_RDLCK
;
1054 if (fcntl(fd
, F_SETLKW
, &flock
) >= 0)
1058 pa_log("%slock: %s", !b
? "un" : "", pa_cstrerror(errno
));
1062 HANDLE h
= (HANDLE
)_get_osfhandle(fd
);
1064 if (b
&& LockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1066 if (!b
&& UnlockFile(h
, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1069 pa_log("%slock failed: 0x%08X", !b
? "un" : "", GetLastError());
1075 /* Remove trailing newlines from a string */
1076 char* pa_strip_nl(char *s
) {
1079 s
[strcspn(s
, "\r\n")] = 0;
1083 /* Create a temporary lock file and lock it. */
1084 int pa_lock_lockfile(const char *fn
) {
1091 if ((fd
= open(fn
, O_CREAT
|O_RDWR
1098 , S_IRUSR
|S_IWUSR
)) < 0) {
1099 pa_log_warn("Failed to create lock file '%s': %s", fn
, pa_cstrerror(errno
));
1103 if (pa_lock_fd(fd
, 1) < 0) {
1104 pa_log_warn("Failed to lock file '%s'.", fn
);
1108 if (fstat(fd
, &st
) < 0) {
1109 pa_log_warn("Failed to fstat() file '%s': %s", fn
, pa_cstrerror(errno
));
1113 /* Check wheter the file has been removed meanwhile. When yes,
1114 * restart this loop, otherwise, we're done */
1115 if (st
.st_nlink
>= 1)
1118 if (pa_lock_fd(fd
, 0) < 0) {
1119 pa_log_warn("Failed to unlock file '%s'.", fn
);
1123 if (pa_close(fd
) < 0) {
1124 pa_log_warn("Failed to close file '%s': %s", fn
, pa_cstrerror(errno
));
1142 /* Unlock a temporary lcok file */
1143 int pa_unlock_lockfile(const char *fn
, int fd
) {
1148 if (unlink(fn
) < 0) {
1149 pa_log_warn("Unable to remove lock file '%s': %s", fn
, pa_cstrerror(errno
));
1154 if (pa_lock_fd(fd
, 0) < 0) {
1155 pa_log_warn("Failed to unlock file '%s'.", fn
);
1159 if (pa_close(fd
) < 0) {
1160 pa_log_warn("Failed to close '%s': %s", fn
, pa_cstrerror(errno
));
1167 static char *get_pulse_home(void) {
1171 if (!pa_get_home_dir(h
, sizeof(h
))) {
1172 pa_log_error("Failed to get home directory.");
1176 if (stat(h
, &st
) < 0) {
1177 pa_log_error("Failed to stat home directory %s: %s", h
, pa_cstrerror(errno
));
1181 if (st
.st_uid
!= getuid()) {
1182 pa_log_error("Home directory %s not ours.", h
);
1186 return pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse", h
);
1189 char *pa_get_state_dir(void) {
1192 /* The state directory shall contain dynamic data that should be
1193 * kept across reboots, and is private to this user */
1195 if (!(d
= pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1196 if (!(d
= get_pulse_home()))
1199 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1200 * dir then this will break. */
1202 if (pa_make_secure_dir(d
, 0700, (pid_t
) -1, (pid_t
) -1) < 0) {
1203 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno
));
1211 static char* make_random_dir(mode_t m
) {
1212 static const char table
[] =
1213 "abcdefghijklmnopqrstuvwxyz"
1214 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1217 char fn
[24] = "/tmp/pulse-";
1219 fn
[sizeof(fn
)-1] = 0;
1227 for (i
= 11; i
< sizeof(fn
)-1; i
++)
1228 fn
[i
] = table
[rand() % (sizeof(table
)-1)];
1230 u
= umask((~m
) & 0777);
1232 saved_errno
= errno
;
1236 return pa_xstrdup(fn
);
1238 errno
= saved_errno
;
1240 if (errno
!= EEXIST
) {
1241 pa_log_error("Failed to create random directory %s: %s", fn
, pa_cstrerror(errno
));
1247 static int make_random_dir_and_link(mode_t m
, const char *k
) {
1250 if (!(p
= make_random_dir(m
)))
1253 if (symlink(p
, k
) < 0) {
1254 int saved_errno
= errno
;
1256 if (errno
!= EEXIST
)
1257 pa_log_error("Failed to symlink %s to %s: %s", k
, p
, pa_cstrerror(errno
));
1262 errno
= saved_errno
;
1269 char *pa_get_runtime_dir(void) {
1270 char *d
, *k
= NULL
, *p
= NULL
, *t
= NULL
, *mid
;
1273 /* The runtime directory shall contain dynamic data that needs NOT
1274 * to be kept accross reboots and is usuallly private to the user,
1275 * except in system mode, where it might be accessible by other
1276 * users, too. Since we need POSIX locking and UNIX sockets in
1277 * this directory, we link it to a random subdir in /tmp, if it
1278 * was not explicitly configured. */
1280 if ((d
= getenv("PULSE_RUNTIME_PATH"))) {
1283 m
= pa_in_system_mode() ? 0755 : 0700;
1285 if (pa_make_secure_dir(d
, m
, (pid_t
) -1, (pid_t
) -1) < 0) {
1286 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno
));
1290 return pa_xstrdup(d
);
1293 if (!(d
= get_pulse_home()))
1296 if (!(mid
= pa_machine_id())) {
1301 k
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s:runtime", d
, mid
);
1306 /* OK, first let's check if the "runtime" symlink is already
1309 if (!(p
= pa_readlink(k
))) {
1311 if (errno
!= ENOENT
) {
1312 pa_log_error("Failed to stat runtime directory %s: %s", k
, pa_cstrerror(errno
));
1316 /* Hmm, so the runtime directory didn't exist yet, so let's
1317 * create one in /tmp and symlink that to it */
1319 if (make_random_dir_and_link(0700, k
) < 0) {
1321 /* Mhmm, maybe another process was quicker than us,
1322 * let's check if that was valid */
1323 if (errno
== EEXIST
)
1332 /* Make sure that this actually makes sense */
1333 if (!pa_is_path_absolute(p
)) {
1334 pa_log_error("Path %s in link %s is not absolute.", p
, k
);
1338 /* Hmm, so this symlink is still around, make sure nobody fools
1341 if (lstat(p
, &st
) < 0) {
1343 if (errno
!= ENOENT
) {
1344 pa_log_error("Failed to stat runtime directory %s: %s", p
, pa_cstrerror(errno
));
1350 if (S_ISDIR(st
.st_mode
) &&
1351 (st
.st_uid
== getuid()) &&
1352 ((st
.st_mode
& 0777) == 0700)) {
1358 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1364 /* Hmm, so the link points to some nonexisting or invalid
1365 * dir. Let's replace it by a new link. We first create a
1366 * temporary link and then rename that to allow concurrent
1367 * execution of this function. */
1369 t
= pa_sprintf_malloc("%s.tmp", k
);
1371 if (make_random_dir_and_link(0700, t
) < 0) {
1373 if (errno
!= EEXIST
) {
1374 pa_log_error("Failed to symlink %s: %s", t
, pa_cstrerror(errno
));
1381 /* Hmm, someone lese was quicker then us. Let's give
1382 * him some time to finish, and retry. */
1387 /* OK, we succeeded in creating the temporary symlink, so
1388 * let's rename it */
1389 if (rename(t
, k
) < 0) {
1390 pa_log_error("Failed to rename %s to %s: %s", t
, k
, pa_cstrerror(errno
));
1406 /* Try to open a configuration file. If "env" is specified, open the
1407 * value of the specified environment variable. Otherwise look for a
1408 * file "local" in the home directory or a file "global" in global
1409 * file system. If "result" is non-NULL, a pointer to a newly
1410 * allocated buffer containing the used configuration file is
1412 FILE *pa_open_config_file(const char *global
, const char *local
, const char *env
, char **result
) {
1417 if (!getenv(PULSE_ROOTENV
))
1421 if (env
&& (fn
= getenv(env
))) {
1425 if (!ExpandEnvironmentStrings(fn
, buf
, PATH_MAX
))
1430 if ((f
= fopen(fn
, "r"))) {
1432 *result
= pa_xstrdup(fn
);
1437 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1447 if ((e
= getenv("PULSE_CONFIG_PATH")))
1448 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1449 else if (pa_get_home_dir(h
, sizeof(h
)))
1450 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1455 if (!ExpandEnvironmentStrings(lfn
, buf
, PATH_MAX
)) {
1462 if ((f
= fopen(fn
, "r"))) {
1464 *result
= pa_xstrdup(fn
);
1470 if (errno
!= ENOENT
) {
1471 pa_log_warn("Failed to open configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1483 if (!ExpandEnvironmentStrings(global
, buf
, PATH_MAX
))
1488 if ((f
= fopen(global
, "r"))) {
1491 *result
= pa_xstrdup(global
);
1501 char *pa_find_config_file(const char *global
, const char *local
, const char *env
) {
1506 if (!getenv(PULSE_ROOTENV
))
1510 if (env
&& (fn
= getenv(env
))) {
1513 if (!ExpandEnvironmentStrings(fn
, buf
, PATH_MAX
))
1518 if (access(fn
, R_OK
) == 0)
1519 return pa_xstrdup(fn
);
1521 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1530 if ((e
= getenv("PULSE_CONFIG_PATH")))
1531 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", e
, local
);
1532 else if (pa_get_home_dir(h
, sizeof(h
)))
1533 fn
= lfn
= pa_sprintf_malloc("%s" PA_PATH_SEP
".pulse" PA_PATH_SEP
"%s", h
, local
);
1538 if (!ExpandEnvironmentStrings(lfn
, buf
, PATH_MAX
)) {
1545 if (access(fn
, R_OK
) == 0) {
1546 char *r
= pa_xstrdup(fn
);
1551 if (errno
!= ENOENT
) {
1552 pa_log_warn("Failed to access configuration file '%s': %s", fn
, pa_cstrerror(errno
));
1562 if (!ExpandEnvironmentStrings(global
, buf
, PATH_MAX
))
1567 if (access(global
, R_OK
) == 0)
1568 return pa_xstrdup(global
);
1575 /* Format the specified data as a hexademical string */
1576 char *pa_hexstr(const uint8_t* d
, size_t dlength
, char *s
, size_t slength
) {
1577 size_t i
= 0, j
= 0;
1578 const char hex
[] = "0123456789abcdef";
1582 pa_assert(slength
> 0);
1584 while (i
< dlength
&& j
+3 <= slength
) {
1585 s
[j
++] = hex
[*d
>> 4];
1586 s
[j
++] = hex
[*d
& 0xF];
1592 s
[j
< slength
? j
: slength
] = 0;
1596 /* Convert a hexadecimal digit to a number or -1 if invalid */
1597 static int hexc(char c
) {
1598 if (c
>= '0' && c
<= '9')
1601 if (c
>= 'A' && c
<= 'F')
1602 return c
- 'A' + 10;
1604 if (c
>= 'a' && c
<= 'f')
1605 return c
- 'a' + 10;
1610 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1611 size_t pa_parsehex(const char *p
, uint8_t *d
, size_t dlength
) {
1617 while (j
< dlength
&& *p
) {
1620 if ((b
= hexc(*(p
++))) < 0)
1623 d
[j
] = (uint8_t) (b
<< 4);
1628 if ((b
= hexc(*(p
++))) < 0)
1631 d
[j
] |= (uint8_t) b
;
1638 /* Returns nonzero when *s starts with *pfx */
1639 pa_bool_t
pa_startswith(const char *s
, const char *pfx
) {
1647 return strlen(s
) >= l
&& strncmp(s
, pfx
, l
) == 0;
1650 /* Returns nonzero when *s ends with *sfx */
1651 pa_bool_t
pa_endswith(const char *s
, const char *sfx
) {
1660 return l1
>= l2
&& strcmp(s
+l1
-l2
, sfx
) == 0;
1663 pa_bool_t
pa_is_path_absolute(const char *fn
) {
1669 return strlen(fn
) >= 3 && isalpha(fn
[0]) && fn
[1] == ':' && fn
[2] == '\\';
1673 char *pa_make_path_absolute(const char *p
) {
1679 if (pa_is_path_absolute(p
))
1680 return pa_xstrdup(p
);
1682 if (!(cwd
= pa_getcwd()))
1683 return pa_xstrdup(p
);
1685 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", cwd
, p
);
1690 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
1691 * if fn is non-null and starts with / return fn
1692 * otherwise append fn to the run time path and return it */
1693 static char *get_path(const char *fn
, pa_bool_t prependmid
, pa_bool_t rt
) {
1696 if (pa_is_path_absolute(fn
))
1697 return pa_xstrdup(fn
);
1699 rtp
= rt
? pa_get_runtime_dir() : pa_get_state_dir();
1710 if (!(mid
= pa_machine_id())) {
1715 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s:%s", rtp
, mid
, fn
);
1718 r
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", rtp
, fn
);
1726 char *pa_runtime_path(const char *fn
) {
1727 return get_path(fn
, FALSE
, TRUE
);
1730 char *pa_state_path(const char *fn
, pa_bool_t appendmid
) {
1731 return get_path(fn
, appendmid
, FALSE
);
1734 /* Convert the string s to a signed integer in *ret_i */
1735 int pa_atoi(const char *s
, int32_t *ret_i
) {
1743 l
= strtol(s
, &x
, 0);
1745 if (!x
|| *x
|| errno
!= 0)
1748 if ((int32_t) l
!= l
)
1751 *ret_i
= (int32_t) l
;
1756 /* Convert the string s to an unsigned integer in *ret_u */
1757 int pa_atou(const char *s
, uint32_t *ret_u
) {
1765 l
= strtoul(s
, &x
, 0);
1767 if (!x
|| *x
|| errno
!= 0)
1770 if ((uint32_t) l
!= l
)
1773 *ret_u
= (uint32_t) l
;
1778 #ifdef HAVE_STRTOF_L
1779 static locale_t c_locale
= NULL
;
1781 static void c_locale_destroy(void) {
1782 freelocale(c_locale
);
1786 int pa_atod(const char *s
, double *ret_d
) {
1794 /* This should be locale independent */
1796 #ifdef HAVE_STRTOF_L
1800 if ((c_locale
= newlocale(LC_ALL_MASK
, "C", NULL
)))
1801 atexit(c_locale_destroy
);
1807 f
= strtod_l(s
, &x
, c_locale
);
1815 if (!x
|| *x
|| errno
!= 0)
1823 /* Same as snprintf, but guarantees NUL-termination on every platform */
1824 int pa_snprintf(char *str
, size_t size
, const char *format
, ...) {
1829 pa_assert(size
> 0);
1832 va_start(ap
, format
);
1833 ret
= pa_vsnprintf(str
, size
, format
, ap
);
1839 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
1840 int pa_vsnprintf(char *str
, size_t size
, const char *format
, va_list ap
) {
1844 pa_assert(size
> 0);
1847 ret
= vsnprintf(str
, size
, format
, ap
);
1854 return PA_MIN((int) size
-1, ret
);
1857 /* Truncate the specified string, but guarantee that the string
1858 * returned still validates as UTF8 */
1859 char *pa_truncate_utf8(char *c
, size_t l
) {
1861 pa_assert(pa_utf8_valid(c
));
1868 while (l
> 0 && !pa_utf8_valid(c
))
1874 char *pa_getcwd(void) {
1878 char *p
= pa_xnew(char, l
);
1882 if (errno
!= ERANGE
)
1890 void *pa_will_need(const void *p
, size_t l
) {
1891 #ifdef RLIMIT_MEMLOCK
1902 a
= PA_PAGE_ALIGN_PTR(p
);
1903 size
= (const uint8_t*) p
+ l
- (const uint8_t*) a
;
1905 #ifdef HAVE_POSIX_MADVISE
1906 if ((r
= posix_madvise((void*) a
, size
, POSIX_MADV_WILLNEED
)) == 0) {
1907 pa_log_debug("posix_madvise() worked fine!");
1912 /* Most likely the memory was not mmap()ed from a file and thus
1913 * madvise() didn't work, so let's misuse mlock() do page this
1914 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
1915 * inviting, the man page of mlock() tells us: "All pages that
1916 * contain a part of the specified address range are guaranteed to
1917 * be resident in RAM when the call returns successfully." */
1919 #ifdef RLIMIT_MEMLOCK
1920 pa_assert_se(getrlimit(RLIMIT_MEMLOCK
, &rlim
) == 0);
1922 if (rlim
.rlim_cur
< PA_PAGE_SIZE
) {
1923 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
));
1927 bs
= PA_PAGE_ALIGN(rlim
.rlim_cur
);
1929 bs
= PA_PAGE_SIZE
*4;
1932 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r
));
1935 while (size
> 0 && bs
> 0) {
1940 if (mlock(a
, bs
) < 0) {
1941 bs
= PA_PAGE_ALIGN(bs
/ 2);
1945 pa_assert_se(munlock(a
, bs
) == 0);
1947 a
= (const uint8_t*) a
+ bs
;
1953 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno
));
1955 pa_log_debug("mlock() worked fine!");
1960 void pa_close_pipe(int fds
[2]) {
1964 pa_assert_se(pa_close(fds
[0]) == 0);
1967 pa_assert_se(pa_close(fds
[1]) == 0);
1969 fds
[0] = fds
[1] = -1;
1972 char *pa_readlink(const char *p
) {
1979 c
= pa_xnew(char, l
);
1981 if ((n
= readlink(p
, c
, l
-1)) < 0) {
1986 if ((size_t) n
< l
-1) {
1996 int pa_close_all(int except_fd
, ...) {
2001 va_start(ap
, except_fd
);
2004 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2009 p
= pa_xnew(int, n
+1);
2011 va_start(ap
, except_fd
);
2014 if (except_fd
>= 0) {
2018 while ((fd
= va_arg(ap
, int)) >= 0)
2025 r
= pa_close_allv(p
);
2031 int pa_close_allv(const int except_fds
[]) {
2040 if ((d
= opendir("/proc/self/fd"))) {
2044 while ((de
= readdir(d
))) {
2050 if (de
->d_name
[0] == '.')
2054 l
= strtol(de
->d_name
, &e
, 10);
2055 if (errno
!= 0 || !e
|| *e
) {
2063 if ((long) fd
!= l
) {
2076 for (i
= 0; except_fds
[i
] >= 0; i
++)
2077 if (except_fds
[i
] == fd
) {
2085 if (pa_close(fd
) < 0) {
2086 saved_errno
= errno
;
2088 errno
= saved_errno
;
2100 if (getrlimit(RLIMIT_NOFILE
, &rl
) < 0)
2103 for (fd
= 3; fd
< (int) rl
.rlim_max
; fd
++) {
2108 for (i
= 0; except_fds
[i
] >= 0; i
++)
2109 if (except_fds
[i
] == fd
) {
2117 if (pa_close(fd
) < 0 && errno
!= EBADF
)
2124 int pa_unblock_sigs(int except
, ...) {
2129 va_start(ap
, except
);
2132 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2137 p
= pa_xnew(int, n
+1);
2139 va_start(ap
, except
);
2146 while ((sig
= va_arg(ap
, int)) >= 0)
2153 r
= pa_unblock_sigsv(p
);
2159 int pa_unblock_sigsv(const int except
[]) {
2163 if (sigemptyset(&ss
) < 0)
2166 for (i
= 0; except
[i
] > 0; i
++)
2167 if (sigaddset(&ss
, except
[i
]) < 0)
2170 return sigprocmask(SIG_SETMASK
, &ss
, NULL
);
2173 int pa_reset_sigs(int except
, ...) {
2178 va_start(ap
, except
);
2181 for (n
= 1; va_arg(ap
, int) >= 0; n
++)
2186 p
= pa_xnew(int, n
+1);
2188 va_start(ap
, except
);
2195 while ((sig
= va_arg(ap
, int)) >= 0)
2202 r
= pa_reset_sigsv(p
);
2208 int pa_reset_sigsv(const int except
[]) {
2211 for (sig
= 1; sig
< _NSIG
; sig
++) {
2212 pa_bool_t reset
= TRUE
;
2223 for (i
= 0; except
[i
] > 0; i
++) {
2224 if (sig
== except
[i
]) {
2233 struct sigaction sa
;
2235 memset(&sa
, 0, sizeof(sa
));
2236 sa
.sa_handler
= SIG_DFL
;
2238 /* On Linux the first two RT signals are reserved by
2239 * glibc, and sigaction() will return EINVAL for them. */
2240 if ((sigaction(sig
, &sa
, NULL
) < 0))
2241 if (errno
!= EINVAL
)
2249 void pa_set_env(const char *key
, const char *value
) {
2253 putenv(pa_sprintf_malloc("%s=%s", key
, value
));
2256 pa_bool_t
pa_in_system_mode(void) {
2259 if (!(e
= getenv("PULSE_SYSTEM")))
2265 char *pa_machine_id(void) {
2269 if ((f
= fopen(PA_MACHINE_ID
, "r"))) {
2270 char ln
[34] = "", *r
;
2272 r
= fgets(ln
, sizeof(ln
)-1, f
);
2276 return pa_xstrdup(pa_strip_nl(ln
));
2284 c
= pa_xnew(char, l
);
2286 if (!pa_get_host_name(c
, l
)) {
2288 if (errno
== EINVAL
|| errno
== ENAMETOOLONG
) {
2297 if (strlen(c
) < l
-1)
2300 /* Hmm, the hostname is as long the space we offered the
2301 * function, we cannot know if it fully fit in, so let's play
2302 * safe and retry. */