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>
101 #include "core-util.h"
103 /* Not all platforms have this */
105 #define MSG_NOSIGNAL 0
110 #define PULSE_ROOTENV "PULSE_ROOT"
112 int pa_set_root(HANDLE handle) {
113 char library_path[MAX_PATH + sizeof(PULSE_ROOTENV) + 1], *sep;
115 strcpy(library_path, PULSE_ROOTENV "=");
117 /* FIXME: Needs to set errno */
119 if (!GetModuleFileName(handle, library_path + sizeof(PULSE_ROOTENV), MAX_PATH))
122 sep = strrchr(library_path, PA_PATH_SEP_CHAR);
126 if (_putenv(library_path) < 0)
134 /** Make a file descriptor nonblock. Doesn't do any error checking */
135 void pa_make_fd_nonblock(int fd) {
141 pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
143 if (!(v & O_NONBLOCK))
144 pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0);
146 #elif defined(OS_IS_WIN32)
148 if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
149 pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
150 pa_log_warn("Only sockets can be made non-blocking!");
153 pa_log_warn("Non-blocking I/O not supported.!");
158 /* Set the FD_CLOEXEC flag for a fd */
159 void pa_make_fd_cloexec(int fd) {
165 pa_assert_se((v = fcntl(fd, F_GETFD, 0)) >= 0);
167 if (!(v & FD_CLOEXEC))
168 pa_assert_se(fcntl(fd, F_SETFD, v|FD_CLOEXEC) >= 0);
173 /** Creates a directory securely */
174 int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
185 u = umask((~m) & 0777);
191 if (r < 0 && errno != EEXIST)
195 if (uid == (uid_t)-1)
197 if (gid == (gid_t)-1)
199 (void) chown(dir, uid, gid);
207 if (lstat(dir, &st) < 0)
209 if (stat(dir, &st) < 0)
214 if (!S_ISDIR(st.st_mode) ||
215 (st.st_uid != uid) ||
216 (st.st_gid != gid) ||
217 ((st.st_mode & 0777) != m)) {
222 pa_log_warn("Secure directory creation not supported on Win32.");
235 /* Return a newly allocated sting containing the parent directory of the specified file */
236 char *pa_parent_dir(const char *fn) {
237 char *slash, *dir = pa_xstrdup(fn);
239 if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
249 /* Creates a the parent directory of the specified path securely */
250 int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {
254 if (!(dir = pa_parent_dir(fn)))
257 if (pa_make_secure_dir(dir, m, uid, gid) < 0)
267 /** Platform independent read function. Necessary since not all
268 * systems treat all file descriptors equal. If type is
269 * non-NULL it is used to cache the type of the fd. This is
270 * useful for making sure that only a single syscall is executed per
271 * function call. The variable pointed to should be initialized to 0
273 ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
277 if (!type || *type == 0) {
280 if ((r = recv(fd, buf, count, 0)) >= 0)
283 if (WSAGetLastError() != WSAENOTSOCK) {
284 errno = WSAGetLastError();
294 return read(fd, buf, count);
297 /** Similar to pa_read(), but handles writes */
298 ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
300 if (!type || *type == 0) {
303 if ((r = send(fd, buf, count, MSG_NOSIGNAL)) >= 0)
307 if (WSAGetLastError() != WSAENOTSOCK) {
308 errno = WSAGetLastError();
312 if (errno != ENOTSOCK)
320 return write(fd, buf, count);
323 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
324 * unless EOF is reached or an error occured */
325 ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
341 if ((r = pa_read(fd, data, size, type)) < 0)
348 data = (uint8_t*) data + r;
355 /** Similar to pa_loop_read(), but wraps write() */
356 ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
372 if ((r = pa_write(fd, data, size, type)) < 0)
379 data = (const uint8_t*) data + r;
386 /** Platform independent read function. Necessary since not all
387 * systems treat all file descriptors equal. */
388 int pa_close(int fd) {
393 if ((ret = closesocket(fd)) == 0)
396 if (WSAGetLastError() != WSAENOTSOCK) {
397 errno = WSAGetLastError();
405 if ((r = close(fd)) >= 0)
413 /* Print a warning messages in case that the given signal is not
414 * blocked or trapped */
415 void pa_check_signal_is_blocked(int sig) {
416 #ifdef HAVE_SIGACTION
420 /* If POSIX threads are supported use thread-aware
421 * pthread_sigmask() function, to check if the signal is
422 * blocked. Otherwise fall back to sigprocmask() */
425 if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) {
427 if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) {
428 pa_log("sigprocmask(): %s", pa_cstrerror(errno));
435 if (sigismember(&set, sig))
438 /* Check whether the signal is trapped */
440 if (sigaction(sig, NULL, &sa) < 0) {
441 pa_log("sigaction(): %s", pa_cstrerror(errno));
445 if (sa.sa_handler != SIG_DFL)
448 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig));
449 #else /* HAVE_SIGACTION */
450 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig));
454 /* The following function is based on an example from the GNU libc
455 * documentation. This function is similar to GNU's asprintf(). */
456 char *pa_sprintf_malloc(const char *format, ...) {
466 c = pa_xrealloc(c, size);
468 va_start(ap, format);
469 r = vsnprintf(c, size, format, ap);
474 if (r > -1 && (size_t) r < size)
477 if (r > -1) /* glibc 2.1 */
484 /* Same as the previous function, but use a va_list instead of an
486 char *pa_vsprintf_malloc(const char *format, va_list ap) {
496 c = pa_xrealloc(c, size);
499 r = vsnprintf(c, size, format, aq);
504 if (r > -1 && (size_t) r < size)
507 if (r > -1) /* glibc 2.1 */
514 /* Similar to OpenBSD's strlcpy() function */
515 char *pa_strlcpy(char *b, const char *s, size_t l) {
525 /* Make the current thread a realtime thread, and acquire the highest
526 * rtprio we can get that is less or equal the specified parameter. If
527 * the thread is already realtime, don't do anything. */
528 int pa_make_realtime(int rtprio) {
530 #ifdef _POSIX_PRIORITY_SCHEDULING
531 struct sched_param sp;
534 memset(&sp, 0, sizeof(sp));
537 if ((r = pthread_getschedparam(pthread_self(), &policy, &sp)) != 0) {
538 pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r));
542 if (policy == SCHED_FIFO && sp.sched_priority >= rtprio) {
543 pa_log_info("Thread already being scheduled with SCHED_FIFO with priority %i.", sp.sched_priority);
547 sp.sched_priority = rtprio;
548 if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) != 0) {
550 while (sp.sched_priority > 1) {
551 sp.sched_priority --;
553 if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) == 0) {
554 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i, which is lower than the requested %i.", sp.sched_priority, rtprio);
559 pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r));
563 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority);
572 /* This is merely used for giving the user a hint. This is not correct
573 * for anything security related */
574 pa_bool_t pa_can_realtime(void) {
579 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
583 if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0)
584 if (rl.rlim_cur > 0 || rl.rlim_cur == RLIM_INFINITY)
589 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
593 if ((cap = cap_get_proc())) {
594 cap_flag_value_t flag = CAP_CLEAR;
596 if (cap_get_flag(cap, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0)
597 if (flag == CAP_SET) {
610 /* This is merely used for giving the user a hint. This is not correct
611 * for anything security related */
612 pa_bool_t pa_can_high_priority(void) {
617 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
621 if (getrlimit(RLIMIT_NICE, &rl) >= 0)
622 if (rl.rlim_cur >= 21 || rl.rlim_cur == RLIM_INFINITY)
627 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
631 if ((cap = cap_get_proc())) {
632 cap_flag_value_t flag = CAP_CLEAR;
634 if (cap_get_flag(cap, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0)
635 if (flag == CAP_SET) {
648 /* Raise the priority of the current process as much as possible that
649 * is <= the specified nice level..*/
650 int pa_raise_priority(int nice_level) {
652 #ifdef HAVE_SYS_RESOURCE_H
653 if (setpriority(PRIO_PROCESS, 0, nice_level) < 0) {
656 for (n = nice_level+1; n < 0; n++) {
658 if (setpriority(PRIO_PROCESS, 0, n) == 0) {
659 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
664 pa_log_warn("setpriority(): %s", pa_cstrerror(errno));
668 pa_log_info("Successfully gained nice level %i.", nice_level);
672 if (nice_level < 0) {
673 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
674 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
678 pa_log_info("Successfully gained high priority class.");
685 /* Reset the priority to normal, inverting the changes made by
686 * pa_raise_priority() and pa_make_realtime()*/
687 void pa_reset_priority(void) {
688 #ifdef HAVE_SYS_RESOURCE_H
689 struct sched_param sp;
691 setpriority(PRIO_PROCESS, 0, 0);
693 memset(&sp, 0, sizeof(sp));
694 pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp) == 0);
698 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
702 static int match(const char *expr, const char *v) {
707 if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
712 if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
714 else if (k == REG_NOMATCH)
727 /* Try to parse a boolean string value.*/
728 int pa_parse_boolean(const char *v) {
733 /* First we check language independant */
734 if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
736 else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
739 /* And then we check language dependant */
740 if ((expr = nl_langinfo(YESEXPR)))
742 if ((r = match(expr, v)) > 0)
745 if ((expr = nl_langinfo(NOEXPR)))
747 if ((r = match(expr, v)) > 0)
754 /* Split the specified string wherever one of the strings in delimiter
755 * occurs. Each time it is called returns a newly allocated string
756 * with pa_xmalloc(). The variable state points to, should be
757 * initiallized to NULL before the first call. */
758 char *pa_split(const char *c, const char *delimiter, const char**state) {
759 const char *current = *state ? *state : c;
765 l = strcspn(current, delimiter);
771 return pa_xstrndup(current, l);
774 /* What is interpreted as whitespace? */
775 #define WHITESPACE " \t\n"
777 /* Split a string into words. Otherwise similar to pa_split(). */
778 char *pa_split_spaces(const char *c, const char **state) {
779 const char *current = *state ? *state : c;
782 if (!*current || *c == 0)
785 current += strspn(current, WHITESPACE);
786 l = strcspn(current, WHITESPACE);
790 return pa_xstrndup(current, l);
793 PA_STATIC_TLS_DECLARE(signame, pa_xfree);
795 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
796 const char *pa_sig2str(int sig) {
809 char buf[SIG2STR_MAX];
811 if (sig2str(sig, buf) == 0) {
812 pa_xfree(PA_STATIC_TLS_GET(signame));
813 t = pa_sprintf_malloc("SIG%s", buf);
814 PA_STATIC_TLS_SET(signame, t);
822 case SIGHUP: return "SIGHUP";
824 case SIGINT: return "SIGINT";
826 case SIGQUIT: return "SIGQUIT";
828 case SIGILL: return "SIGULL";
830 case SIGTRAP: return "SIGTRAP";
832 case SIGABRT: return "SIGABRT";
834 case SIGBUS: return "SIGBUS";
836 case SIGFPE: return "SIGFPE";
838 case SIGKILL: return "SIGKILL";
841 case SIGUSR1: return "SIGUSR1";
843 case SIGSEGV: return "SIGSEGV";
845 case SIGUSR2: return "SIGUSR2";
848 case SIGPIPE: return "SIGPIPE";
851 case SIGALRM: return "SIGALRM";
853 case SIGTERM: return "SIGTERM";
855 case SIGSTKFLT: return "SIGSTKFLT";
858 case SIGCHLD: return "SIGCHLD";
861 case SIGCONT: return "SIGCONT";
864 case SIGSTOP: return "SIGSTOP";
867 case SIGTSTP: return "SIGTSTP";
870 case SIGTTIN: return "SIGTTIN";
873 case SIGTTOU: return "SIGTTOU";
876 case SIGURG: return "SIGURG";
879 case SIGXCPU: return "SIGXCPU";
882 case SIGXFSZ: return "SIGXFSZ";
885 case SIGVTALRM: return "SIGVTALRM";
888 case SIGPROF: return "SIGPROF";
891 case SIGWINCH: return "SIGWINCH";
894 case SIGIO: return "SIGIO";
897 case SIGPWR: return "SIGPWR";
900 case SIGSYS: return "SIGSYS";
905 if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
906 pa_xfree(PA_STATIC_TLS_GET(signame));
907 t = pa_sprintf_malloc("SIGRTMIN+%i", sig - SIGRTMIN);
908 PA_STATIC_TLS_SET(signame, t);
917 pa_xfree(PA_STATIC_TLS_GET(signame));
918 t = pa_sprintf_malloc("SIG%i", sig);
919 PA_STATIC_TLS_SET(signame, t);
925 /* Check whether the specified GID and the group name match */
926 static int is_group(gid_t gid, const char *name) {
927 struct group group, *result = NULL;
932 #ifdef HAVE_GETGRGID_R
933 #ifdef _SC_GETGR_R_SIZE_MAX
934 n = sysconf(_SC_GETGR_R_SIZE_MAX);
941 data = pa_xmalloc((size_t) n);
944 if (getgrgid_r(gid, &group, data, (size_t) n, &result) < 0 || !result) {
945 pa_log("getgrgid_r(%u): %s", (unsigned) gid, pa_cstrerror(errno));
953 r = strcmp(name, result->gr_name) == 0;
958 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not
959 * support getgrgid_r. */
962 if ((result = getgrgid(gid)) == NULL) {
963 pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno));
971 r = strcmp(name, result->gr_name) == 0;
979 /* Check the current user is member of the specified group */
980 int pa_own_uid_in_group(const char *name, gid_t *gid) {
981 GETGROUPS_T *gids, tgid;
982 long n = sysconf(_SC_NGROUPS_MAX);
987 gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
989 if ((n = getgroups((int) n, gids)) < 0) {
990 pa_log("getgroups(): %s", pa_cstrerror(errno));
994 for (i = 0; i < n; i++) {
996 if ((k = is_group(gids[i], name)) < 0)
1005 if ((k = is_group(tgid = getgid(), name)) < 0)
1021 /* Check whether the specifc user id is a member of the specified group */
1022 int pa_uid_in_group(uid_t uid, const char *name) {
1023 char *g_buf, *p_buf;
1025 struct group grbuf, *gr;
1029 g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
1030 g_buf = pa_xmalloc((size_t) g_n);
1032 p_n = sysconf(_SC_GETPW_R_SIZE_MAX);
1033 p_buf = pa_xmalloc((size_t) p_n);
1036 if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
1045 for (i = gr->gr_mem; *i; i++) {
1046 struct passwd pwbuf, *pw;
1049 if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw)
1052 if (pw->pw_uid == uid) {
1065 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
1066 gid_t pa_get_gid_of_group(const char *name) {
1067 gid_t ret = (gid_t) -1;
1070 struct group grbuf, *gr;
1072 g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
1073 g_buf = pa_xmalloc((size_t) g_n);
1076 if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
1091 int pa_check_in_group(gid_t g) {
1092 gid_t gids[NGROUPS_MAX];
1095 if ((r = getgroups(NGROUPS_MAX, gids)) < 0)
1105 #else /* HAVE_GRP_H */
1107 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1113 int pa_uid_in_group(uid_t uid, const char *name) {
1118 gid_t pa_get_gid_of_group(const char *name) {
1123 int pa_check_in_group(gid_t g) {
1130 /* Lock or unlock a file entirely.
1131 (advisory on UNIX, mandatory on Windows) */
1132 int pa_lock_fd(int fd, int b) {
1136 /* Try a R/W lock first */
1138 flock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
1139 flock.l_whence = SEEK_SET;
1143 if (fcntl(fd, F_SETLKW, &flock) >= 0)
1146 /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
1147 if (b && errno == EBADF) {
1148 flock.l_type = F_RDLCK;
1149 if (fcntl(fd, F_SETLKW, &flock) >= 0)
1153 pa_log("%slock: %s", !b? "un" : "", pa_cstrerror(errno));
1157 HANDLE h = (HANDLE)_get_osfhandle(fd);
1159 if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1161 if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1164 pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError());
1166 /* FIXME: Needs to set errno! */
1172 /* Remove trailing newlines from a string */
1173 char* pa_strip_nl(char *s) {
1176 s[strcspn(s, "\r\n")] = 0;
1180 /* Create a temporary lock file and lock it. */
1181 int pa_lock_lockfile(const char *fn) {
1188 if ((fd = open(fn, O_CREAT|O_RDWR
1195 , S_IRUSR|S_IWUSR)) < 0) {
1196 pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno));
1200 if (pa_lock_fd(fd, 1) < 0) {
1201 pa_log_warn("Failed to lock file '%s'.", fn);
1205 if (fstat(fd, &st) < 0) {
1206 pa_log_warn("Failed to fstat() file '%s': %s", fn, pa_cstrerror(errno));
1210 /* Check wheter the file has been removed meanwhile. When yes,
1211 * restart this loop, otherwise, we're done */
1212 if (st.st_nlink >= 1)
1215 if (pa_lock_fd(fd, 0) < 0) {
1216 pa_log_warn("Failed to unlock file '%s'.", fn);
1220 if (pa_close(fd) < 0) {
1221 pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno));
1234 int saved_errno = errno;
1236 errno = saved_errno;
1242 /* Unlock a temporary lcok file */
1243 int pa_unlock_lockfile(const char *fn, int fd) {
1248 if (unlink(fn) < 0) {
1249 pa_log_warn("Unable to remove lock file '%s': %s", fn, pa_cstrerror(errno));
1254 if (pa_lock_fd(fd, 0) < 0) {
1255 pa_log_warn("Failed to unlock file '%s'.", fn);
1259 if (pa_close(fd) < 0) {
1260 pa_log_warn("Failed to close '%s': %s", fn, pa_cstrerror(errno));
1267 static char *get_pulse_home(void) {
1271 if (!pa_get_home_dir(h, sizeof(h))) {
1272 pa_log_error("Failed to get home directory.");
1276 if (stat(h, &st) < 0) {
1277 pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno));
1281 if (st.st_uid != getuid()) {
1282 pa_log_error("Home directory %s not ours.", h);
1287 return pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
1290 char *pa_get_state_dir(void) {
1293 /* The state directory shall contain dynamic data that should be
1294 * kept across reboots, and is private to this user */
1296 if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1297 if (!(d = get_pulse_home()))
1300 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1301 * dir then this will break. */
1303 if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0) {
1304 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1312 static char* make_random_dir(mode_t m) {
1313 static const char table[] =
1314 "abcdefghijklmnopqrstuvwxyz"
1315 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1322 if (!(tmpdir = getenv("TMPDIR")))
1323 if (!(tmpdir = getenv("TMP")))
1324 if (!(tmpdir = getenv("TEMP")))
1325 tmpdir = getenv("TEMPDIR");
1327 if (!tmpdir || !pa_is_path_absolute(tmpdir))
1330 fn = pa_sprintf_malloc("%s/pulse-XXXXXXXXXXXX", tmpdir);
1331 pathlen = strlen(fn);
1339 for (i = pathlen - 12; i < pathlen; i++)
1340 fn[i] = table[rand() % (sizeof(table)-1)];
1342 u = umask((~m) & 0777);
1345 saved_errno = errno;
1347 errno = saved_errno;
1352 if (errno != EEXIST) {
1353 pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
1360 static int make_random_dir_and_link(mode_t m, const char *k) {
1363 if (!(p = make_random_dir(m)))
1366 if (symlink(p, k) < 0) {
1367 int saved_errno = errno;
1369 if (errno != EEXIST)
1370 pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno));
1375 errno = saved_errno;
1382 char *pa_get_runtime_dir(void) {
1383 char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
1387 /* The runtime directory shall contain dynamic data that needs NOT
1388 * to be kept accross reboots and is usuallly private to the user,
1389 * except in system mode, where it might be accessible by other
1390 * users, too. Since we need POSIX locking and UNIX sockets in
1391 * this directory, we link it to a random subdir in /tmp, if it
1392 * was not explicitly configured. */
1394 m = pa_in_system_mode() ? 0755U : 0700U;
1396 if ((d = getenv("PULSE_RUNTIME_PATH"))) {
1398 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
1399 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1403 return pa_xstrdup(d);
1406 if (!(d = get_pulse_home()))
1409 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
1410 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1414 if (!(mid = pa_machine_id())) {
1419 k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:runtime", d, mid);
1424 /* OK, first let's check if the "runtime" symlink is already
1427 if (!(p = pa_readlink(k))) {
1429 if (errno != ENOENT) {
1430 pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
1434 /* Hmm, so the runtime directory didn't exist yet, so let's
1435 * create one in /tmp and symlink that to it */
1437 if (make_random_dir_and_link(0700, k) < 0) {
1439 /* Mhmm, maybe another process was quicker than us,
1440 * let's check if that was valid */
1441 if (errno == EEXIST)
1450 /* Make sure that this actually makes sense */
1451 if (!pa_is_path_absolute(p)) {
1452 pa_log_error("Path %s in link %s is not absolute.", p, k);
1457 /* Hmm, so this symlink is still around, make sure nobody fools
1460 if (lstat(p, &st) < 0) {
1462 if (errno != ENOENT) {
1463 pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno));
1469 if (S_ISDIR(st.st_mode) &&
1470 (st.st_uid == getuid()) &&
1471 ((st.st_mode & 0777) == 0700)) {
1477 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1483 /* Hmm, so the link points to some nonexisting or invalid
1484 * dir. Let's replace it by a new link. We first create a
1485 * temporary link and then rename that to allow concurrent
1486 * execution of this function. */
1488 t = pa_sprintf_malloc("%s.tmp", k);
1490 if (make_random_dir_and_link(0700, t) < 0) {
1492 if (errno != EEXIST) {
1493 pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno));
1500 /* Hmm, someone lese was quicker then us. Let's give
1501 * him some time to finish, and retry. */
1506 /* OK, we succeeded in creating the temporary symlink, so
1507 * let's rename it */
1508 if (rename(t, k) < 0) {
1509 pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno));
1525 /* Try to open a configuration file. If "env" is specified, open the
1526 * value of the specified environment variable. Otherwise look for a
1527 * file "local" in the home directory or a file "global" in global
1528 * file system. If "result" is non-NULL, a pointer to a newly
1529 * allocated buffer containing the used configuration file is
1531 FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
1536 if (!getenv(PULSE_ROOTENV))
1540 if (env && (fn = getenv(env))) {
1544 if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
1545 /* FIXME: Needs to set errno! */
1550 if ((f = fopen(fn, "r"))) {
1552 *result = pa_xstrdup(fn);
1557 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1567 if ((e = getenv("PULSE_CONFIG_PATH")))
1568 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1569 else if (pa_get_home_dir(h, sizeof(h)))
1570 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1575 if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
1576 /* FIXME: Needs to set errno! */
1583 if ((f = fopen(fn, "r"))) {
1585 *result = pa_xstrdup(fn);
1591 if (errno != ENOENT) {
1592 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1604 if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
1605 /* FIXME: Needs to set errno! */
1610 if ((f = fopen(global, "r"))) {
1613 *result = pa_xstrdup(global);
1623 char *pa_find_config_file(const char *global, const char *local, const char *env) {
1628 if (!getenv(PULSE_ROOTENV))
1632 if (env && (fn = getenv(env))) {
1635 if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
1636 /* FIXME: Needs to set errno! */
1641 if (access(fn, R_OK) == 0)
1642 return pa_xstrdup(fn);
1644 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1653 if ((e = getenv("PULSE_CONFIG_PATH")))
1654 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1655 else if (pa_get_home_dir(h, sizeof(h)))
1656 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1661 if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
1662 /* FIXME: Needs to set errno! */
1669 if (access(fn, R_OK) == 0) {
1670 char *r = pa_xstrdup(fn);
1675 if (errno != ENOENT) {
1676 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1686 if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
1687 /* FIXME: Needs to set errno! */
1692 if (access(global, R_OK) == 0)
1693 return pa_xstrdup(global);
1701 /* Format the specified data as a hexademical string */
1702 char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {
1703 size_t i = 0, j = 0;
1704 const char hex[] = "0123456789abcdef";
1708 pa_assert(slength > 0);
1710 while (i < dlength && j+3 <= slength) {
1711 s[j++] = hex[*d >> 4];
1712 s[j++] = hex[*d & 0xF];
1718 s[j < slength ? j : slength] = 0;
1722 /* Convert a hexadecimal digit to a number or -1 if invalid */
1723 static int hexc(char c) {
1724 if (c >= '0' && c <= '9')
1727 if (c >= 'A' && c <= 'F')
1728 return c - 'A' + 10;
1730 if (c >= 'a' && c <= 'f')
1731 return c - 'a' + 10;
1737 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1738 size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) {
1744 while (j < dlength && *p) {
1747 if ((b = hexc(*(p++))) < 0)
1750 d[j] = (uint8_t) (b << 4);
1755 if ((b = hexc(*(p++))) < 0)
1758 d[j] |= (uint8_t) b;
1765 /* Returns nonzero when *s starts with *pfx */
1766 pa_bool_t pa_startswith(const char *s, const char *pfx) {
1774 return strlen(s) >= l && strncmp(s, pfx, l) == 0;
1777 /* Returns nonzero when *s ends with *sfx */
1778 pa_bool_t pa_endswith(const char *s, const char *sfx) {
1787 return l1 >= l2 && strcmp(s+l1-l2, sfx) == 0;
1790 pa_bool_t pa_is_path_absolute(const char *fn) {
1796 return strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\';
1800 char *pa_make_path_absolute(const char *p) {
1806 if (pa_is_path_absolute(p))
1807 return pa_xstrdup(p);
1809 if (!(cwd = pa_getcwd()))
1810 return pa_xstrdup(p);
1812 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", cwd, p);
1817 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
1818 * if fn is non-null and starts with / return fn
1819 * otherwise append fn to the run time path and return it */
1820 static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {
1823 if (pa_is_path_absolute(fn))
1824 return pa_xstrdup(fn);
1826 rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
1837 if (!(mid = pa_machine_id())) {
1842 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:%s", rtp, mid, fn);
1845 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn);
1853 char *pa_runtime_path(const char *fn) {
1854 return get_path(fn, FALSE, TRUE);
1857 char *pa_state_path(const char *fn, pa_bool_t appendmid) {
1858 return get_path(fn, appendmid, FALSE);
1861 /* Convert the string s to a signed integer in *ret_i */
1862 int pa_atoi(const char *s, int32_t *ret_i) {
1870 l = strtol(s, &x, 0);
1872 if (!x || *x || errno) {
1878 if ((int32_t) l != l) {
1883 *ret_i = (int32_t) l;
1888 /* Convert the string s to an unsigned integer in *ret_u */
1889 int pa_atou(const char *s, uint32_t *ret_u) {
1897 l = strtoul(s, &x, 0);
1899 if (!x || *x || errno) {
1905 if ((uint32_t) l != l) {
1910 *ret_u = (uint32_t) l;
1915 #ifdef HAVE_STRTOF_L
1916 static locale_t c_locale = NULL;
1918 static void c_locale_destroy(void) {
1919 freelocale(c_locale);
1923 int pa_atod(const char *s, double *ret_d) {
1930 /* This should be locale independent */
1932 #ifdef HAVE_STRTOF_L
1936 if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL)))
1937 atexit(c_locale_destroy);
1943 f = strtod_l(s, &x, c_locale);
1951 if (!x || *x || errno) {
1962 /* Same as snprintf, but guarantees NUL-termination on every platform */
1963 size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
1968 pa_assert(size > 0);
1971 va_start(ap, format);
1972 ret = pa_vsnprintf(str, size, format, ap);
1978 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
1979 size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
1983 pa_assert(size > 0);
1986 ret = vsnprintf(str, size, format, ap);
1993 if ((size_t) ret > size-1)
1996 return (size_t) ret;
1999 /* Truncate the specified string, but guarantee that the string
2000 * returned still validates as UTF8 */
2001 char *pa_truncate_utf8(char *c, size_t l) {
2003 pa_assert(pa_utf8_valid(c));
2010 while (l > 0 && !pa_utf8_valid(c))
2016 char *pa_getcwd(void) {
2020 char *p = pa_xmalloc(l);
2024 if (errno != ERANGE)
2032 void *pa_will_need(const void *p, size_t l) {
2033 #ifdef RLIMIT_MEMLOCK
2044 a = PA_PAGE_ALIGN_PTR(p);
2045 size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
2047 #ifdef HAVE_POSIX_MADVISE
2048 if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
2049 pa_log_debug("posix_madvise() worked fine!");
2054 /* Most likely the memory was not mmap()ed from a file and thus
2055 * madvise() didn't work, so let's misuse mlock() do page this
2056 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2057 * inviting, the man page of mlock() tells us: "All pages that
2058 * contain a part of the specified address range are guaranteed to
2059 * be resident in RAM when the call returns successfully." */
2061 #ifdef RLIMIT_MEMLOCK
2062 pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
2064 if (rlim.rlim_cur < PA_PAGE_SIZE) {
2065 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));
2070 bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
2072 bs = PA_PAGE_SIZE*4;
2075 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r));
2078 while (size > 0 && bs > 0) {
2083 if (mlock(a, bs) < 0) {
2084 bs = PA_PAGE_ALIGN(bs / 2);
2088 pa_assert_se(munlock(a, bs) == 0);
2090 a = (const uint8_t*) a + bs;
2096 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno));
2098 pa_log_debug("mlock() worked fine!");
2103 void pa_close_pipe(int fds[2]) {
2107 pa_assert_se(pa_close(fds[0]) == 0);
2110 pa_assert_se(pa_close(fds[1]) == 0);
2112 fds[0] = fds[1] = -1;
2115 char *pa_readlink(const char *p) {
2124 if ((n = readlink(p, c, l-1)) < 0) {
2129 if ((size_t) n < l-1) {
2139 int pa_close_all(int except_fd, ...) {
2144 va_start(ap, except_fd);
2147 for (n = 1; va_arg(ap, int) >= 0; n++)
2152 p = pa_xnew(int, n+1);
2154 va_start(ap, except_fd);
2157 if (except_fd >= 0) {
2161 while ((fd = va_arg(ap, int)) >= 0)
2168 r = pa_close_allv(p);
2174 int pa_close_allv(const int except_fds[]) {
2183 if ((d = opendir("/proc/self/fd"))) {
2187 while ((de = readdir(d))) {
2193 if (de->d_name[0] == '.')
2197 l = strtol(de->d_name, &e, 10);
2198 if (errno != 0 || !e || *e) {
2206 if ((long) fd != l) {
2219 for (i = 0; except_fds[i] >= 0; i++)
2220 if (except_fds[i] == fd) {
2228 if (pa_close(fd) < 0) {
2229 saved_errno = errno;
2231 errno = saved_errno;
2243 if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
2246 for (fd = 3; fd < (int) rl.rlim_max; fd++) {
2251 for (i = 0; except_fds[i] >= 0; i++)
2252 if (except_fds[i] == fd) {
2260 if (pa_close(fd) < 0 && errno != EBADF)
2267 int pa_unblock_sigs(int except, ...) {
2272 va_start(ap, except);
2275 for (n = 1; va_arg(ap, int) >= 0; n++)
2280 p = pa_xnew(int, n+1);
2282 va_start(ap, except);
2289 while ((sig = va_arg(ap, int)) >= 0)
2296 r = pa_unblock_sigsv(p);
2302 int pa_unblock_sigsv(const int except[]) {
2306 if (sigemptyset(&ss) < 0)
2309 for (i = 0; except[i] > 0; i++)
2310 if (sigaddset(&ss, except[i]) < 0)
2313 return sigprocmask(SIG_SETMASK, &ss, NULL);
2316 int pa_reset_sigs(int except, ...) {
2321 va_start(ap, except);
2324 for (n = 1; va_arg(ap, int) >= 0; n++)
2329 p = pa_xnew(int, n+1);
2331 va_start(ap, except);
2338 while ((sig = va_arg(ap, int)) >= 0)
2345 r = pa_reset_sigsv(p);
2351 int pa_reset_sigsv(const int except[]) {
2354 for (sig = 1; sig < NSIG; sig++) {
2355 pa_bool_t reset = TRUE;
2366 for (i = 0; except[i] > 0; i++) {
2367 if (sig == except[i]) {
2376 struct sigaction sa;
2378 memset(&sa, 0, sizeof(sa));
2379 sa.sa_handler = SIG_DFL;
2381 /* On Linux the first two RT signals are reserved by
2382 * glibc, and sigaction() will return EINVAL for them. */
2383 if ((sigaction(sig, &sa, NULL) < 0))
2384 if (errno != EINVAL)
2392 void pa_set_env(const char *key, const char *value) {
2396 putenv(pa_sprintf_malloc("%s=%s", key, value));
2399 pa_bool_t pa_in_system_mode(void) {
2402 if (!(e = getenv("PULSE_SYSTEM")))
2408 char *pa_machine_id(void) {
2412 /* The returned value is supposed be some kind of ascii identifier
2413 * that is unique and stable across reboots. */
2415 /* First we try the D-Bus UUID, which is the best option we have,
2416 * since it fits perfectly our needs and is not as volatile as the
2417 * hostname which might be set from dhcp. */
2419 if ((f = fopen(PA_MACHINE_ID, "r"))) {
2420 char ln[34] = "", *r;
2422 r = fgets(ln, sizeof(ln)-1, f);
2428 return pa_xstrdup(ln);
2431 /* The we fall back to the host name. It supposed to be somewhat
2432 * unique, at least in a network, but may change. */
2440 if (!pa_get_host_name(c, l)) {
2442 if (errno != EINVAL && errno != ENAMETOOLONG)
2445 } else if (strlen(c) < l-1) {
2455 /* Hmm, the hostname is as long the space we offered the
2456 * function, we cannot know if it fully fit in, so let's play
2457 * safe and retry. */
2463 /* If no hostname was set we use the POSIX hostid. It's usually
2464 * the IPv4 address. Mit not be that stable. */
2465 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
2468 char *pa_uname_string(void) {
2471 pa_assert_se(uname(&u) == 0);
2473 return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);