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>
45 #include <sys/utsname.h>
55 #ifdef HAVE_SYS_RESOURCE_H
56 #include <sys/resource.h>
59 #ifdef HAVE_SYS_CAPABILITY_H
60 #include <sys/capability.h>
63 #ifdef HAVE_SYS_MMAN_H
87 #ifdef HAVE_LIBSAMPLERATE
88 #include <samplerate.h>
91 #include <pulse/xmalloc.h>
92 #include <pulse/util.h>
93 #include <pulse/utf8.h>
95 #include <pulsecore/core-error.h>
96 #include <pulsecore/winsock.h>
97 #include <pulsecore/log.h>
98 #include <pulsecore/macro.h>
99 #include <pulsecore/thread.h>
100 #include <pulsecore/strbuf.h>
102 #include "core-util.h"
104 /* Not all platforms have this */
106 #define MSG_NOSIGNAL 0
111 #define PULSE_ROOTENV "PULSE_ROOT"
113 int pa_set_root(HANDLE handle) {
114 char library_path[MAX_PATH + sizeof(PULSE_ROOTENV) + 1], *sep;
116 strcpy(library_path, PULSE_ROOTENV "=");
118 /* FIXME: Needs to set errno */
120 if (!GetModuleFileName(handle, library_path + sizeof(PULSE_ROOTENV), MAX_PATH))
123 sep = strrchr(library_path, PA_PATH_SEP_CHAR);
127 if (_putenv(library_path) < 0)
135 /** Make a file descriptor nonblock. Doesn't do any error checking */
136 void pa_make_fd_nonblock(int fd) {
142 pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
144 if (!(v & O_NONBLOCK))
145 pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0);
147 #elif defined(OS_IS_WIN32)
149 if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
150 pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
151 pa_log_warn("Only sockets can be made non-blocking!");
154 pa_log_warn("Non-blocking I/O not supported.!");
159 /* Set the FD_CLOEXEC flag for a fd */
160 void pa_make_fd_cloexec(int fd) {
166 pa_assert_se((v = fcntl(fd, F_GETFD, 0)) >= 0);
168 if (!(v & FD_CLOEXEC))
169 pa_assert_se(fcntl(fd, F_SETFD, v|FD_CLOEXEC) >= 0);
174 /** Creates a directory securely */
175 int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
186 u = umask((~m) & 0777);
192 if (r < 0 && errno != EEXIST)
196 if (uid == (uid_t)-1)
198 if (gid == (gid_t)-1)
200 (void) chown(dir, uid, gid);
208 if (lstat(dir, &st) < 0)
210 if (stat(dir, &st) < 0)
215 if (!S_ISDIR(st.st_mode) ||
216 (st.st_uid != uid) ||
217 (st.st_gid != gid) ||
218 ((st.st_mode & 0777) != m)) {
223 pa_log_warn("Secure directory creation not supported on Win32.");
236 /* Return a newly allocated sting containing the parent directory of the specified file */
237 char *pa_parent_dir(const char *fn) {
238 char *slash, *dir = pa_xstrdup(fn);
240 if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
250 /* Creates a the parent directory of the specified path securely */
251 int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {
255 if (!(dir = pa_parent_dir(fn)))
258 if (pa_make_secure_dir(dir, m, uid, gid) < 0)
268 /** Platform independent read function. Necessary since not all
269 * systems treat all file descriptors equal. If type is
270 * non-NULL it is used to cache the type of the fd. This is
271 * useful for making sure that only a single syscall is executed per
272 * function call. The variable pointed to should be initialized to 0
274 ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
278 if (!type || *type == 0) {
281 if ((r = recv(fd, buf, count, 0)) >= 0)
284 if (WSAGetLastError() != WSAENOTSOCK) {
285 errno = WSAGetLastError();
295 return read(fd, buf, count);
298 /** Similar to pa_read(), but handles writes */
299 ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
301 if (!type || *type == 0) {
304 if ((r = send(fd, buf, count, MSG_NOSIGNAL)) >= 0)
308 if (WSAGetLastError() != WSAENOTSOCK) {
309 errno = WSAGetLastError();
313 if (errno != ENOTSOCK)
321 return write(fd, buf, count);
324 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
325 * unless EOF is reached or an error occured */
326 ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
342 if ((r = pa_read(fd, data, size, type)) < 0)
349 data = (uint8_t*) data + r;
356 /** Similar to pa_loop_read(), but wraps write() */
357 ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
373 if ((r = pa_write(fd, data, size, type)) < 0)
380 data = (const uint8_t*) data + r;
387 /** Platform independent read function. Necessary since not all
388 * systems treat all file descriptors equal. */
389 int pa_close(int fd) {
394 if ((ret = closesocket(fd)) == 0)
397 if (WSAGetLastError() != WSAENOTSOCK) {
398 errno = WSAGetLastError();
406 if ((r = close(fd)) >= 0)
414 /* Print a warning messages in case that the given signal is not
415 * blocked or trapped */
416 void pa_check_signal_is_blocked(int sig) {
417 #ifdef HAVE_SIGACTION
421 /* If POSIX threads are supported use thread-aware
422 * pthread_sigmask() function, to check if the signal is
423 * blocked. Otherwise fall back to sigprocmask() */
426 if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) {
428 if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) {
429 pa_log("sigprocmask(): %s", pa_cstrerror(errno));
436 if (sigismember(&set, sig))
439 /* Check whether the signal is trapped */
441 if (sigaction(sig, NULL, &sa) < 0) {
442 pa_log("sigaction(): %s", pa_cstrerror(errno));
446 if (sa.sa_handler != SIG_DFL)
449 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig));
450 #else /* HAVE_SIGACTION */
451 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig));
455 /* The following function is based on an example from the GNU libc
456 * documentation. This function is similar to GNU's asprintf(). */
457 char *pa_sprintf_malloc(const char *format, ...) {
467 c = pa_xrealloc(c, size);
469 va_start(ap, format);
470 r = vsnprintf(c, size, format, ap);
475 if (r > -1 && (size_t) r < size)
478 if (r > -1) /* glibc 2.1 */
485 /* Same as the previous function, but use a va_list instead of an
487 char *pa_vsprintf_malloc(const char *format, va_list ap) {
497 c = pa_xrealloc(c, size);
500 r = vsnprintf(c, size, format, aq);
505 if (r > -1 && (size_t) r < size)
508 if (r > -1) /* glibc 2.1 */
515 /* Similar to OpenBSD's strlcpy() function */
516 char *pa_strlcpy(char *b, const char *s, size_t l) {
526 /* Make the current thread a realtime thread, and acquire the highest
527 * rtprio we can get that is less or equal the specified parameter. If
528 * the thread is already realtime, don't do anything. */
529 int pa_make_realtime(int rtprio) {
531 #ifdef _POSIX_PRIORITY_SCHEDULING
532 struct sched_param sp;
535 memset(&sp, 0, sizeof(sp));
538 if ((r = pthread_getschedparam(pthread_self(), &policy, &sp)) != 0) {
539 pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r));
543 if (policy == SCHED_FIFO && sp.sched_priority >= rtprio) {
544 pa_log_info("Thread already being scheduled with SCHED_FIFO with priority %i.", sp.sched_priority);
548 sp.sched_priority = rtprio;
549 if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) != 0) {
551 while (sp.sched_priority > 1) {
552 sp.sched_priority --;
554 if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) == 0) {
555 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i, which is lower than the requested %i.", sp.sched_priority, rtprio);
560 pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r));
564 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority);
573 /* This is merely used for giving the user a hint. This is not correct
574 * for anything security related */
575 pa_bool_t pa_can_realtime(void) {
580 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
584 if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0)
585 if (rl.rlim_cur > 0 || rl.rlim_cur == RLIM_INFINITY)
590 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
594 if ((cap = cap_get_proc())) {
595 cap_flag_value_t flag = CAP_CLEAR;
597 if (cap_get_flag(cap, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0)
598 if (flag == CAP_SET) {
611 /* This is merely used for giving the user a hint. This is not correct
612 * for anything security related */
613 pa_bool_t pa_can_high_priority(void) {
618 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
622 if (getrlimit(RLIMIT_NICE, &rl) >= 0)
623 if (rl.rlim_cur >= 21 || rl.rlim_cur == RLIM_INFINITY)
628 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
632 if ((cap = cap_get_proc())) {
633 cap_flag_value_t flag = CAP_CLEAR;
635 if (cap_get_flag(cap, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0)
636 if (flag == CAP_SET) {
649 /* Raise the priority of the current process as much as possible that
650 * is <= the specified nice level..*/
651 int pa_raise_priority(int nice_level) {
653 #ifdef HAVE_SYS_RESOURCE_H
654 if (setpriority(PRIO_PROCESS, 0, nice_level) < 0) {
657 for (n = nice_level+1; n < 0; n++) {
659 if (setpriority(PRIO_PROCESS, 0, n) == 0) {
660 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
665 pa_log_warn("setpriority(): %s", pa_cstrerror(errno));
669 pa_log_info("Successfully gained nice level %i.", nice_level);
673 if (nice_level < 0) {
674 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
675 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
679 pa_log_info("Successfully gained high priority class.");
686 /* Reset the priority to normal, inverting the changes made by
687 * pa_raise_priority() and pa_make_realtime()*/
688 void pa_reset_priority(void) {
689 #ifdef HAVE_SYS_RESOURCE_H
690 struct sched_param sp;
692 setpriority(PRIO_PROCESS, 0, 0);
694 memset(&sp, 0, sizeof(sp));
695 pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp) == 0);
699 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
703 static int match(const char *expr, const char *v) {
708 if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
713 if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
715 else if (k == REG_NOMATCH)
728 /* Try to parse a boolean string value.*/
729 int pa_parse_boolean(const char *v) {
734 /* First we check language independant */
735 if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
737 else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
740 /* And then we check language dependant */
741 if ((expr = nl_langinfo(YESEXPR)))
743 if ((r = match(expr, v)) > 0)
746 if ((expr = nl_langinfo(NOEXPR)))
748 if ((r = match(expr, v)) > 0)
755 /* Split the specified string wherever one of the strings in delimiter
756 * occurs. Each time it is called returns a newly allocated string
757 * with pa_xmalloc(). The variable state points to, should be
758 * initiallized to NULL before the first call. */
759 char *pa_split(const char *c, const char *delimiter, const char**state) {
760 const char *current = *state ? *state : c;
766 l = strcspn(current, delimiter);
772 return pa_xstrndup(current, l);
775 /* What is interpreted as whitespace? */
776 #define WHITESPACE " \t\n"
778 /* Split a string into words. Otherwise similar to pa_split(). */
779 char *pa_split_spaces(const char *c, const char **state) {
780 const char *current = *state ? *state : c;
783 if (!*current || *c == 0)
786 current += strspn(current, WHITESPACE);
787 l = strcspn(current, WHITESPACE);
791 return pa_xstrndup(current, l);
794 PA_STATIC_TLS_DECLARE(signame, pa_xfree);
796 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
797 const char *pa_sig2str(int sig) {
810 char buf[SIG2STR_MAX];
812 if (sig2str(sig, buf) == 0) {
813 pa_xfree(PA_STATIC_TLS_GET(signame));
814 t = pa_sprintf_malloc("SIG%s", buf);
815 PA_STATIC_TLS_SET(signame, t);
823 case SIGHUP: return "SIGHUP";
825 case SIGINT: return "SIGINT";
827 case SIGQUIT: return "SIGQUIT";
829 case SIGILL: return "SIGULL";
831 case SIGTRAP: return "SIGTRAP";
833 case SIGABRT: return "SIGABRT";
835 case SIGBUS: return "SIGBUS";
837 case SIGFPE: return "SIGFPE";
839 case SIGKILL: return "SIGKILL";
842 case SIGUSR1: return "SIGUSR1";
844 case SIGSEGV: return "SIGSEGV";
846 case SIGUSR2: return "SIGUSR2";
849 case SIGPIPE: return "SIGPIPE";
852 case SIGALRM: return "SIGALRM";
854 case SIGTERM: return "SIGTERM";
856 case SIGSTKFLT: return "SIGSTKFLT";
859 case SIGCHLD: return "SIGCHLD";
862 case SIGCONT: return "SIGCONT";
865 case SIGSTOP: return "SIGSTOP";
868 case SIGTSTP: return "SIGTSTP";
871 case SIGTTIN: return "SIGTTIN";
874 case SIGTTOU: return "SIGTTOU";
877 case SIGURG: return "SIGURG";
880 case SIGXCPU: return "SIGXCPU";
883 case SIGXFSZ: return "SIGXFSZ";
886 case SIGVTALRM: return "SIGVTALRM";
889 case SIGPROF: return "SIGPROF";
892 case SIGWINCH: return "SIGWINCH";
895 case SIGIO: return "SIGIO";
898 case SIGPWR: return "SIGPWR";
901 case SIGSYS: return "SIGSYS";
906 if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
907 pa_xfree(PA_STATIC_TLS_GET(signame));
908 t = pa_sprintf_malloc("SIGRTMIN+%i", sig - SIGRTMIN);
909 PA_STATIC_TLS_SET(signame, t);
918 pa_xfree(PA_STATIC_TLS_GET(signame));
919 t = pa_sprintf_malloc("SIG%i", sig);
920 PA_STATIC_TLS_SET(signame, t);
926 /* Check whether the specified GID and the group name match */
927 static int is_group(gid_t gid, const char *name) {
928 struct group group, *result = NULL;
933 #ifdef HAVE_GETGRGID_R
934 #ifdef _SC_GETGR_R_SIZE_MAX
935 n = sysconf(_SC_GETGR_R_SIZE_MAX);
942 data = pa_xmalloc((size_t) n);
945 if (getgrgid_r(gid, &group, data, (size_t) n, &result) < 0 || !result) {
946 pa_log("getgrgid_r(%u): %s", (unsigned) gid, pa_cstrerror(errno));
954 r = strcmp(name, result->gr_name) == 0;
959 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not
960 * support getgrgid_r. */
963 if (!(result = getgrgid(gid))) {
964 pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno));
972 r = strcmp(name, result->gr_name) == 0;
980 /* Check the current user is member of the specified group */
981 int pa_own_uid_in_group(const char *name, gid_t *gid) {
982 GETGROUPS_T *gids, tgid;
983 long n = sysconf(_SC_NGROUPS_MAX);
988 gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
990 if ((n = getgroups((int) n, gids)) < 0) {
991 pa_log("getgroups(): %s", pa_cstrerror(errno));
995 for (i = 0; i < n; i++) {
997 if ((k = is_group(gids[i], name)) < 0)
1006 if ((k = is_group(tgid = getgid(), name)) < 0)
1022 /* Check whether the specifc user id is a member of the specified group */
1023 int pa_uid_in_group(uid_t uid, const char *name) {
1024 char *g_buf, *p_buf;
1026 struct group grbuf, *gr;
1030 #ifdef _SC_GETGR_R_SIZE_MAX
1031 g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
1038 g_buf = pa_xmalloc((size_t) g_n);
1040 #ifdef _SC_GETPW_R_SIZE_MAX
1041 p_n = sysconf(_SC_GETPW_R_SIZE_MAX);
1048 p_buf = pa_xmalloc((size_t) p_n);
1051 #ifdef HAVE_GETGRNAM_R
1052 if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
1054 if (!(gr = getgrnam(name)))
1063 for (i = gr->gr_mem; *i; i++) {
1064 struct passwd pwbuf, *pw;
1066 #ifdef HAVE_GETPWNAM_R
1067 if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw)
1069 if (!(pw = getpwnam(*i)))
1073 if (pw->pw_uid == uid) {
1086 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
1087 gid_t pa_get_gid_of_group(const char *name) {
1088 gid_t ret = (gid_t) -1;
1091 struct group grbuf, *gr;
1093 #ifdef _SC_GETGR_R_SIZE_MAX
1094 g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
1101 g_buf = pa_xmalloc((size_t) g_n);
1104 #ifdef HAVE_GETGRNAM_R
1105 if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
1107 if (!(gr = getgrnam(name)))
1122 int pa_check_in_group(gid_t g) {
1123 gid_t gids[NGROUPS_MAX];
1126 if ((r = getgroups(NGROUPS_MAX, gids)) < 0)
1136 #else /* HAVE_GRP_H */
1138 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1144 int pa_uid_in_group(uid_t uid, const char *name) {
1149 gid_t pa_get_gid_of_group(const char *name) {
1154 int pa_check_in_group(gid_t g) {
1161 /* Lock or unlock a file entirely.
1162 (advisory on UNIX, mandatory on Windows) */
1163 int pa_lock_fd(int fd, int b) {
1167 /* Try a R/W lock first */
1169 flock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
1170 flock.l_whence = SEEK_SET;
1174 if (fcntl(fd, F_SETLKW, &flock) >= 0)
1177 /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
1178 if (b && errno == EBADF) {
1179 flock.l_type = F_RDLCK;
1180 if (fcntl(fd, F_SETLKW, &flock) >= 0)
1184 pa_log("%slock: %s", !b? "un" : "", pa_cstrerror(errno));
1188 HANDLE h = (HANDLE)_get_osfhandle(fd);
1190 if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1192 if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1195 pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError());
1197 /* FIXME: Needs to set errno! */
1203 /* Remove trailing newlines from a string */
1204 char* pa_strip_nl(char *s) {
1207 s[strcspn(s, "\r\n")] = 0;
1211 /* Create a temporary lock file and lock it. */
1212 int pa_lock_lockfile(const char *fn) {
1219 if ((fd = open(fn, O_CREAT|O_RDWR
1226 , S_IRUSR|S_IWUSR)) < 0) {
1227 pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno));
1231 if (pa_lock_fd(fd, 1) < 0) {
1232 pa_log_warn("Failed to lock file '%s'.", fn);
1236 if (fstat(fd, &st) < 0) {
1237 pa_log_warn("Failed to fstat() file '%s': %s", fn, pa_cstrerror(errno));
1241 /* Check wheter the file has been removed meanwhile. When yes,
1242 * restart this loop, otherwise, we're done */
1243 if (st.st_nlink >= 1)
1246 if (pa_lock_fd(fd, 0) < 0) {
1247 pa_log_warn("Failed to unlock file '%s'.", fn);
1251 if (pa_close(fd) < 0) {
1252 pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno));
1265 int saved_errno = errno;
1267 errno = saved_errno;
1273 /* Unlock a temporary lcok file */
1274 int pa_unlock_lockfile(const char *fn, int fd) {
1279 if (unlink(fn) < 0) {
1280 pa_log_warn("Unable to remove lock file '%s': %s", fn, pa_cstrerror(errno));
1285 if (pa_lock_fd(fd, 0) < 0) {
1286 pa_log_warn("Failed to unlock file '%s'.", fn);
1290 if (pa_close(fd) < 0) {
1291 pa_log_warn("Failed to close '%s': %s", fn, pa_cstrerror(errno));
1298 static char *get_pulse_home(void) {
1302 if (!pa_get_home_dir(h, sizeof(h))) {
1303 pa_log_error("Failed to get home directory.");
1307 if (stat(h, &st) < 0) {
1308 pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno));
1312 if (st.st_uid != getuid()) {
1313 pa_log_error("Home directory %s not ours.", h);
1318 return pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
1321 char *pa_get_state_dir(void) {
1324 /* The state directory shall contain dynamic data that should be
1325 * kept across reboots, and is private to this user */
1327 if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1328 if (!(d = get_pulse_home()))
1331 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1332 * dir then this will break. */
1334 if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0) {
1335 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1343 static char* make_random_dir(mode_t m) {
1344 static const char table[] =
1345 "abcdefghijklmnopqrstuvwxyz"
1346 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1353 if (!(tmpdir = getenv("TMPDIR")))
1354 if (!(tmpdir = getenv("TMP")))
1355 if (!(tmpdir = getenv("TEMP")))
1356 tmpdir = getenv("TEMPDIR");
1358 if (!tmpdir || !pa_is_path_absolute(tmpdir))
1361 fn = pa_sprintf_malloc("%s/pulse-XXXXXXXXXXXX", tmpdir);
1362 pathlen = strlen(fn);
1370 for (i = pathlen - 12; i < pathlen; i++)
1371 fn[i] = table[rand() % (sizeof(table)-1)];
1373 u = umask((~m) & 0777);
1376 saved_errno = errno;
1378 errno = saved_errno;
1383 if (errno != EEXIST) {
1384 pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
1391 static int make_random_dir_and_link(mode_t m, const char *k) {
1394 if (!(p = make_random_dir(m)))
1397 if (symlink(p, k) < 0) {
1398 int saved_errno = errno;
1400 if (errno != EEXIST)
1401 pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno));
1406 errno = saved_errno;
1413 char *pa_get_runtime_dir(void) {
1414 char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
1418 /* The runtime directory shall contain dynamic data that needs NOT
1419 * to be kept accross reboots and is usuallly private to the user,
1420 * except in system mode, where it might be accessible by other
1421 * users, too. Since we need POSIX locking and UNIX sockets in
1422 * this directory, we link it to a random subdir in /tmp, if it
1423 * was not explicitly configured. */
1425 m = pa_in_system_mode() ? 0755U : 0700U;
1427 if ((d = getenv("PULSE_RUNTIME_PATH"))) {
1429 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
1430 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1434 return pa_xstrdup(d);
1437 if (!(d = get_pulse_home()))
1440 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
1441 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1445 if (!(mid = pa_machine_id())) {
1450 k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:runtime", d, mid);
1455 /* OK, first let's check if the "runtime" symlink is already
1458 if (!(p = pa_readlink(k))) {
1460 if (errno != ENOENT) {
1461 pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
1465 /* Hmm, so the runtime directory didn't exist yet, so let's
1466 * create one in /tmp and symlink that to it */
1468 if (make_random_dir_and_link(0700, k) < 0) {
1470 /* Mhmm, maybe another process was quicker than us,
1471 * let's check if that was valid */
1472 if (errno == EEXIST)
1481 /* Make sure that this actually makes sense */
1482 if (!pa_is_path_absolute(p)) {
1483 pa_log_error("Path %s in link %s is not absolute.", p, k);
1488 /* Hmm, so this symlink is still around, make sure nobody fools
1491 if (lstat(p, &st) < 0) {
1493 if (errno != ENOENT) {
1494 pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno));
1500 if (S_ISDIR(st.st_mode) &&
1501 (st.st_uid == getuid()) &&
1502 ((st.st_mode & 0777) == 0700)) {
1508 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1514 /* Hmm, so the link points to some nonexisting or invalid
1515 * dir. Let's replace it by a new link. We first create a
1516 * temporary link and then rename that to allow concurrent
1517 * execution of this function. */
1519 t = pa_sprintf_malloc("%s.tmp", k);
1521 if (make_random_dir_and_link(0700, t) < 0) {
1523 if (errno != EEXIST) {
1524 pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno));
1531 /* Hmm, someone lese was quicker then us. Let's give
1532 * him some time to finish, and retry. */
1537 /* OK, we succeeded in creating the temporary symlink, so
1538 * let's rename it */
1539 if (rename(t, k) < 0) {
1540 pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno));
1556 /* Try to open a configuration file. If "env" is specified, open the
1557 * value of the specified environment variable. Otherwise look for a
1558 * file "local" in the home directory or a file "global" in global
1559 * file system. If "result" is non-NULL, a pointer to a newly
1560 * allocated buffer containing the used configuration file is
1562 FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
1567 if (!getenv(PULSE_ROOTENV))
1571 if (env && (fn = getenv(env))) {
1575 if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
1576 /* FIXME: Needs to set errno! */
1581 if ((f = fopen(fn, "r"))) {
1583 *result = pa_xstrdup(fn);
1588 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1598 if ((e = getenv("PULSE_CONFIG_PATH")))
1599 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1600 else if (pa_get_home_dir(h, sizeof(h)))
1601 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1606 if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
1607 /* FIXME: Needs to set errno! */
1614 if ((f = fopen(fn, "r"))) {
1616 *result = pa_xstrdup(fn);
1622 if (errno != ENOENT) {
1623 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1635 if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
1636 /* FIXME: Needs to set errno! */
1641 if ((f = fopen(global, "r"))) {
1644 *result = pa_xstrdup(global);
1654 char *pa_find_config_file(const char *global, const char *local, const char *env) {
1659 if (!getenv(PULSE_ROOTENV))
1663 if (env && (fn = getenv(env))) {
1666 if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
1667 /* FIXME: Needs to set errno! */
1672 if (access(fn, R_OK) == 0)
1673 return pa_xstrdup(fn);
1675 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1684 if ((e = getenv("PULSE_CONFIG_PATH")))
1685 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1686 else if (pa_get_home_dir(h, sizeof(h)))
1687 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1692 if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
1693 /* FIXME: Needs to set errno! */
1700 if (access(fn, R_OK) == 0) {
1701 char *r = pa_xstrdup(fn);
1706 if (errno != ENOENT) {
1707 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1717 if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
1718 /* FIXME: Needs to set errno! */
1723 if (access(global, R_OK) == 0)
1724 return pa_xstrdup(global);
1732 /* Format the specified data as a hexademical string */
1733 char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {
1734 size_t i = 0, j = 0;
1735 const char hex[] = "0123456789abcdef";
1739 pa_assert(slength > 0);
1741 while (i < dlength && j+3 <= slength) {
1742 s[j++] = hex[*d >> 4];
1743 s[j++] = hex[*d & 0xF];
1749 s[j < slength ? j : slength] = 0;
1753 /* Convert a hexadecimal digit to a number or -1 if invalid */
1754 static int hexc(char c) {
1755 if (c >= '0' && c <= '9')
1758 if (c >= 'A' && c <= 'F')
1759 return c - 'A' + 10;
1761 if (c >= 'a' && c <= 'f')
1762 return c - 'a' + 10;
1768 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1769 size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) {
1775 while (j < dlength && *p) {
1778 if ((b = hexc(*(p++))) < 0)
1781 d[j] = (uint8_t) (b << 4);
1786 if ((b = hexc(*(p++))) < 0)
1789 d[j] |= (uint8_t) b;
1796 /* Returns nonzero when *s starts with *pfx */
1797 pa_bool_t pa_startswith(const char *s, const char *pfx) {
1805 return strlen(s) >= l && strncmp(s, pfx, l) == 0;
1808 /* Returns nonzero when *s ends with *sfx */
1809 pa_bool_t pa_endswith(const char *s, const char *sfx) {
1818 return l1 >= l2 && strcmp(s+l1-l2, sfx) == 0;
1821 pa_bool_t pa_is_path_absolute(const char *fn) {
1827 return strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\';
1831 char *pa_make_path_absolute(const char *p) {
1837 if (pa_is_path_absolute(p))
1838 return pa_xstrdup(p);
1840 if (!(cwd = pa_getcwd()))
1841 return pa_xstrdup(p);
1843 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", cwd, p);
1848 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
1849 * if fn is non-null and starts with / return fn
1850 * otherwise append fn to the run time path and return it */
1851 static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {
1854 if (pa_is_path_absolute(fn))
1855 return pa_xstrdup(fn);
1857 rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
1868 if (!(mid = pa_machine_id())) {
1873 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:%s", rtp, mid, fn);
1876 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn);
1884 char *pa_runtime_path(const char *fn) {
1885 return get_path(fn, FALSE, TRUE);
1888 char *pa_state_path(const char *fn, pa_bool_t appendmid) {
1889 return get_path(fn, appendmid, FALSE);
1892 /* Convert the string s to a signed integer in *ret_i */
1893 int pa_atoi(const char *s, int32_t *ret_i) {
1901 l = strtol(s, &x, 0);
1903 if (!x || *x || errno) {
1909 if ((int32_t) l != l) {
1914 *ret_i = (int32_t) l;
1919 /* Convert the string s to an unsigned integer in *ret_u */
1920 int pa_atou(const char *s, uint32_t *ret_u) {
1928 l = strtoul(s, &x, 0);
1930 if (!x || *x || errno) {
1936 if ((uint32_t) l != l) {
1941 *ret_u = (uint32_t) l;
1946 #ifdef HAVE_STRTOF_L
1947 static locale_t c_locale = NULL;
1949 static void c_locale_destroy(void) {
1950 freelocale(c_locale);
1954 int pa_atod(const char *s, double *ret_d) {
1961 /* This should be locale independent */
1963 #ifdef HAVE_STRTOF_L
1967 if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL)))
1968 atexit(c_locale_destroy);
1974 f = strtod_l(s, &x, c_locale);
1982 if (!x || *x || errno) {
1993 /* Same as snprintf, but guarantees NUL-termination on every platform */
1994 size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
1999 pa_assert(size > 0);
2002 va_start(ap, format);
2003 ret = pa_vsnprintf(str, size, format, ap);
2009 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2010 size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
2014 pa_assert(size > 0);
2017 ret = vsnprintf(str, size, format, ap);
2024 if ((size_t) ret > size-1)
2027 return (size_t) ret;
2030 /* Truncate the specified string, but guarantee that the string
2031 * returned still validates as UTF8 */
2032 char *pa_truncate_utf8(char *c, size_t l) {
2034 pa_assert(pa_utf8_valid(c));
2041 while (l > 0 && !pa_utf8_valid(c))
2047 char *pa_getcwd(void) {
2051 char *p = pa_xmalloc(l);
2055 if (errno != ERANGE)
2063 void *pa_will_need(const void *p, size_t l) {
2064 #ifdef RLIMIT_MEMLOCK
2075 a = PA_PAGE_ALIGN_PTR(p);
2076 size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
2078 #ifdef HAVE_POSIX_MADVISE
2079 if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
2080 pa_log_debug("posix_madvise() worked fine!");
2085 /* Most likely the memory was not mmap()ed from a file and thus
2086 * madvise() didn't work, so let's misuse mlock() do page this
2087 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2088 * inviting, the man page of mlock() tells us: "All pages that
2089 * contain a part of the specified address range are guaranteed to
2090 * be resident in RAM when the call returns successfully." */
2092 #ifdef RLIMIT_MEMLOCK
2093 pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
2095 if (rlim.rlim_cur < PA_PAGE_SIZE) {
2096 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));
2101 bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
2103 bs = PA_PAGE_SIZE*4;
2106 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r));
2109 while (size > 0 && bs > 0) {
2114 if (mlock(a, bs) < 0) {
2115 bs = PA_PAGE_ALIGN(bs / 2);
2119 pa_assert_se(munlock(a, bs) == 0);
2121 a = (const uint8_t*) a + bs;
2127 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno));
2129 pa_log_debug("mlock() worked fine!");
2134 void pa_close_pipe(int fds[2]) {
2138 pa_assert_se(pa_close(fds[0]) == 0);
2141 pa_assert_se(pa_close(fds[1]) == 0);
2143 fds[0] = fds[1] = -1;
2146 char *pa_readlink(const char *p) {
2155 if ((n = readlink(p, c, l-1)) < 0) {
2160 if ((size_t) n < l-1) {
2170 int pa_close_all(int except_fd, ...) {
2175 va_start(ap, except_fd);
2178 for (n = 1; va_arg(ap, int) >= 0; n++)
2183 p = pa_xnew(int, n+1);
2185 va_start(ap, except_fd);
2188 if (except_fd >= 0) {
2192 while ((fd = va_arg(ap, int)) >= 0)
2199 r = pa_close_allv(p);
2205 int pa_close_allv(const int except_fds[]) {
2214 if ((d = opendir("/proc/self/fd"))) {
2218 while ((de = readdir(d))) {
2224 if (de->d_name[0] == '.')
2228 l = strtol(de->d_name, &e, 10);
2229 if (errno != 0 || !e || *e) {
2237 if ((long) fd != l) {
2250 for (i = 0; except_fds[i] >= 0; i++)
2251 if (except_fds[i] == fd) {
2259 if (pa_close(fd) < 0) {
2260 saved_errno = errno;
2262 errno = saved_errno;
2274 if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
2277 for (fd = 3; fd < (int) rl.rlim_max; fd++) {
2282 for (i = 0; except_fds[i] >= 0; i++)
2283 if (except_fds[i] == fd) {
2291 if (pa_close(fd) < 0 && errno != EBADF)
2298 int pa_unblock_sigs(int except, ...) {
2303 va_start(ap, except);
2306 for (n = 1; va_arg(ap, int) >= 0; n++)
2311 p = pa_xnew(int, n+1);
2313 va_start(ap, except);
2320 while ((sig = va_arg(ap, int)) >= 0)
2327 r = pa_unblock_sigsv(p);
2333 int pa_unblock_sigsv(const int except[]) {
2337 if (sigemptyset(&ss) < 0)
2340 for (i = 0; except[i] > 0; i++)
2341 if (sigaddset(&ss, except[i]) < 0)
2344 return sigprocmask(SIG_SETMASK, &ss, NULL);
2347 int pa_reset_sigs(int except, ...) {
2352 va_start(ap, except);
2355 for (n = 1; va_arg(ap, int) >= 0; n++)
2360 p = pa_xnew(int, n+1);
2362 va_start(ap, except);
2369 while ((sig = va_arg(ap, int)) >= 0)
2376 r = pa_reset_sigsv(p);
2382 int pa_reset_sigsv(const int except[]) {
2385 for (sig = 1; sig < NSIG; sig++) {
2386 pa_bool_t reset = TRUE;
2397 for (i = 0; except[i] > 0; i++) {
2398 if (sig == except[i]) {
2407 struct sigaction sa;
2409 memset(&sa, 0, sizeof(sa));
2410 sa.sa_handler = SIG_DFL;
2412 /* On Linux the first two RT signals are reserved by
2413 * glibc, and sigaction() will return EINVAL for them. */
2414 if ((sigaction(sig, &sa, NULL) < 0))
2415 if (errno != EINVAL)
2423 void pa_set_env(const char *key, const char *value) {
2427 putenv(pa_sprintf_malloc("%s=%s", key, value));
2430 pa_bool_t pa_in_system_mode(void) {
2433 if (!(e = getenv("PULSE_SYSTEM")))
2439 char *pa_machine_id(void) {
2443 /* The returned value is supposed be some kind of ascii identifier
2444 * that is unique and stable across reboots. */
2446 /* First we try the D-Bus UUID, which is the best option we have,
2447 * since it fits perfectly our needs and is not as volatile as the
2448 * hostname which might be set from dhcp. */
2450 if ((f = fopen(PA_MACHINE_ID, "r"))) {
2451 char ln[34] = "", *r;
2453 r = fgets(ln, sizeof(ln)-1, f);
2459 return pa_xstrdup(ln);
2462 /* The we fall back to the host name. It supposed to be somewhat
2463 * unique, at least in a network, but may change. */
2471 if (!pa_get_host_name(c, l)) {
2473 if (errno != EINVAL && errno != ENAMETOOLONG)
2476 } else if (strlen(c) < l-1) {
2486 /* Hmm, the hostname is as long the space we offered the
2487 * function, we cannot know if it fully fit in, so let's play
2488 * safe and retry. */
2494 /* If no hostname was set we use the POSIX hostid. It's usually
2495 * the IPv4 address. Mit not be that stable. */
2496 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
2499 char *pa_uname_string(void) {
2502 pa_assert_se(uname(&u) == 0);
2504 return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
2507 #ifdef HAVE_VALGRIND_MEMCHECK_H
2508 pa_bool_t pa_in_valgrind(void) {
2511 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
2512 * here instead of really checking whether we run in valgrind or
2516 b = getenv("VALGRIND") ? 2 : 1;
2522 unsigned pa_gcd(unsigned a, unsigned b) {
2533 void pa_reduce(unsigned *num, unsigned *den) {
2535 unsigned gcd = pa_gcd(*num, *den);
2543 pa_assert(pa_gcd(*num, *den) == 1);
2546 unsigned pa_ncpus(void) {
2549 #ifdef _SC_NPROCESSORS_CONF
2550 ncpus = sysconf(_SC_NPROCESSORS_CONF);
2555 return ncpus <= 0 ? 1 : (unsigned) ncpus;
2558 char *pa_replace(const char*s, const char*a, const char *b) {
2567 sb = pa_strbuf_new();
2572 if (!(p = strstr(s, a)))
2575 pa_strbuf_putsn(sb, s, p-s);
2576 pa_strbuf_puts(sb, b);
2580 pa_strbuf_puts(sb, s);
2582 return pa_strbuf_tostring_free(sb);
2585 char *pa_unescape(char *p) {
2587 pa_bool_t escaped = FALSE;
2589 for (s = p, d = p; *s; s++) {
2590 if (!escaped && *s == '\\') {