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, see <http://www.gnu.org/licenses/>.
37 #include <sys/types.h>
41 #ifdef HAVE_LANGINFO_H
46 #include <sys/utsname.h>
49 #if defined(HAVE_REGEX_H)
51 #elif defined(HAVE_PCREPOSIX_H)
52 #include <pcreposix.h>
64 #ifdef HAVE_SYS_RESOURCE_H
65 #include <sys/resource.h>
68 #ifdef HAVE_SYS_CAPABILITY_H
69 #include <sys/capability.h>
72 #ifdef HAVE_SYS_MMAN_H
100 #ifdef HAVE_LIBSAMPLERATE
101 #include <samplerate.h>
105 #include <pulsecore/rtkit.h>
108 #if defined(__linux__) && !defined(__ANDROID__)
109 #include <sys/personality.h>
116 #include <pulse/xmalloc.h>
117 #include <pulse/util.h>
118 #include <pulse/utf8.h>
120 #include <pulsecore/core-error.h>
121 #include <pulsecore/socket.h>
122 #include <pulsecore/log.h>
123 #include <pulsecore/macro.h>
124 #include <pulsecore/thread.h>
125 #include <pulsecore/strbuf.h>
126 #include <pulsecore/usergroup.h>
127 #include <pulsecore/strlist.h>
128 #include <pulsecore/pipe.h>
129 #include <pulsecore/once.h>
131 #include "core-util.h"
133 /* Not all platforms have this */
135 #define MSG_NOSIGNAL 0
138 #define NEWLINE "\r\n"
139 #define WHITESPACE "\n\r \t"
141 static pa_strlist *recorded_env = NULL;
144 static fd_set nonblocking_fds;
149 /* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
150 char *pa_win32_get_toplevel(HANDLE handle) {
151 static char *toplevel = NULL;
154 char library_path[MAX_PATH];
157 if (!GetModuleFileName(handle, library_path, MAX_PATH))
160 toplevel = pa_xstrdup(library_path);
162 p = strrchr(toplevel, PA_PATH_SEP_CHAR);
166 p = strrchr(toplevel, PA_PATH_SEP_CHAR);
167 if (p && pa_streq(p + 1, "bin"))
176 static void set_nonblock(int fd, bool nonblock) {
182 pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
187 nv = v & ~O_NONBLOCK;
190 pa_assert_se(fcntl(fd, F_SETFL, nv) >= 0);
192 #elif defined(OS_IS_WIN32)
200 if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
201 pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
202 pa_log_warn("Only sockets can be made non-blocking!");
206 /* There is no method to query status, so we remember all fds */
208 FD_SET(fd, &nonblocking_fds);
210 FD_CLR(fd, &nonblocking_fds);
212 pa_log_warn("Non-blocking I/O not supported.!");
217 /** Make a file descriptor nonblock. Doesn't do any error checking */
218 void pa_make_fd_nonblock(int fd) {
219 set_nonblock(fd, true);
222 /** Make a file descriptor blocking. Doesn't do any error checking */
223 void pa_make_fd_block(int fd) {
224 set_nonblock(fd, false);
227 /** Query if a file descriptor is non-blocking */
228 bool pa_is_fd_nonblock(int fd) {
234 pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
236 return !!(v & O_NONBLOCK);
238 #elif defined(OS_IS_WIN32)
239 return !!FD_ISSET(fd, &nonblocking_fds);
246 /* Set the FD_CLOEXEC flag for a fd */
247 void pa_make_fd_cloexec(int fd) {
253 pa_assert_se((v = fcntl(fd, F_GETFD, 0)) >= 0);
255 if (!(v & FD_CLOEXEC))
256 pa_assert_se(fcntl(fd, F_SETFD, v|FD_CLOEXEC) >= 0);
261 /** Creates a directory securely. Will create parent directories recursively if
262 * required. This will not update permissions on parent directories if they
263 * already exist, however. */
264 int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid, bool update_perms) {
277 u = umask((~m) & 0777);
283 if (r < 0 && errno == ENOENT && retry) {
284 /* If a parent directory in the path doesn't exist, try to create that
285 * first, then try again. */
286 pa_make_secure_parent_dir(dir, m, uid, gid, false);
291 if (r < 0 && errno != EEXIST)
294 #if defined(HAVE_FSTAT) && !defined(OS_IS_WIN32)
310 if (fstat(fd, &st) < 0) {
311 pa_assert_se(pa_close(fd) >= 0);
315 if (!S_ISDIR(st.st_mode)) {
316 pa_assert_se(pa_close(fd) >= 0);
322 pa_assert_se(pa_close(fd) >= 0);
327 if (uid == (uid_t) -1)
329 if (gid == (gid_t) -1)
331 if (((st.st_uid != uid) || (st.st_gid != gid)) && fchown(fd, uid, gid) < 0) {
332 pa_assert_se(pa_close(fd) >= 0);
338 if ((st.st_mode & 07777) != m && fchmod(fd, m) < 0) {
339 pa_assert_se(pa_close(fd) >= 0);
344 pa_assert_se(pa_close(fd) >= 0);
347 pa_log_warn("Secure directory creation not supported on this platform.");
360 /* Return a newly allocated sting containing the parent directory of the specified file */
361 char *pa_parent_dir(const char *fn) {
362 char *slash, *dir = pa_xstrdup(fn);
364 if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
374 /* Creates a the parent directory of the specified path securely */
375 int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid, bool update_perms) {
379 if (!(dir = pa_parent_dir(fn)))
382 if (pa_make_secure_dir(dir, m, uid, gid, update_perms) < 0)
392 /** Platform independent read function. Necessary since not all
393 * systems treat all file descriptors equal. If type is
394 * non-NULL it is used to cache the type of the fd. This is
395 * useful for making sure that only a single syscall is executed per
396 * function call. The variable pointed to should be initialized to 0
398 ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
402 if (!type || *type == 0) {
405 if ((r = recv(fd, buf, count, 0)) >= 0)
408 if (WSAGetLastError() != WSAENOTSOCK) {
409 errno = WSAGetLastError();
422 if ((r = read(fd, buf, count)) < 0)
430 /** Similar to pa_read(), but handles writes */
431 ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
433 if (!type || *type == 0) {
437 if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) {
449 if (WSAGetLastError() != WSAENOTSOCK) {
450 errno = WSAGetLastError();
454 if (errno != ENOTSOCK)
465 if ((r = write(fd, buf, count)) < 0)
473 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
474 * unless EOF is reached or an error occurred */
475 ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
491 if ((r = pa_read(fd, data, size, type)) < 0)
498 data = (uint8_t*) data + r;
505 /** Similar to pa_loop_read(), but wraps write() */
506 ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
522 if ((r = pa_write(fd, data, size, type)) < 0)
529 data = (const uint8_t*) data + r;
536 /** Platform independent close function. Necessary since not all
537 * systems treat all file descriptors equal. */
538 int pa_close(int fd) {
543 FD_CLR(fd, &nonblocking_fds);
545 if ((ret = closesocket(fd)) == 0)
548 if (WSAGetLastError() != WSAENOTSOCK) {
549 errno = WSAGetLastError();
557 if ((r = close(fd)) < 0)
565 /* Print a warning messages in case that the given signal is not
566 * blocked or trapped */
567 void pa_check_signal_is_blocked(int sig) {
568 #ifdef HAVE_SIGACTION
572 /* If POSIX threads are supported use thread-aware
573 * pthread_sigmask() function, to check if the signal is
574 * blocked. Otherwise fall back to sigprocmask() */
577 if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) {
579 if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) {
580 pa_log("sigprocmask(): %s", pa_cstrerror(errno));
587 if (sigismember(&set, sig))
590 /* Check whether the signal is trapped */
592 if (sigaction(sig, NULL, &sa) < 0) {
593 pa_log("sigaction(): %s", pa_cstrerror(errno));
597 if (sa.sa_handler != SIG_DFL)
600 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig));
601 #else /* HAVE_SIGACTION */
602 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig));
606 /* The following function is based on an example from the GNU libc
607 * documentation. This function is similar to GNU's asprintf(). */
608 char *pa_sprintf_malloc(const char *format, ...) {
618 c = pa_xrealloc(c, size);
620 va_start(ap, format);
621 r = vsnprintf(c, size, format, ap);
626 if (r > -1 && (size_t) r < size)
629 if (r > -1) /* glibc 2.1 */
636 /* Same as the previous function, but use a va_list instead of an
638 char *pa_vsprintf_malloc(const char *format, va_list ap) {
648 c = pa_xrealloc(c, size);
651 r = vsnprintf(c, size, format, aq);
656 if (r > -1 && (size_t) r < size)
659 if (r > -1) /* glibc 2.1 */
666 /* Similar to OpenBSD's strlcpy() function */
667 char *pa_strlcpy(char *b, const char *s, size_t l) {
685 #ifdef HAVE_SYS_RESOURCE_H
686 static int set_nice(int nice_level) {
692 dbus_error_init(&error);
695 #ifdef HAVE_SYS_RESOURCE_H
696 if (setpriority(PRIO_PROCESS, 0, nice_level) >= 0) {
697 pa_log_debug("setpriority() worked.");
703 /* Try to talk to RealtimeKit */
705 if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
706 pa_log("Failed to connect to system bus: %s", error.message);
707 dbus_error_free(&error);
712 /* We need to disable exit on disconnect because otherwise
713 * dbus_shutdown will kill us. See
714 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
715 dbus_connection_set_exit_on_disconnect(bus, FALSE);
717 r = rtkit_make_high_priority(bus, 0, nice_level);
718 dbus_connection_close(bus);
719 dbus_connection_unref(bus);
722 pa_log_debug("RealtimeKit worked.");
733 /* Raise the priority of the current process as much as possible that
734 * is <= the specified nice level..*/
735 int pa_raise_priority(int nice_level) {
737 #ifdef HAVE_SYS_RESOURCE_H
740 if (set_nice(nice_level) >= 0) {
741 pa_log_info("Successfully gained nice level %i.", nice_level);
745 for (n = nice_level+1; n < 0; n++)
746 if (set_nice(n) >= 0) {
747 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
751 pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno));
756 if (nice_level < 0) {
757 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
758 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
763 pa_log_info("Successfully gained high priority class.");
770 /* Reset the priority to normal, inverting the changes made by
771 * pa_raise_priority() and pa_thread_make_realtime()*/
772 void pa_reset_priority(void) {
773 #ifdef HAVE_SYS_RESOURCE_H
774 struct sched_param sp;
776 setpriority(PRIO_PROCESS, 0, 0);
779 pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp);
783 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
787 int pa_match(const char *expr, const char *v) {
788 #if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
793 if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
798 if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
800 else if (k == REG_NOMATCH)
817 /* Try to parse a boolean string value.*/
818 int pa_parse_boolean(const char *v) {
821 /* First we check language independent */
822 if (pa_streq(v, "1") || !strcasecmp(v, "y") || !strcasecmp(v, "t")
823 || !strcasecmp(v, "yes") || !strcasecmp(v, "true") || !strcasecmp(v, "on"))
825 else if (pa_streq(v, "0") || !strcasecmp(v, "n") || !strcasecmp(v, "f")
826 || !strcasecmp(v, "no") || !strcasecmp(v, "false") || !strcasecmp(v, "off"))
829 #ifdef HAVE_LANGINFO_H
832 /* And then we check language dependent */
833 if ((expr = nl_langinfo(YESEXPR)))
835 if (pa_match(expr, v) > 0)
838 if ((expr = nl_langinfo(NOEXPR)))
840 if (pa_match(expr, v) > 0)
849 /* Try to parse a volume string to pa_volume_t. The allowed formats are:
850 * db, % and unsigned integer */
851 int pa_parse_volume(const char *v, pa_volume_t *volume) {
865 memcpy(str, v, len + 1);
867 if (str[len - 1] == '%') {
869 if (pa_atod(str, &d) < 0)
872 d = d / 100 * PA_VOLUME_NORM;
874 if (d < 0 || d > PA_VOLUME_MAX)
881 if (len > 2 && (str[len - 1] == 'b' || str[len - 1] == 'B') &&
882 (str[len - 2] == 'd' || str[len - 2] == 'D')) {
884 if (pa_atod(str, &d) < 0)
887 if (d > pa_sw_volume_to_dB(PA_VOLUME_MAX))
890 *volume = pa_sw_volume_from_dB(d);
894 if (pa_atou(v, &i) < 0 || !PA_VOLUME_IS_VALID(i))
901 /* Split the specified string wherever one of the characters in delimiter
902 * occurs. Each time it is called returns a newly allocated string
903 * with pa_xmalloc(). The variable state points to, should be
904 * initialized to NULL before the first call. */
905 char *pa_split(const char *c, const char *delimiter, const char**state) {
906 const char *current = *state ? *state : c;
912 l = strcspn(current, delimiter);
918 return pa_xstrndup(current, l);
921 /* Split the specified string wherever one of the characters in delimiter
922 * occurs. Each time it is called returns a pointer to the substring within the
923 * string and the length in 'n'. Note that the resultant string cannot be used
924 * as-is without the length parameter, since it is merely pointing to a point
925 * within the original string. The variable state points to, should be
926 * initialized to NULL before the first call. */
927 const char *pa_split_in_place(const char *c, const char *delimiter, size_t *n, const char**state) {
928 const char *current = *state ? *state : c;
934 l = strcspn(current, delimiter);
944 /* Split a string into words. Otherwise similar to pa_split(). */
945 char *pa_split_spaces(const char *c, const char **state) {
946 const char *current = *state ? *state : c;
949 if (!*current || *c == 0)
952 current += strspn(current, WHITESPACE);
953 l = strcspn(current, WHITESPACE);
957 return pa_xstrndup(current, l);
960 /* Similar to pa_split_spaces, except this returns a string in-place.
961 Returned string is generally not NULL-terminated.
962 See pa_split_in_place(). */
963 const char *pa_split_spaces_in_place(const char *c, size_t *n, const char **state) {
964 const char *current = *state ? *state : c;
967 if (!*current || *c == 0)
970 current += strspn(current, WHITESPACE);
971 l = strcspn(current, WHITESPACE);
979 PA_STATIC_TLS_DECLARE(signame, pa_xfree);
981 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
982 const char *pa_sig2str(int sig) {
995 char buf[SIG2STR_MAX];
997 if (sig2str(sig, buf) == 0) {
998 pa_xfree(PA_STATIC_TLS_GET(signame));
999 t = pa_sprintf_malloc("SIG%s", buf);
1000 PA_STATIC_TLS_SET(signame, t);
1008 case SIGHUP: return "SIGHUP";
1010 case SIGINT: return "SIGINT";
1012 case SIGQUIT: return "SIGQUIT";
1014 case SIGILL: return "SIGULL";
1016 case SIGTRAP: return "SIGTRAP";
1018 case SIGABRT: return "SIGABRT";
1020 case SIGBUS: return "SIGBUS";
1022 case SIGFPE: return "SIGFPE";
1024 case SIGKILL: return "SIGKILL";
1027 case SIGUSR1: return "SIGUSR1";
1029 case SIGSEGV: return "SIGSEGV";
1031 case SIGUSR2: return "SIGUSR2";
1034 case SIGPIPE: return "SIGPIPE";
1037 case SIGALRM: return "SIGALRM";
1039 case SIGTERM: return "SIGTERM";
1041 case SIGSTKFLT: return "SIGSTKFLT";
1044 case SIGCHLD: return "SIGCHLD";
1047 case SIGCONT: return "SIGCONT";
1050 case SIGSTOP: return "SIGSTOP";
1053 case SIGTSTP: return "SIGTSTP";
1056 case SIGTTIN: return "SIGTTIN";
1059 case SIGTTOU: return "SIGTTOU";
1062 case SIGURG: return "SIGURG";
1065 case SIGXCPU: return "SIGXCPU";
1068 case SIGXFSZ: return "SIGXFSZ";
1071 case SIGVTALRM: return "SIGVTALRM";
1074 case SIGPROF: return "SIGPROF";
1077 case SIGWINCH: return "SIGWINCH";
1080 case SIGIO: return "SIGIO";
1083 case SIGPWR: return "SIGPWR";
1086 case SIGSYS: return "SIGSYS";
1091 if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
1092 pa_xfree(PA_STATIC_TLS_GET(signame));
1093 t = pa_sprintf_malloc("SIGRTMIN+%i", sig - SIGRTMIN);
1094 PA_STATIC_TLS_SET(signame, t);
1103 pa_xfree(PA_STATIC_TLS_GET(signame));
1104 t = pa_sprintf_malloc("SIG%i", sig);
1105 PA_STATIC_TLS_SET(signame, t);
1111 /* Check whether the specified GID and the group name match */
1112 static int is_group(gid_t gid, const char *name) {
1113 struct group *group = NULL;
1117 if (!(group = pa_getgrgid_malloc(gid))) {
1121 pa_log("pa_getgrgid_malloc(%u): %s", gid, pa_cstrerror(errno));
1126 r = pa_streq(name, group->gr_name);
1129 pa_getgrgid_free(group);
1134 /* Check the current user is member of the specified group */
1135 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1136 GETGROUPS_T *gids, tgid;
1137 long n = sysconf(_SC_NGROUPS_MAX);
1142 gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
1144 if ((n = getgroups((int) n, gids)) < 0) {
1145 pa_log("getgroups(): %s", pa_cstrerror(errno));
1149 for (i = 0; i < n; i++) {
1151 if ((k = is_group(gids[i], name)) < 0)
1160 if ((k = is_group(tgid = getgid(), name)) < 0)
1176 /* Check whether the specific user id is a member of the specified group */
1177 int pa_uid_in_group(uid_t uid, const char *name) {
1178 struct group *group = NULL;
1183 if (!(group = pa_getgrnam_malloc(name))) {
1190 for (i = group->gr_mem; *i; i++) {
1191 struct passwd *pw = NULL;
1194 if (!(pw = pa_getpwnam_malloc(*i)))
1197 if (pw->pw_uid == uid)
1200 pa_getpwnam_free(pw);
1207 pa_getgrnam_free(group);
1212 /* Get the GID of a given group, return (gid_t) -1 on failure. */
1213 gid_t pa_get_gid_of_group(const char *name) {
1214 gid_t ret = (gid_t) -1;
1215 struct group *gr = NULL;
1218 if (!(gr = pa_getgrnam_malloc(name))) {
1227 pa_getgrnam_free(gr);
1231 int pa_check_in_group(gid_t g) {
1232 gid_t gids[NGROUPS_MAX];
1235 if ((r = getgroups(NGROUPS_MAX, gids)) < 0)
1245 #else /* HAVE_GRP_H */
1247 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1253 int pa_uid_in_group(uid_t uid, const char *name) {
1258 gid_t pa_get_gid_of_group(const char *name) {
1263 int pa_check_in_group(gid_t g) {
1270 /* Lock or unlock a file entirely.
1271 (advisory on UNIX, mandatory on Windows) */
1272 int pa_lock_fd(int fd, int b) {
1274 struct flock f_lock;
1276 /* Try a R/W lock first */
1278 f_lock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
1279 f_lock.l_whence = SEEK_SET;
1283 if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
1286 /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
1287 if (b && errno == EBADF) {
1288 f_lock.l_type = F_RDLCK;
1289 if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
1293 pa_log("%slock: %s", !b ? "un" : "", pa_cstrerror(errno));
1297 HANDLE h = (HANDLE) _get_osfhandle(fd);
1299 if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1301 if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1304 pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError());
1306 /* FIXME: Needs to set errno! */
1312 /* Remove trailing newlines from a string */
1313 char* pa_strip_nl(char *s) {
1316 s[strcspn(s, NEWLINE)] = 0;
1320 char *pa_strip(char *s) {
1323 /* Drops trailing whitespace. Modifies the string in
1324 * place. Returns pointer to first non-space character */
1326 s += strspn(s, WHITESPACE);
1328 for (e = s; *e; e++)
1329 if (!strchr(WHITESPACE, *e))
1340 /* Create a temporary lock file and lock it. */
1341 int pa_lock_lockfile(const char *fn) {
1348 if ((fd = pa_open_cloexec(fn, O_CREAT|O_RDWR
1352 , S_IRUSR|S_IWUSR)) < 0) {
1353 pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno));
1357 if (pa_lock_fd(fd, 1) < 0) {
1358 pa_log_warn("Failed to lock file '%s'.", fn);
1362 if (fstat(fd, &st) < 0) {
1363 pa_log_warn("Failed to fstat() file '%s': %s", fn, pa_cstrerror(errno));
1367 /* Check whether the file has been removed meanwhile. When yes,
1368 * restart this loop, otherwise, we're done */
1369 if (st.st_nlink >= 1)
1372 if (pa_lock_fd(fd, 0) < 0) {
1373 pa_log_warn("Failed to unlock file '%s'.", fn);
1377 if (pa_close(fd) < 0) {
1378 pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno));
1389 int saved_errno = errno;
1391 errno = saved_errno;
1397 /* Unlock a temporary lock file */
1398 int pa_unlock_lockfile(const char *fn, int fd) {
1403 if (unlink(fn) < 0) {
1404 pa_log_warn("Unable to remove lock file '%s': %s", fn, pa_cstrerror(errno));
1409 if (pa_lock_fd(fd, 0) < 0) {
1410 pa_log_warn("Failed to unlock file '%s'.", fn);
1414 if (pa_close(fd) < 0) {
1415 pa_log_warn("Failed to close '%s': %s", fn, pa_cstrerror(errno));
1422 static int check_ours(const char *p) {
1427 if (stat(p, &st) < 0)
1431 if (st.st_uid != getuid())
1438 static char *get_pulse_home(void) {
1442 h = pa_get_home_dir_malloc();
1444 pa_log_error("Failed to get home directory.");
1449 if (t < 0 && t != -ENOENT) {
1450 pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t));
1455 /* If the old directory exists, use it. */
1456 ret = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
1458 if (access(ret, F_OK) >= 0)
1462 /* Otherwise go for the XDG compliant directory. */
1463 if (pa_get_config_home_dir(&ret) < 0)
1469 char *pa_get_state_dir(void) {
1472 /* The state directory shall contain dynamic data that should be
1473 * kept across reboots, and is private to this user */
1475 if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1476 if (!(d = get_pulse_home()))
1479 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1480 * dir then this will break. */
1482 if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1, true) < 0) {
1483 pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
1491 char *pa_get_home_dir_malloc(void) {
1493 size_t allocated = 128;
1496 homedir = pa_xmalloc(allocated);
1498 if (!pa_get_home_dir(homedir, allocated)) {
1503 if (strlen(homedir) < allocated - 1)
1513 int pa_append_to_home_dir(const char *path, char **_r) {
1519 home_dir = pa_get_home_dir_malloc();
1521 pa_log("Failed to get home directory.");
1522 return -PA_ERR_NOENTITY;
1525 *_r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", home_dir, path);
1530 int pa_get_config_home_dir(char **_r) {
1536 e = getenv("XDG_CONFIG_HOME");
1538 *_r = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", e);
1542 home_dir = pa_get_home_dir_malloc();
1544 return -PA_ERR_NOENTITY;
1546 *_r = pa_sprintf_malloc("%s" PA_PATH_SEP ".config" PA_PATH_SEP "pulse", home_dir);
1551 int pa_append_to_config_home_dir(const char *path, char **_r) {
1553 char *config_home_dir;
1558 r = pa_get_config_home_dir(&config_home_dir);
1562 *_r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", config_home_dir, path);
1563 pa_xfree(config_home_dir);
1567 char *pa_get_binary_name_malloc(void) {
1569 size_t allocated = 128;
1572 t = pa_xmalloc(allocated);
1574 if (!pa_get_binary_name(t, allocated)) {
1580 if (strnlen(t, allocated - 1) < allocated - 1)
1582 if (strlen(t) < allocated - 1)
1593 static char* make_random_dir(mode_t m) {
1594 static const char table[] =
1595 "abcdefghijklmnopqrstuvwxyz"
1596 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1602 fn = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1603 pathlen = strlen(fn);
1611 for (i = pathlen - 12; i < pathlen; i++)
1612 fn[i] = table[rand() % (sizeof(table)-1)];
1614 u = umask((~m) & 0777);
1621 saved_errno = errno;
1623 errno = saved_errno;
1628 if (errno != EEXIST) {
1629 pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
1636 static int make_random_dir_and_link(mode_t m, const char *k) {
1639 if (!(p = make_random_dir(m)))
1643 if (symlink(p, k) < 0) {
1644 int saved_errno = errno;
1646 if (errno != EEXIST)
1647 pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno));
1652 errno = saved_errno;
1664 char *pa_get_runtime_dir(void) {
1665 char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
1668 /* The runtime directory shall contain dynamic data that needs NOT
1669 * to be kept across reboots and is usually private to the user,
1670 * except in system mode, where it might be accessible by other
1671 * users, too. Since we need POSIX locking and UNIX sockets in
1672 * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
1673 * set create a directory in $HOME and link it to a random subdir
1674 * in /tmp, if it was not explicitly configured. */
1676 m = pa_in_system_mode() ? 0755U : 0700U;
1678 /* Use the explicitly configured value if it is set */
1679 d = getenv("PULSE_RUNTIME_PATH");
1682 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1, true) < 0) {
1683 pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
1687 return pa_xstrdup(d);
1690 /* Use the XDG standard for the runtime directory. */
1691 d = getenv("XDG_RUNTIME_DIR");
1695 if (stat(d, &st) == 0 && st.st_uid != getuid()) {
1696 pa_log(_("XDG_RUNTIME_DIR (%s) is not owned by us (uid %d), but by uid %d! "
1697 "(This could e.g. happen if you try to connect to a non-root PulseAudio as a root user, over the native protocol. Don't do that.)"),
1698 d, getuid(), st.st_uid);
1703 k = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", d);
1705 if (pa_make_secure_dir(k, m, (uid_t) -1, (gid_t) -1, true) < 0) {
1706 pa_log_error("Failed to create secure directory (%s): %s", k, pa_cstrerror(errno));
1713 /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
1714 d = get_pulse_home();
1718 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1, true) < 0) {
1719 pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
1724 mid = pa_machine_id();
1730 k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-runtime", d, mid);
1735 /* OK, first let's check if the "runtime" symlink already exists */
1740 if (errno != ENOENT) {
1741 pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
1746 /* Hmm, so the runtime directory didn't exist yet, so let's
1747 * create one in /tmp and symlink that to it */
1749 if (make_random_dir_and_link(0700, k) < 0) {
1751 /* Mhmm, maybe another process was quicker than us,
1752 * let's check if that was valid */
1753 if (errno == EEXIST)
1759 /* No symlink possible, so let's just create the runtime directly
1760 * Do not check again if it exists since it cannot be a symlink */
1761 if (mkdir(k) < 0 && errno != EEXIST)
1768 /* Make sure that this actually makes sense */
1769 if (!pa_is_path_absolute(p)) {
1770 pa_log_error("Path %s in link %s is not absolute.", p, k);
1775 /* Hmm, so this symlink is still around, make sure nobody fools us */
1779 if (lstat(p, &st) < 0) {
1781 if (errno != ENOENT) {
1782 pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno));
1788 if (S_ISDIR(st.st_mode) &&
1789 (st.st_uid == getuid()) &&
1790 ((st.st_mode & 0777) == 0700)) {
1796 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1804 /* Hmm, so the link points to some nonexisting or invalid
1805 * dir. Let's replace it by a new link. We first create a
1806 * temporary link and then rename that to allow concurrent
1807 * execution of this function. */
1809 t = pa_sprintf_malloc("%s.tmp", k);
1811 if (make_random_dir_and_link(0700, t) < 0) {
1813 if (errno != EEXIST) {
1814 pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno));
1821 /* Hmm, someone else was quicker then us. Let's give
1822 * him some time to finish, and retry. */
1827 /* OK, we succeeded in creating the temporary symlink, so
1828 * let's rename it */
1829 if (rename(t, k) < 0) {
1830 pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno));
1846 /* Try to open a configuration file. If "env" is specified, open the
1847 * value of the specified environment variable. Otherwise look for a
1848 * file "local" in the home directory or a file "global" in global
1849 * file system. If "result" is non-NULL, a pointer to a newly
1850 * allocated buffer containing the used configuration file is
1852 FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
1856 if (env && (fn = getenv(env))) {
1857 if ((f = pa_fopen_cloexec(fn, "r"))) {
1859 *result = pa_xstrdup(fn);
1864 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1873 if ((e = getenv("PULSE_CONFIG_PATH"))) {
1874 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1875 f = pa_fopen_cloexec(fn, "r");
1876 } else if ((h = pa_get_home_dir_malloc())) {
1877 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1878 f = pa_fopen_cloexec(fn, "r");
1881 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".config/pulse" PA_PATH_SEP "%s", h, local);
1882 f = pa_fopen_cloexec(fn, "r");
1890 *result = pa_xstrdup(fn);
1896 if (errno != ENOENT) {
1897 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1909 if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
1910 gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
1911 pa_win32_get_toplevel(NULL),
1912 global + strlen(PA_DEFAULT_CONFIG_DIR));
1915 gfn = pa_xstrdup(global);
1917 if ((f = pa_fopen_cloexec(gfn, "r"))) {
1932 char *pa_find_config_file(const char *global, const char *local, const char *env) {
1935 if (env && (fn = getenv(env))) {
1936 if (access(fn, R_OK) == 0)
1937 return pa_xstrdup(fn);
1939 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1948 if ((e = getenv("PULSE_CONFIG_PATH")))
1949 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1950 else if ((h = pa_get_home_dir_malloc())) {
1951 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1956 if (access(fn, R_OK) == 0) {
1957 char *r = pa_xstrdup(fn);
1962 if (errno != ENOENT) {
1963 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1975 if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
1976 gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
1977 pa_win32_get_toplevel(NULL),
1978 global + strlen(PA_DEFAULT_CONFIG_DIR));
1981 gfn = pa_xstrdup(global);
1983 if (access(gfn, R_OK) == 0)
1993 /* Format the specified data as a hexademical string */
1994 char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {
1995 size_t i = 0, j = 0;
1996 const char hex[] = "0123456789abcdef";
2000 pa_assert(slength > 0);
2002 while (j+2 < slength && i < dlength) {
2003 s[j++] = hex[*d >> 4];
2004 s[j++] = hex[*d & 0xF];
2010 s[j < slength ? j : slength] = 0;
2014 /* Convert a hexadecimal digit to a number or -1 if invalid */
2015 static int hexc(char c) {
2016 if (c >= '0' && c <= '9')
2019 if (c >= 'A' && c <= 'F')
2020 return c - 'A' + 10;
2022 if (c >= 'a' && c <= 'f')
2023 return c - 'a' + 10;
2029 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
2030 size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) {
2036 while (j < dlength && *p) {
2039 if ((b = hexc(*(p++))) < 0)
2042 d[j] = (uint8_t) (b << 4);
2047 if ((b = hexc(*(p++))) < 0)
2050 d[j] |= (uint8_t) b;
2057 /* Returns nonzero when *s starts with *pfx */
2058 bool pa_startswith(const char *s, const char *pfx) {
2066 return strlen(s) >= l && strncmp(s, pfx, l) == 0;
2069 /* Returns nonzero when *s ends with *sfx */
2070 bool pa_endswith(const char *s, const char *sfx) {
2079 return l1 >= l2 && pa_streq(s + l1 - l2, sfx);
2082 bool pa_is_path_absolute(const char *fn) {
2088 return strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\';
2092 char *pa_make_path_absolute(const char *p) {
2098 if (pa_is_path_absolute(p))
2099 return pa_xstrdup(p);
2101 if (!(cwd = pa_getcwd()))
2102 return pa_xstrdup(p);
2104 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", cwd, p);
2109 /* If fn is NULL, return the PulseAudio runtime or state dir (depending on the
2110 * rt parameter). If fn is non-NULL and starts with /, return fn. Otherwise,
2111 * append fn to the runtime/state dir and return it. */
2112 static char *get_path(const char *fn, bool prependmid, bool rt) {
2115 rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
2118 char *r, *canonical_rtp;
2120 if (pa_is_path_absolute(fn)) {
2122 return pa_xstrdup(fn);
2128 /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
2129 if ((canonical_rtp = pa_realpath(rtp))) {
2130 if (strlen(rtp) >= strlen(canonical_rtp))
2133 pa_xfree(canonical_rtp);
2134 canonical_rtp = rtp;
2137 canonical_rtp = rtp;
2142 if (!(mid = pa_machine_id())) {
2143 pa_xfree(canonical_rtp);
2147 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-%s", canonical_rtp, mid, fn);
2150 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", canonical_rtp, fn);
2152 pa_xfree(canonical_rtp);
2158 char *pa_runtime_path(const char *fn) {
2159 return get_path(fn, false, true);
2162 char *pa_state_path(const char *fn, bool appendmid) {
2163 return get_path(fn, appendmid, false);
2166 /* Convert the string s to a signed integer in *ret_i */
2167 int pa_atoi(const char *s, int32_t *ret_i) {
2173 if (pa_atol(s, &l) < 0)
2176 if ((int32_t) l != l) {
2181 *ret_i = (int32_t) l;
2186 /* Convert the string s to an unsigned integer in *ret_u */
2187 int pa_atou(const char *s, uint32_t *ret_u) {
2194 /* strtoul() ignores leading spaces. We don't. */
2195 if (isspace((unsigned char)*s)) {
2200 /* strtoul() accepts strings that start with a minus sign. In that case the
2201 * original negative number gets negated, and strtoul() returns the negated
2202 * result. We don't want that kind of behaviour. strtoul() also allows a
2203 * leading plus sign, which is also a thing that we don't want. */
2204 if (*s == '-' || *s == '+') {
2210 l = strtoul(s, &x, 0);
2212 /* If x doesn't point to the end of s, there was some trailing garbage in
2213 * the string. If x points to s, no conversion was done (empty string). */
2214 if (!x || *x || x == s || errno) {
2220 if ((uint32_t) l != l) {
2225 *ret_u = (uint32_t) l;
2230 /* Convert the string s to a signed long integer in *ret_l. */
2231 int pa_atol(const char *s, long *ret_l) {
2238 /* strtol() ignores leading spaces. We don't. */
2239 if (isspace((unsigned char)*s)) {
2244 /* strtol() accepts leading plus signs, but that's ugly, so we don't allow
2252 l = strtol(s, &x, 0);
2254 /* If x doesn't point to the end of s, there was some trailing garbage in
2255 * the string. If x points to s, no conversion was done (at least an empty
2256 * string can trigger this). */
2257 if (!x || *x || x == s || errno) {
2268 #ifdef HAVE_STRTOD_L
2269 static locale_t c_locale = NULL;
2271 static void c_locale_destroy(void) {
2272 freelocale(c_locale);
2276 int pa_atod(const char *s, double *ret_d) {
2283 /* strtod() ignores leading spaces. We don't. */
2284 if (isspace((unsigned char)*s)) {
2289 /* strtod() accepts leading plus signs, but that's ugly, so we don't allow
2296 /* This should be locale independent */
2298 #ifdef HAVE_STRTOD_L
2302 if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL)))
2303 atexit(c_locale_destroy);
2309 f = strtod_l(s, &x, c_locale);
2317 /* If x doesn't point to the end of s, there was some trailing garbage in
2318 * the string. If x points to s, no conversion was done (at least an empty
2319 * string can trigger this). */
2320 if (!x || *x || x == s || errno) {
2336 /* Same as snprintf, but guarantees NUL-termination on every platform */
2337 size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
2342 pa_assert(size > 0);
2345 va_start(ap, format);
2346 ret = pa_vsnprintf(str, size, format, ap);
2352 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2353 size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
2357 pa_assert(size > 0);
2360 ret = vsnprintf(str, size, format, ap);
2367 if ((size_t) ret > size-1)
2370 return (size_t) ret;
2373 /* Truncate the specified string, but guarantee that the string
2374 * returned still validates as UTF8 */
2375 char *pa_truncate_utf8(char *c, size_t l) {
2377 pa_assert(pa_utf8_valid(c));
2384 while (l > 0 && !pa_utf8_valid(c))
2390 char *pa_getcwd(void) {
2394 char *p = pa_xmalloc(l);
2398 if (errno != ERANGE) {
2408 void *pa_will_need(const void *p, size_t l) {
2409 #ifdef RLIMIT_MEMLOCK
2416 const size_t page_size = pa_page_size();
2421 a = PA_PAGE_ALIGN_PTR(p);
2422 size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
2424 #ifdef HAVE_POSIX_MADVISE
2425 if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
2426 pa_log_debug("posix_madvise() worked fine!");
2431 /* Most likely the memory was not mmap()ed from a file and thus
2432 * madvise() didn't work, so let's misuse mlock() do page this
2433 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2434 * inviting, the man page of mlock() tells us: "All pages that
2435 * contain a part of the specified address range are guaranteed to
2436 * be resident in RAM when the call returns successfully." */
2438 #ifdef RLIMIT_MEMLOCK
2439 pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
2441 if (rlim.rlim_cur < page_size) {
2442 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));
2447 bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
2452 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r));
2455 while (size > 0 && bs > 0) {
2460 if (mlock(a, bs) < 0) {
2461 bs = PA_PAGE_ALIGN(bs / 2);
2465 pa_assert_se(munlock(a, bs) == 0);
2467 a = (const uint8_t*) a + bs;
2473 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno));
2475 pa_log_debug("mlock() worked fine!");
2480 void pa_close_pipe(int fds[2]) {
2484 pa_assert_se(pa_close(fds[0]) == 0);
2487 pa_assert_se(pa_close(fds[1]) == 0);
2489 fds[0] = fds[1] = -1;
2492 char *pa_readlink(const char *p) {
2493 #ifdef HAVE_READLINK
2502 if ((n = readlink(p, c, l-1)) < 0) {
2507 if ((size_t) n < l-1) {
2520 int pa_close_all(int except_fd, ...) {
2525 va_start(ap, except_fd);
2528 for (n = 1; va_arg(ap, int) >= 0; n++)
2533 p = pa_xnew(int, n+1);
2535 va_start(ap, except_fd);
2538 if (except_fd >= 0) {
2542 while ((fd = va_arg(ap, int)) >= 0)
2549 r = pa_close_allv(p);
2555 int pa_close_allv(const int except_fds[]) {
2560 #if defined(__linux__) || defined(__sun)
2564 if ((d = opendir("/proc/self/fd"))) {
2568 while ((de = readdir(d))) {
2574 if (de->d_name[0] == '.')
2578 l = strtol(de->d_name, &e, 10);
2579 if (errno != 0 || !e || *e) {
2587 if ((long) fd != l) {
2600 for (i = 0; except_fds[i] >= 0; i++)
2601 if (except_fds[i] == fd) {
2609 if (pa_close(fd) < 0) {
2610 saved_errno = errno;
2612 errno = saved_errno;
2624 if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
2625 maxfd = (int) rl.rlim_max;
2627 maxfd = sysconf(_SC_OPEN_MAX);
2629 for (fd = 3; fd < maxfd; fd++) {
2634 for (i = 0; except_fds[i] >= 0; i++)
2635 if (except_fds[i] == fd) {
2643 if (pa_close(fd) < 0 && errno != EBADF)
2646 #endif /* !OS_IS_WIN32 */
2651 int pa_unblock_sigs(int except, ...) {
2656 va_start(ap, except);
2659 for (n = 1; va_arg(ap, int) >= 0; n++)
2664 p = pa_xnew(int, n+1);
2666 va_start(ap, except);
2673 while ((sig = va_arg(ap, int)) >= 0)
2680 r = pa_unblock_sigsv(p);
2686 int pa_unblock_sigsv(const int except[]) {
2691 if (sigemptyset(&ss) < 0)
2694 for (i = 0; except[i] > 0; i++)
2695 if (sigaddset(&ss, except[i]) < 0)
2698 return sigprocmask(SIG_SETMASK, &ss, NULL);
2704 int pa_reset_sigs(int except, ...) {
2709 va_start(ap, except);
2712 for (n = 1; va_arg(ap, int) >= 0; n++)
2717 p = pa_xnew(int, n+1);
2719 va_start(ap, except);
2726 while ((sig = va_arg(ap, int)) >= 0)
2733 r = pa_reset_sigsv(p);
2739 int pa_reset_sigsv(const int except[]) {
2743 for (sig = 1; sig < NSIG; sig++) {
2755 for (i = 0; except[i] > 0; i++) {
2756 if (sig == except[i]) {
2765 struct sigaction sa;
2767 memset(&sa, 0, sizeof(sa));
2768 sa.sa_handler = SIG_DFL;
2770 /* On Linux the first two RT signals are reserved by
2771 * glibc, and sigaction() will return EINVAL for them. */
2772 if ((sigaction(sig, &sa, NULL) < 0))
2773 if (errno != EINVAL)
2782 void pa_set_env(const char *key, const char *value) {
2786 /* This is not thread-safe */
2789 SetEnvironmentVariable(key, value);
2791 setenv(key, value, 1);
2795 void pa_unset_env(const char *key) {
2798 /* This is not thread-safe */
2801 SetEnvironmentVariable(key, NULL);
2807 void pa_set_env_and_record(const char *key, const char *value) {
2811 /* This is not thread-safe */
2813 pa_set_env(key, value);
2814 recorded_env = pa_strlist_prepend(recorded_env, key);
2817 void pa_unset_env_recorded(void) {
2819 /* This is not thread-safe */
2824 recorded_env = pa_strlist_pop(recorded_env, &s);
2834 bool pa_in_system_mode(void) {
2837 if (!(e = getenv("PULSE_SYSTEM")))
2843 /* Checks a delimiters-separated list of words in haystack for needle */
2844 bool pa_str_in_list(const char *haystack, const char *delimiters, const char *needle) {
2846 const char *state = NULL;
2848 if (!haystack || !needle)
2851 while ((s = pa_split(haystack, delimiters, &state))) {
2852 if (pa_streq(needle, s)) {
2863 /* Checks a whitespace-separated list of words in haystack for needle */
2864 bool pa_str_in_list_spaces(const char *haystack, const char *needle) {
2867 const char *state = NULL;
2869 if (!haystack || !needle)
2872 while ((s = pa_split_spaces_in_place(haystack, &n, &state))) {
2873 if (pa_strneq(needle, s, n))
2880 char *pa_get_user_name_malloc(void) {
2884 #ifdef _SC_LOGIN_NAME_MAX
2885 k = (ssize_t) sysconf(_SC_LOGIN_NAME_MAX);
2891 u = pa_xnew(char, k+1);
2893 if (!(pa_get_user_name(u, k))) {
2901 char *pa_get_host_name_malloc(void) {
2910 if (!pa_get_host_name(c, l)) {
2912 if (errno != EINVAL && errno != ENAMETOOLONG)
2915 } else if (strlen(c) < l-1) {
2923 u = pa_utf8_filter(c);
2928 /* Hmm, the hostname is as long the space we offered the
2929 * function, we cannot know if it fully fit in, so let's play
2930 * safe and retry. */
2939 char *pa_machine_id(void) {
2943 /* The returned value is supposed be some kind of ascii identifier
2944 * that is unique and stable across reboots. First we try if the machine-id
2945 * file is available. If it's available, that's great, since it provides an
2946 * identifier that suits our needs perfectly. If it's not, we fall back to
2947 * the hostname, which is not as good, since it can change over time. */
2949 /* We search for the machine-id file from four locations. The first two are
2950 * relative to the configured installation prefix, but if we're installed
2951 * under /usr/local, for example, it's likely that the machine-id won't be
2952 * found there, so we also try the hardcoded paths.
2954 * PA_MACHINE_ID or PA_MACHINE_ID_FALLBACK might exist on a Windows system,
2955 * but the last two hardcoded paths certainly don't, hence we don't try
2956 * them on Windows. */
2957 if ((f = pa_fopen_cloexec(PA_MACHINE_ID, "r")) ||
2958 (f = pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK, "r")) ||
2959 #if !defined(OS_IS_WIN32)
2960 (f = pa_fopen_cloexec("/etc/machine-id", "r")) ||
2961 (f = pa_fopen_cloexec("/var/lib/dbus/machine-id", "r"))
2966 char ln[34] = "", *r;
2968 r = fgets(ln, sizeof(ln)-1, f);
2974 return pa_utf8_filter(ln);
2977 if ((h = pa_get_host_name_malloc()))
2980 #if !defined(OS_IS_WIN32) && !defined(__ANDROID__)
2981 /* If no hostname was set we use the POSIX hostid. It's usually
2982 * the IPv4 address. Might not be that stable. */
2983 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
2989 char *pa_session_id(void) {
2992 e = getenv("XDG_SESSION_ID");
2996 return pa_utf8_filter(e);
2999 char *pa_uname_string(void) {
3003 pa_assert_se(uname(&u) >= 0);
3005 return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
3011 i.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
3012 pa_assert_se(GetVersionEx(&i));
3014 return pa_sprintf_malloc("Windows %d.%d (%d) %s", i.dwMajorVersion, i.dwMinorVersion, i.dwBuildNumber, i.szCSDVersion);
3018 #ifdef HAVE_VALGRIND_MEMCHECK_H
3019 bool pa_in_valgrind(void) {
3022 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
3023 * here instead of really checking whether we run in valgrind or
3027 b = getenv("VALGRIND") ? 2 : 1;
3033 unsigned pa_gcd(unsigned a, unsigned b) {
3044 void pa_reduce(unsigned *num, unsigned *den) {
3046 unsigned gcd = pa_gcd(*num, *den);
3054 pa_assert(pa_gcd(*num, *den) == 1);
3057 unsigned pa_ncpus(void) {
3060 #ifdef _SC_NPROCESSORS_ONLN
3061 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
3066 return ncpus <= 0 ? 1 : (unsigned) ncpus;
3069 char *pa_replace(const char*s, const char*a, const char *b) {
3079 sb = pa_strbuf_new();
3084 if (!(p = strstr(s, a)))
3087 pa_strbuf_putsn(sb, s, p-s);
3088 pa_strbuf_puts(sb, b);
3092 pa_strbuf_puts(sb, s);
3094 return pa_strbuf_to_string_free(sb);
3097 char *pa_escape(const char *p, const char *chars) {
3100 char *out_string, *output;
3101 int char_count = strlen(p);
3103 /* Maximum number of characters in output string
3104 * including trailing 0. */
3105 char_count = 2 * char_count + 1;
3107 /* allocate output string */
3108 out_string = pa_xmalloc(char_count);
3109 output = out_string;
3111 /* write output string */
3112 for (s = p; *s; ++s) {
3116 for (c = chars; *c; ++c) {
3128 /* Remove trailing garbage */
3129 output = pa_xstrdup(out_string);
3131 pa_xfree(out_string);
3135 char *pa_unescape(char *p) {
3137 bool escaped = false;
3139 for (s = p, d = p; *s; s++) {
3140 if (!escaped && *s == '\\') {
3154 char *pa_realpath(const char *path) {
3158 /* We want only absolute paths */
3159 if (path[0] != '/') {
3164 #if defined(__GLIBC__)
3168 if (!(r = realpath(path, NULL)))
3171 /* We copy this here in case our pa_xmalloc() is not
3172 * implemented on top of libc malloc() */
3176 #elif defined(PATH_MAX)
3179 path_buf = pa_xmalloc(PATH_MAX);
3181 #if defined(OS_IS_WIN32)
3182 if (!(t = _fullpath(path_buf, path, _MAX_PATH))) {
3187 if (!(t = realpath(path, path_buf))) {
3194 #error "It's not clear whether this system supports realpath(..., NULL) like GNU libc does. If it doesn't we need a private version of realpath() here."
3200 void pa_disable_sigpipe(void) {
3203 struct sigaction sa;
3207 if (sigaction(SIGPIPE, NULL, &sa) < 0) {
3208 pa_log("sigaction(): %s", pa_cstrerror(errno));
3212 sa.sa_handler = SIG_IGN;
3214 if (sigaction(SIGPIPE, &sa, NULL) < 0) {
3215 pa_log("sigaction(): %s", pa_cstrerror(errno));
3221 void pa_xfreev(void**a) {
3227 for (p = a; *p; p++)
3233 char **pa_split_spaces_strv(const char *s) {
3235 unsigned i = 0, n = 8;
3236 const char *state = NULL;
3238 t = pa_xnew(char*, n);
3239 while ((e = pa_split_spaces(s, &state))) {
3244 t = pa_xrenew(char*, t, n);
3257 char* pa_maybe_prefix_path(const char *path, const char *prefix) {
3260 if (pa_is_path_absolute(path))
3261 return pa_xstrdup(path);
3263 return pa_sprintf_malloc("%s" PA_PATH_SEP "%s", prefix, path);
3266 size_t pa_pipe_buf(int fd) {
3271 if ((n = fpathconf(fd, _PC_PIPE_BUF)) >= 0)
3282 void pa_reset_personality(void) {
3284 #if defined(__linux__) && !defined(__ANDROID__)
3285 if (personality(PER_LINUX) < 0)
3286 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno));
3291 bool pa_run_from_build_tree(void) {
3292 static bool b = false;
3294 #ifdef HAVE_RUNNING_FROM_BUILD_TREE
3297 if ((rp = pa_readlink("/proc/self/exe"))) {
3298 b = pa_startswith(rp, PA_BUILDDIR);
3307 const char *pa_get_temp_dir(void) {
3310 if ((t = getenv("TMPDIR")) &&
3311 pa_is_path_absolute(t))
3314 if ((t = getenv("TMP")) &&
3315 pa_is_path_absolute(t))
3318 if ((t = getenv("TEMP")) &&
3319 pa_is_path_absolute(t))
3322 if ((t = getenv("TEMPDIR")) &&
3323 pa_is_path_absolute(t))
3329 int pa_open_cloexec(const char *fn, int flags, mode_t mode) {
3337 if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0)
3340 if (errno != EINVAL)
3344 if ((fd = open(fn, flags, mode)) >= 0)
3351 /* Some implementations might simply ignore O_CLOEXEC if it is not
3352 * understood, make sure FD_CLOEXEC is enabled anyway */
3354 pa_make_fd_cloexec(fd);
3358 int pa_socket_cloexec(int domain, int type, int protocol) {
3362 if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0)
3365 if (errno != EINVAL)
3369 if ((fd = socket(domain, type, protocol)) >= 0)
3376 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3377 * not understood, make sure FD_CLOEXEC is enabled anyway */
3379 pa_make_fd_cloexec(fd);
3383 int pa_pipe_cloexec(int pipefd[2]) {
3387 if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0)
3390 if (errno == EMFILE) {
3391 pa_log_error("The per-process limit on the number of open file descriptors has been reached.");
3395 if (errno == ENFILE) {
3396 pa_log_error("The system-wide limit on the total number of open files has been reached.");
3400 if (errno != EINVAL && errno != ENOSYS)
3405 if ((r = pipe(pipefd)) >= 0)
3408 if (errno == EMFILE) {
3409 pa_log_error("The per-process limit on the number of open file descriptors has been reached.");
3413 if (errno == ENFILE) {
3414 pa_log_error("The system-wide limit on the total number of open files has been reached.");
3422 pa_make_fd_cloexec(pipefd[0]);
3423 pa_make_fd_cloexec(pipefd[1]);
3428 int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
3434 if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0)
3437 if (errno != EINVAL && errno != ENOSYS)
3443 if ((fd = paccept(sockfd, addr, addrlen, NULL, SOCK_CLOEXEC)) >= 0)
3447 if ((fd = accept(sockfd, addr, addrlen)) >= 0)
3454 pa_make_fd_cloexec(fd);
3458 FILE* pa_fopen_cloexec(const char *path, const char *mode) {
3462 m = pa_sprintf_malloc("%se", mode);
3465 if ((f = fopen(path, m))) {
3472 if (errno != EINVAL)
3475 if (!(f = fopen(path, mode)))
3479 pa_make_fd_cloexec(fileno(f));
3483 void pa_nullify_stdfds(void) {
3486 pa_close(STDIN_FILENO);
3487 pa_close(STDOUT_FILENO);
3488 pa_close(STDERR_FILENO);
3490 pa_assert_se(open("/dev/null", O_RDONLY) == STDIN_FILENO);
3491 pa_assert_se(open("/dev/null", O_WRONLY) == STDOUT_FILENO);
3492 pa_assert_se(open("/dev/null", O_WRONLY) == STDERR_FILENO);
3499 char *pa_read_line_from_file(const char *fn) {
3501 char ln[256] = "", *r;
3503 if (!(f = pa_fopen_cloexec(fn, "r")))
3506 r = fgets(ln, sizeof(ln)-1, f);
3515 return pa_xstrdup(ln);
3518 bool pa_running_in_vm(void) {
3520 #if defined(__i386__) || defined(__x86_64__)
3522 /* Both CPUID and DMI are x86 specific interfaces... */
3525 unsigned int eax, ebx, ecx, edx;
3529 const char *const dmi_vendors[] = {
3530 "/sys/class/dmi/id/sys_vendor",
3531 "/sys/class/dmi/id/board_vendor",
3532 "/sys/class/dmi/id/bios_vendor"
3537 for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) {
3540 if ((s = pa_read_line_from_file(dmi_vendors[i]))) {
3542 if (pa_startswith(s, "QEMU") ||
3543 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3544 pa_startswith(s, "VMware") ||
3545 pa_startswith(s, "VMW") ||
3546 pa_startswith(s, "Microsoft Corporation") ||
3547 pa_startswith(s, "innotek GmbH") ||
3548 pa_startswith(s, "Xen")) {
3562 /* Hypervisors provide presence on 0x1 cpuid leaf.
3563 * http://lwn.net/Articles/301888/ */
3564 if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0)
3567 if (ecx & 0x80000000)
3570 #endif /* HAVE_CPUID_H */
3572 #endif /* defined(__i386__) || defined(__x86_64__) */
3577 size_t pa_page_size(void) {
3578 #if defined(PAGE_SIZE)
3580 #elif defined(PAGESIZE)
3582 #elif defined(HAVE_SYSCONF)
3583 static size_t page_size = 4096; /* Let's hope it's like x86. */
3586 long ret = sysconf(_SC_PAGE_SIZE);