pulsecore: Use pa_streq instead of strcmp.
[pulseaudio-raopUDP/pulseaudio-raop-alac.git] / src / pulsecore / core-util.c
blobd79d289f1e75ba9e2d3972ca9cb80630b6a8e94e
1 /***
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
21 USA.
22 ***/
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <signal.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <limits.h>
37 #include <ctype.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <dirent.h>
42 #ifdef HAVE_LANGINFO_H
43 #include <langinfo.h>
44 #endif
46 #ifdef HAVE_UNAME
47 #include <sys/utsname.h>
48 #endif
50 #if defined(HAVE_REGEX_H)
51 #include <regex.h>
52 #elif defined(HAVE_PCREPOSIX_H)
53 #include <pcreposix.h>
54 #endif
56 #ifdef HAVE_STRTOF_L
57 #include <locale.h>
58 #endif
60 #ifdef HAVE_SCHED_H
61 #include <sched.h>
63 #if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
64 #define SCHED_RESET_ON_FORK 0x40000000
65 #endif
66 #endif
68 #ifdef HAVE_SYS_RESOURCE_H
69 #include <sys/resource.h>
70 #endif
72 #ifdef HAVE_SYS_CAPABILITY_H
73 #include <sys/capability.h>
74 #endif
76 #ifdef HAVE_SYS_MMAN_H
77 #include <sys/mman.h>
78 #endif
80 #ifdef HAVE_PTHREAD
81 #include <pthread.h>
82 #endif
84 #ifdef HAVE_NETDB_H
85 #include <netdb.h>
86 #endif
88 #ifdef HAVE_WINDOWS_H
89 #include <windows.h>
90 #endif
92 #ifndef ENOTSUP
93 #define ENOTSUP 135
94 #endif
96 #ifdef HAVE_PWD_H
97 #include <pwd.h>
98 #endif
100 #ifdef HAVE_GRP_H
101 #include <grp.h>
102 #endif
104 #ifdef HAVE_LIBSAMPLERATE
105 #include <samplerate.h>
106 #endif
108 #ifdef __APPLE__
109 #include <xlocale.h>
110 #include <mach/mach_init.h>
111 #include <mach/thread_act.h>
112 #include <mach/thread_policy.h>
113 #include <sys/sysctl.h>
114 #endif
116 #ifdef HAVE_DBUS
117 #include "rtkit.h"
118 #endif
120 #ifdef __linux__
121 #include <sys/personality.h>
122 #endif
124 #include <pulse/xmalloc.h>
125 #include <pulse/util.h>
126 #include <pulse/utf8.h>
128 #include <pulsecore/core-error.h>
129 #include <pulsecore/socket.h>
130 #include <pulsecore/log.h>
131 #include <pulsecore/macro.h>
132 #include <pulsecore/thread.h>
133 #include <pulsecore/strbuf.h>
134 #include <pulsecore/usergroup.h>
135 #include <pulsecore/strlist.h>
136 #include <pulsecore/cpu-x86.h>
137 #include <pulsecore/pipe.h>
139 #include "core-util.h"
141 /* Not all platforms have this */
142 #ifndef MSG_NOSIGNAL
143 #define MSG_NOSIGNAL 0
144 #endif
146 #define NEWLINE "\r\n"
147 #define WHITESPACE "\n\r \t"
149 static pa_strlist *recorded_env = NULL;
151 #ifdef OS_IS_WIN32
153 /* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
154 char *pa_win32_get_toplevel(HANDLE handle) {
155 static char *toplevel = NULL;
157 if (!toplevel) {
158 char library_path[MAX_PATH];
159 char *p;
161 if (!GetModuleFileName(handle, library_path, MAX_PATH))
162 return NULL;
164 toplevel = pa_xstrdup(library_path);
166 p = strrchr(toplevel, PA_PATH_SEP_CHAR);
167 if (p)
168 *p = '\0';
170 p = strrchr(toplevel, PA_PATH_SEP_CHAR);
171 if (p && pa_streq(p + 1, "bin"))
172 *p = '\0';
175 return toplevel;
178 #endif
180 /** Make a file descriptor nonblock. Doesn't do any error checking */
181 void pa_make_fd_nonblock(int fd) {
183 #ifdef O_NONBLOCK
184 int v;
185 pa_assert(fd >= 0);
187 pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
189 if (!(v & O_NONBLOCK))
190 pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0);
192 #elif defined(OS_IS_WIN32)
193 u_long arg = 1;
194 if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
195 pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
196 pa_log_warn("Only sockets can be made non-blocking!");
198 #else
199 pa_log_warn("Non-blocking I/O not supported.!");
200 #endif
204 /* Set the FD_CLOEXEC flag for a fd */
205 void pa_make_fd_cloexec(int fd) {
207 #ifdef FD_CLOEXEC
208 int v;
209 pa_assert(fd >= 0);
211 pa_assert_se((v = fcntl(fd, F_GETFD, 0)) >= 0);
213 if (!(v & FD_CLOEXEC))
214 pa_assert_se(fcntl(fd, F_SETFD, v|FD_CLOEXEC) >= 0);
215 #endif
219 /** Creates a directory securely */
220 int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
221 struct stat st;
222 int r, saved_errno;
224 pa_assert(dir);
226 #ifdef OS_IS_WIN32
227 r = mkdir(dir);
228 #else
230 mode_t u;
231 u = umask((~m) & 0777);
232 r = mkdir(dir, m);
233 umask(u);
235 #endif
237 if (r < 0 && errno != EEXIST)
238 return -1;
240 #if defined(HAVE_FSTAT) && !defined(OS_IS_WIN32)
242 int fd;
243 if ((fd = open(dir,
244 #ifdef O_CLOEXEC
245 O_CLOEXEC|
246 #endif
247 #ifdef O_NOCTTY
248 O_NOCTTY|
249 #endif
250 #ifdef O_NOFOLLOW
251 O_NOFOLLOW|
252 #endif
253 O_RDONLY)) < 0)
254 goto fail;
256 if (fstat(fd, &st) < 0) {
257 pa_assert_se(pa_close(fd) >= 0);
258 goto fail;
261 if (!S_ISDIR(st.st_mode)) {
262 pa_assert_se(pa_close(fd) >= 0);
263 errno = EEXIST;
264 goto fail;
267 #ifdef HAVE_FCHOWN
268 if (uid == (uid_t) -1)
269 uid = getuid();
270 if (gid == (gid_t) -1)
271 gid = getgid();
272 if (fchown(fd, uid, gid) < 0)
273 goto fail;
274 #endif
276 #ifdef HAVE_FCHMOD
277 (void) fchmod(fd, m);
278 #endif
280 pa_assert_se(pa_close(fd) >= 0);
282 #endif
284 #ifdef HAVE_LSTAT
285 if (lstat(dir, &st) < 0)
286 #else
287 if (stat(dir, &st) < 0)
288 #endif
289 goto fail;
291 #ifndef OS_IS_WIN32
292 if (!S_ISDIR(st.st_mode) ||
293 (st.st_uid != uid) ||
294 (st.st_gid != gid) ||
295 ((st.st_mode & 0777) != m)) {
296 errno = EACCES;
297 goto fail;
299 #else
300 pa_log_warn("Secure directory creation not supported on Win32.");
301 #endif
303 return 0;
305 fail:
306 saved_errno = errno;
307 rmdir(dir);
308 errno = saved_errno;
310 return -1;
313 /* Return a newly allocated sting containing the parent directory of the specified file */
314 char *pa_parent_dir(const char *fn) {
315 char *slash, *dir = pa_xstrdup(fn);
317 if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
318 pa_xfree(dir);
319 errno = ENOENT;
320 return NULL;
323 *(slash-1) = 0;
324 return dir;
327 /* Creates a the parent directory of the specified path securely */
328 int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {
329 int ret = -1;
330 char *dir;
332 if (!(dir = pa_parent_dir(fn)))
333 goto finish;
335 if (pa_make_secure_dir(dir, m, uid, gid) < 0)
336 goto finish;
338 ret = 0;
340 finish:
341 pa_xfree(dir);
342 return ret;
345 /** Platform independent read function. Necessary since not all
346 * systems treat all file descriptors equal. If type is
347 * non-NULL it is used to cache the type of the fd. This is
348 * useful for making sure that only a single syscall is executed per
349 * function call. The variable pointed to should be initialized to 0
350 * by the caller. */
351 ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
353 #ifdef OS_IS_WIN32
355 if (!type || *type == 0) {
356 ssize_t r;
358 if ((r = recv(fd, buf, count, 0)) >= 0)
359 return r;
361 if (WSAGetLastError() != WSAENOTSOCK) {
362 errno = WSAGetLastError();
363 return r;
366 if (type)
367 *type = 1;
370 #endif
372 for (;;) {
373 ssize_t r;
375 if ((r = read(fd, buf, count)) < 0)
376 if (errno == EINTR)
377 continue;
379 return r;
383 /** Similar to pa_read(), but handles writes */
384 ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
386 if (!type || *type == 0) {
387 ssize_t r;
389 for (;;) {
390 if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) {
392 if (errno == EINTR)
393 continue;
395 break;
398 return r;
401 #ifdef OS_IS_WIN32
402 if (WSAGetLastError() != WSAENOTSOCK) {
403 errno = WSAGetLastError();
404 return r;
406 #else
407 if (errno != ENOTSOCK)
408 return r;
409 #endif
411 if (type)
412 *type = 1;
415 for (;;) {
416 ssize_t r;
418 if ((r = write(fd, buf, count)) < 0)
419 if (errno == EINTR)
420 continue;
422 return r;
426 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
427 * unless EOF is reached or an error occurred */
428 ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
429 ssize_t ret = 0;
430 int _type;
432 pa_assert(fd >= 0);
433 pa_assert(data);
434 pa_assert(size);
436 if (!type) {
437 _type = 0;
438 type = &_type;
441 while (size > 0) {
442 ssize_t r;
444 if ((r = pa_read(fd, data, size, type)) < 0)
445 return r;
447 if (r == 0)
448 break;
450 ret += r;
451 data = (uint8_t*) data + r;
452 size -= (size_t) r;
455 return ret;
458 /** Similar to pa_loop_read(), but wraps write() */
459 ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
460 ssize_t ret = 0;
461 int _type;
463 pa_assert(fd >= 0);
464 pa_assert(data);
465 pa_assert(size);
467 if (!type) {
468 _type = 0;
469 type = &_type;
472 while (size > 0) {
473 ssize_t r;
475 if ((r = pa_write(fd, data, size, type)) < 0)
476 return r;
478 if (r == 0)
479 break;
481 ret += r;
482 data = (const uint8_t*) data + r;
483 size -= (size_t) r;
486 return ret;
489 /** Platform independent read function. Necessary since not all
490 * systems treat all file descriptors equal. */
491 int pa_close(int fd) {
493 #ifdef OS_IS_WIN32
494 int ret;
496 if ((ret = closesocket(fd)) == 0)
497 return 0;
499 if (WSAGetLastError() != WSAENOTSOCK) {
500 errno = WSAGetLastError();
501 return ret;
503 #endif
505 for (;;) {
506 int r;
508 if ((r = close(fd)) < 0)
509 if (errno == EINTR)
510 continue;
512 return r;
516 /* Print a warning messages in case that the given signal is not
517 * blocked or trapped */
518 void pa_check_signal_is_blocked(int sig) {
519 #ifdef HAVE_SIGACTION
520 struct sigaction sa;
521 sigset_t set;
523 /* If POSIX threads are supported use thread-aware
524 * pthread_sigmask() function, to check if the signal is
525 * blocked. Otherwise fall back to sigprocmask() */
527 #ifdef HAVE_PTHREAD
528 if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) {
529 #endif
530 if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) {
531 pa_log("sigprocmask(): %s", pa_cstrerror(errno));
532 return;
534 #ifdef HAVE_PTHREAD
536 #endif
538 if (sigismember(&set, sig))
539 return;
541 /* Check whether the signal is trapped */
543 if (sigaction(sig, NULL, &sa) < 0) {
544 pa_log("sigaction(): %s", pa_cstrerror(errno));
545 return;
548 if (sa.sa_handler != SIG_DFL)
549 return;
551 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig));
552 #else /* HAVE_SIGACTION */
553 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig));
554 #endif
557 /* The following function is based on an example from the GNU libc
558 * documentation. This function is similar to GNU's asprintf(). */
559 char *pa_sprintf_malloc(const char *format, ...) {
560 size_t size = 100;
561 char *c = NULL;
563 pa_assert(format);
565 for(;;) {
566 int r;
567 va_list ap;
569 c = pa_xrealloc(c, size);
571 va_start(ap, format);
572 r = vsnprintf(c, size, format, ap);
573 va_end(ap);
575 c[size-1] = 0;
577 if (r > -1 && (size_t) r < size)
578 return c;
580 if (r > -1) /* glibc 2.1 */
581 size = (size_t) r+1;
582 else /* glibc 2.0 */
583 size *= 2;
587 /* Same as the previous function, but use a va_list instead of an
588 * ellipsis */
589 char *pa_vsprintf_malloc(const char *format, va_list ap) {
590 size_t size = 100;
591 char *c = NULL;
593 pa_assert(format);
595 for(;;) {
596 int r;
597 va_list aq;
599 c = pa_xrealloc(c, size);
601 va_copy(aq, ap);
602 r = vsnprintf(c, size, format, aq);
603 va_end(aq);
605 c[size-1] = 0;
607 if (r > -1 && (size_t) r < size)
608 return c;
610 if (r > -1) /* glibc 2.1 */
611 size = (size_t) r+1;
612 else /* glibc 2.0 */
613 size *= 2;
617 /* Similar to OpenBSD's strlcpy() function */
618 char *pa_strlcpy(char *b, const char *s, size_t l) {
619 size_t k;
621 pa_assert(b);
622 pa_assert(s);
623 pa_assert(l > 0);
625 k = strlen(s);
627 if (k > l-1)
628 k = l-1;
630 memcpy(b, s, k);
631 b[k] = 0;
633 return b;
636 #ifdef _POSIX_PRIORITY_SCHEDULING
637 static int set_scheduler(int rtprio) {
638 #ifdef HAVE_SCHED_H
639 struct sched_param sp;
640 #ifdef HAVE_DBUS
641 int r;
642 DBusError error;
643 DBusConnection *bus;
645 dbus_error_init(&error);
646 #endif
648 pa_zero(sp);
649 sp.sched_priority = rtprio;
651 #ifdef SCHED_RESET_ON_FORK
652 if (pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, &sp) == 0) {
653 pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
654 return 0;
656 #endif
658 if (pthread_setschedparam(pthread_self(), SCHED_RR, &sp) == 0) {
659 pa_log_debug("SCHED_RR worked.");
660 return 0;
662 #endif /* HAVE_SCHED_H */
664 #ifdef HAVE_DBUS
665 /* Try to talk to RealtimeKit */
667 if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
668 pa_log("Failed to connect to system bus: %s\n", error.message);
669 dbus_error_free(&error);
670 errno = -EIO;
671 return -1;
674 /* We need to disable exit on disconnect because otherwise
675 * dbus_shutdown will kill us. See
676 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
677 dbus_connection_set_exit_on_disconnect(bus, FALSE);
679 r = rtkit_make_realtime(bus, 0, rtprio);
680 dbus_connection_close(bus);
681 dbus_connection_unref(bus);
683 if (r >= 0) {
684 pa_log_debug("RealtimeKit worked.");
685 return 0;
688 errno = -r;
689 #else
690 errno = 0;
691 #endif
693 return -1;
695 #endif
697 /* Make the current thread a realtime thread, and acquire the highest
698 * rtprio we can get that is less or equal the specified parameter. If
699 * the thread is already realtime, don't do anything. */
700 int pa_make_realtime(int rtprio) {
702 #if defined(OS_IS_DARWIN)
703 struct thread_time_constraint_policy ttcpolicy;
704 uint64_t freq = 0;
705 size_t size = sizeof(freq);
706 int ret;
708 ret = sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0);
709 if (ret < 0) {
710 pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
711 return -1;
714 pa_log_debug("sysctl for hw.cpufrequency: %llu", freq);
716 /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
717 ttcpolicy.period = freq / 160;
718 ttcpolicy.computation = freq / 3300;
719 ttcpolicy.constraint = freq / 2200;
720 ttcpolicy.preemptible = 1;
722 ret = thread_policy_set(mach_thread_self(),
723 THREAD_TIME_CONSTRAINT_POLICY,
724 (thread_policy_t) &ttcpolicy,
725 THREAD_TIME_CONSTRAINT_POLICY_COUNT);
726 if (ret) {
727 pa_log_info("Unable to set real-time thread priority (%08x).", ret);
728 return -1;
731 pa_log_info("Successfully acquired real-time thread priority.");
732 return 0;
734 #elif defined(_POSIX_PRIORITY_SCHEDULING)
735 int p;
737 if (set_scheduler(rtprio) >= 0) {
738 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio);
739 return 0;
742 for (p = rtprio-1; p >= 1; p--)
743 if (set_scheduler(p) >= 0) {
744 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p, rtprio);
745 return 0;
747 #elif defined(OS_IS_WIN32)
748 /* Windows only allows realtime scheduling to be set on a per process basis.
749 * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
750 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) {
751 pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
752 return 0;
755 pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
756 errno = EPERM;
757 #else
758 errno = ENOTSUP;
759 #endif
760 pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno));
761 return -1;
764 #ifdef HAVE_SYS_RESOURCE_H
765 static int set_nice(int nice_level) {
766 #ifdef HAVE_DBUS
767 DBusError error;
768 DBusConnection *bus;
769 int r;
771 dbus_error_init(&error);
772 #endif
774 #ifdef HAVE_SYS_RESOURCE_H
775 if (setpriority(PRIO_PROCESS, 0, nice_level) >= 0) {
776 pa_log_debug("setpriority() worked.");
777 return 0;
779 #endif
781 #ifdef HAVE_DBUS
782 /* Try to talk to RealtimeKit */
784 if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
785 pa_log("Failed to connect to system bus: %s\n", error.message);
786 dbus_error_free(&error);
787 errno = -EIO;
788 return -1;
791 /* We need to disable exit on disconnect because otherwise
792 * dbus_shutdown will kill us. See
793 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
794 dbus_connection_set_exit_on_disconnect(bus, FALSE);
796 r = rtkit_make_high_priority(bus, 0, nice_level);
797 dbus_connection_unref(bus);
799 if (r >= 0) {
800 pa_log_debug("RealtimeKit worked.");
801 return 0;
804 errno = -r;
805 #endif
807 return -1;
809 #endif
811 /* Raise the priority of the current process as much as possible that
812 * is <= the specified nice level..*/
813 int pa_raise_priority(int nice_level) {
815 #ifdef HAVE_SYS_RESOURCE_H
816 int n;
818 if (set_nice(nice_level) >= 0) {
819 pa_log_info("Successfully gained nice level %i.", nice_level);
820 return 0;
823 for (n = nice_level+1; n < 0; n++)
824 if (set_nice(n) >= 0) {
825 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
826 return 0;
829 pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno));
830 return -1;
831 #endif
833 #ifdef OS_IS_WIN32
834 if (nice_level < 0) {
835 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
836 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
837 errno = EPERM;
838 return -1;
841 pa_log_info("Successfully gained high priority class.");
843 #endif
845 return 0;
848 /* Reset the priority to normal, inverting the changes made by
849 * pa_raise_priority() and pa_make_realtime()*/
850 void pa_reset_priority(void) {
851 #ifdef HAVE_SYS_RESOURCE_H
852 struct sched_param sp;
854 setpriority(PRIO_PROCESS, 0, 0);
856 pa_zero(sp);
857 pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp);
858 #endif
860 #ifdef OS_IS_WIN32
861 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
862 #endif
865 int pa_match(const char *expr, const char *v) {
866 int k;
867 regex_t re;
868 int r;
870 if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
871 errno = EINVAL;
872 return -1;
875 if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
876 r = 1;
877 else if (k == REG_NOMATCH)
878 r = 0;
879 else
880 r = -1;
882 regfree(&re);
884 if (r < 0)
885 errno = EINVAL;
887 return r;
890 /* Try to parse a boolean string value.*/
891 int pa_parse_boolean(const char *v) {
892 pa_assert(v);
894 /* First we check language independent */
895 if (pa_streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
896 return 1;
897 else if (pa_streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
898 return 0;
900 #ifdef HAVE_LANGINFO_H
902 const char *expr;
903 /* And then we check language dependent */
904 if ((expr = nl_langinfo(YESEXPR)))
905 if (expr[0])
906 if (pa_match(expr, v) > 0)
907 return 1;
909 if ((expr = nl_langinfo(NOEXPR)))
910 if (expr[0])
911 if (pa_match(expr, v) > 0)
912 return 0;
914 #endif
916 errno = EINVAL;
917 return -1;
920 /* Split the specified string wherever one of the strings in delimiter
921 * occurs. Each time it is called returns a newly allocated string
922 * with pa_xmalloc(). The variable state points to, should be
923 * initialized to NULL before the first call. */
924 char *pa_split(const char *c, const char *delimiter, const char**state) {
925 const char *current = *state ? *state : c;
926 size_t l;
928 if (!*current)
929 return NULL;
931 l = strcspn(current, delimiter);
932 *state = current+l;
934 if (**state)
935 (*state)++;
937 return pa_xstrndup(current, l);
940 /* Split a string into words. Otherwise similar to pa_split(). */
941 char *pa_split_spaces(const char *c, const char **state) {
942 const char *current = *state ? *state : c;
943 size_t l;
945 if (!*current || *c == 0)
946 return NULL;
948 current += strspn(current, WHITESPACE);
949 l = strcspn(current, WHITESPACE);
951 *state = current+l;
953 return pa_xstrndup(current, l);
956 PA_STATIC_TLS_DECLARE(signame, pa_xfree);
958 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
959 const char *pa_sig2str(int sig) {
960 char *t;
962 if (sig <= 0)
963 goto fail;
965 #ifdef NSIG
966 if (sig >= NSIG)
967 goto fail;
968 #endif
970 #ifdef HAVE_SIG2STR
972 char buf[SIG2STR_MAX];
974 if (sig2str(sig, buf) == 0) {
975 pa_xfree(PA_STATIC_TLS_GET(signame));
976 t = pa_sprintf_malloc("SIG%s", buf);
977 PA_STATIC_TLS_SET(signame, t);
978 return t;
981 #else
983 switch (sig) {
984 #ifdef SIGHUP
985 case SIGHUP: return "SIGHUP";
986 #endif
987 case SIGINT: return "SIGINT";
988 #ifdef SIGQUIT
989 case SIGQUIT: return "SIGQUIT";
990 #endif
991 case SIGILL: return "SIGULL";
992 #ifdef SIGTRAP
993 case SIGTRAP: return "SIGTRAP";
994 #endif
995 case SIGABRT: return "SIGABRT";
996 #ifdef SIGBUS
997 case SIGBUS: return "SIGBUS";
998 #endif
999 case SIGFPE: return "SIGFPE";
1000 #ifdef SIGKILL
1001 case SIGKILL: return "SIGKILL";
1002 #endif
1003 #ifdef SIGUSR1
1004 case SIGUSR1: return "SIGUSR1";
1005 #endif
1006 case SIGSEGV: return "SIGSEGV";
1007 #ifdef SIGUSR2
1008 case SIGUSR2: return "SIGUSR2";
1009 #endif
1010 #ifdef SIGPIPE
1011 case SIGPIPE: return "SIGPIPE";
1012 #endif
1013 #ifdef SIGALRM
1014 case SIGALRM: return "SIGALRM";
1015 #endif
1016 case SIGTERM: return "SIGTERM";
1017 #ifdef SIGSTKFLT
1018 case SIGSTKFLT: return "SIGSTKFLT";
1019 #endif
1020 #ifdef SIGCHLD
1021 case SIGCHLD: return "SIGCHLD";
1022 #endif
1023 #ifdef SIGCONT
1024 case SIGCONT: return "SIGCONT";
1025 #endif
1026 #ifdef SIGSTOP
1027 case SIGSTOP: return "SIGSTOP";
1028 #endif
1029 #ifdef SIGTSTP
1030 case SIGTSTP: return "SIGTSTP";
1031 #endif
1032 #ifdef SIGTTIN
1033 case SIGTTIN: return "SIGTTIN";
1034 #endif
1035 #ifdef SIGTTOU
1036 case SIGTTOU: return "SIGTTOU";
1037 #endif
1038 #ifdef SIGURG
1039 case SIGURG: return "SIGURG";
1040 #endif
1041 #ifdef SIGXCPU
1042 case SIGXCPU: return "SIGXCPU";
1043 #endif
1044 #ifdef SIGXFSZ
1045 case SIGXFSZ: return "SIGXFSZ";
1046 #endif
1047 #ifdef SIGVTALRM
1048 case SIGVTALRM: return "SIGVTALRM";
1049 #endif
1050 #ifdef SIGPROF
1051 case SIGPROF: return "SIGPROF";
1052 #endif
1053 #ifdef SIGWINCH
1054 case SIGWINCH: return "SIGWINCH";
1055 #endif
1056 #ifdef SIGIO
1057 case SIGIO: return "SIGIO";
1058 #endif
1059 #ifdef SIGPWR
1060 case SIGPWR: return "SIGPWR";
1061 #endif
1062 #ifdef SIGSYS
1063 case SIGSYS: return "SIGSYS";
1064 #endif
1067 #ifdef SIGRTMIN
1068 if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
1069 pa_xfree(PA_STATIC_TLS_GET(signame));
1070 t = pa_sprintf_malloc("SIGRTMIN+%i", sig - SIGRTMIN);
1071 PA_STATIC_TLS_SET(signame, t);
1072 return t;
1074 #endif
1076 #endif
1078 fail:
1080 pa_xfree(PA_STATIC_TLS_GET(signame));
1081 t = pa_sprintf_malloc("SIG%i", sig);
1082 PA_STATIC_TLS_SET(signame, t);
1083 return t;
1086 #ifdef HAVE_GRP_H
1088 /* Check whether the specified GID and the group name match */
1089 static int is_group(gid_t gid, const char *name) {
1090 struct group *group = NULL;
1091 int r = -1;
1093 errno = 0;
1094 if (!(group = pa_getgrgid_malloc(gid))) {
1095 if (!errno)
1096 errno = ENOENT;
1098 pa_log("pa_getgrgid_malloc(%u): %s", gid, pa_cstrerror(errno));
1100 goto finish;
1103 r = pa_streq(name, group->gr_name);
1105 finish:
1106 pa_getgrgid_free(group);
1108 return r;
1111 /* Check the current user is member of the specified group */
1112 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1113 GETGROUPS_T *gids, tgid;
1114 long n = sysconf(_SC_NGROUPS_MAX);
1115 int r = -1, i, k;
1117 pa_assert(n > 0);
1119 gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
1121 if ((n = getgroups((int) n, gids)) < 0) {
1122 pa_log("getgroups(): %s", pa_cstrerror(errno));
1123 goto finish;
1126 for (i = 0; i < n; i++) {
1128 if ((k = is_group(gids[i], name)) < 0)
1129 goto finish;
1130 else if (k > 0) {
1131 *gid = gids[i];
1132 r = 1;
1133 goto finish;
1137 if ((k = is_group(tgid = getgid(), name)) < 0)
1138 goto finish;
1139 else if (k > 0) {
1140 *gid = tgid;
1141 r = 1;
1142 goto finish;
1145 r = 0;
1147 finish:
1149 pa_xfree(gids);
1150 return r;
1153 /* Check whether the specific user id is a member of the specified group */
1154 int pa_uid_in_group(uid_t uid, const char *name) {
1155 struct group *group = NULL;
1156 char **i;
1157 int r = -1;
1159 errno = 0;
1160 if (!(group = pa_getgrnam_malloc(name))) {
1161 if (!errno)
1162 errno = ENOENT;
1163 goto finish;
1166 r = 0;
1167 for (i = group->gr_mem; *i; i++) {
1168 struct passwd *pw = NULL;
1170 errno = 0;
1171 if (!(pw = pa_getpwnam_malloc(*i)))
1172 continue;
1174 if (pw->pw_uid == uid)
1175 r = 1;
1177 pa_getpwnam_free(pw);
1179 if (r == 1)
1180 break;
1183 finish:
1184 pa_getgrnam_free(group);
1186 return r;
1189 /* Get the GID of a given group, return (gid_t) -1 on failure. */
1190 gid_t pa_get_gid_of_group(const char *name) {
1191 gid_t ret = (gid_t) -1;
1192 struct group *gr = NULL;
1194 errno = 0;
1195 if (!(gr = pa_getgrnam_malloc(name))) {
1196 if (!errno)
1197 errno = ENOENT;
1198 goto finish;
1201 ret = gr->gr_gid;
1203 finish:
1204 pa_getgrnam_free(gr);
1205 return ret;
1208 int pa_check_in_group(gid_t g) {
1209 gid_t gids[NGROUPS_MAX];
1210 int r;
1212 if ((r = getgroups(NGROUPS_MAX, gids)) < 0)
1213 return -1;
1215 for (; r > 0; r--)
1216 if (gids[r-1] == g)
1217 return 1;
1219 return 0;
1222 #else /* HAVE_GRP_H */
1224 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1225 errno = ENOTSUP;
1226 return -1;
1230 int pa_uid_in_group(uid_t uid, const char *name) {
1231 errno = ENOTSUP;
1232 return -1;
1235 gid_t pa_get_gid_of_group(const char *name) {
1236 errno = ENOTSUP;
1237 return (gid_t) -1;
1240 int pa_check_in_group(gid_t g) {
1241 errno = ENOTSUP;
1242 return -1;
1245 #endif
1247 /* Lock or unlock a file entirely.
1248 (advisory on UNIX, mandatory on Windows) */
1249 int pa_lock_fd(int fd, int b) {
1250 #ifdef F_SETLKW
1251 struct flock f_lock;
1253 /* Try a R/W lock first */
1255 f_lock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
1256 f_lock.l_whence = SEEK_SET;
1257 f_lock.l_start = 0;
1258 f_lock.l_len = 0;
1260 if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
1261 return 0;
1263 /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
1264 if (b && errno == EBADF) {
1265 f_lock.l_type = F_RDLCK;
1266 if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
1267 return 0;
1270 pa_log("%slock: %s", !b ? "un" : "", pa_cstrerror(errno));
1271 #endif
1273 #ifdef OS_IS_WIN32
1274 HANDLE h = (HANDLE) _get_osfhandle(fd);
1276 if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1277 return 0;
1278 if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1279 return 0;
1281 pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError());
1283 /* FIXME: Needs to set errno! */
1284 #endif
1286 return -1;
1289 /* Remove trailing newlines from a string */
1290 char* pa_strip_nl(char *s) {
1291 pa_assert(s);
1293 s[strcspn(s, NEWLINE)] = 0;
1294 return s;
1297 char *pa_strip(char *s) {
1298 char *e, *l = NULL;
1300 /* Drops trailing whitespace. Modifies the string in
1301 * place. Returns pointer to first non-space character */
1303 s += strspn(s, WHITESPACE);
1305 for (e = s; *e; e++)
1306 if (!strchr(WHITESPACE, *e))
1307 l = e;
1309 if (l)
1310 *(l+1) = 0;
1311 else
1312 *s = 0;
1314 return s;
1317 /* Create a temporary lock file and lock it. */
1318 int pa_lock_lockfile(const char *fn) {
1319 int fd;
1320 pa_assert(fn);
1322 for (;;) {
1323 struct stat st;
1325 if ((fd = pa_open_cloexec(fn, O_CREAT|O_RDWR
1326 #ifdef O_NOFOLLOW
1327 |O_NOFOLLOW
1328 #endif
1329 , S_IRUSR|S_IWUSR)) < 0) {
1330 pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno));
1331 goto fail;
1334 if (pa_lock_fd(fd, 1) < 0) {
1335 pa_log_warn("Failed to lock file '%s'.", fn);
1336 goto fail;
1339 if (fstat(fd, &st) < 0) {
1340 pa_log_warn("Failed to fstat() file '%s': %s", fn, pa_cstrerror(errno));
1341 goto fail;
1344 /* Check whether the file has been removed meanwhile. When yes,
1345 * restart this loop, otherwise, we're done */
1346 if (st.st_nlink >= 1)
1347 break;
1349 if (pa_lock_fd(fd, 0) < 0) {
1350 pa_log_warn("Failed to unlock file '%s'.", fn);
1351 goto fail;
1354 if (pa_close(fd) < 0) {
1355 pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno));
1356 fd = -1;
1357 goto fail;
1361 return fd;
1363 fail:
1365 if (fd >= 0) {
1366 int saved_errno = errno;
1367 pa_close(fd);
1368 errno = saved_errno;
1371 return -1;
1374 /* Unlock a temporary lock file */
1375 int pa_unlock_lockfile(const char *fn, int fd) {
1376 int r = 0;
1377 pa_assert(fd >= 0);
1379 if (fn) {
1380 if (unlink(fn) < 0) {
1381 pa_log_warn("Unable to remove lock file '%s': %s", fn, pa_cstrerror(errno));
1382 r = -1;
1386 if (pa_lock_fd(fd, 0) < 0) {
1387 pa_log_warn("Failed to unlock file '%s'.", fn);
1388 r = -1;
1391 if (pa_close(fd) < 0) {
1392 pa_log_warn("Failed to close '%s': %s", fn, pa_cstrerror(errno));
1393 r = -1;
1396 return r;
1399 static char *get_config_home(char *home) {
1400 char *t;
1402 t = getenv("XDG_CONFIG_HOME");
1403 if (t)
1404 return pa_xstrdup(t);
1406 return pa_sprintf_malloc("%s" PA_PATH_SEP ".config", home);
1409 static int check_ours(const char *p) {
1410 struct stat st;
1412 pa_assert(p);
1414 if (stat(p, &st) < 0)
1415 return -errno;
1417 #ifdef HAVE_GETUID
1418 if (st.st_uid != getuid())
1419 return -EACCES;
1420 #endif
1422 return 0;
1425 static char *get_pulse_home(void) {
1426 char *h, *ret, *config_home;
1427 int t;
1429 h = pa_get_home_dir_malloc();
1430 if (!h) {
1431 pa_log_error("Failed to get home directory.");
1432 return NULL;
1435 t = check_ours(h);
1436 if (t < 0 && t != -ENOENT) {
1437 pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t));
1438 pa_xfree(h);
1439 return NULL;
1442 /* If the old directory exists, use it. */
1443 ret = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
1444 if (access(ret, F_OK) >= 0) {
1445 free(h);
1446 return ret;
1448 free(ret);
1450 /* Otherwise go for the XDG compliant directory. */
1451 config_home = get_config_home(h);
1452 free(h);
1453 ret = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", config_home);
1454 free(config_home);
1456 return ret;
1459 char *pa_get_state_dir(void) {
1460 char *d;
1462 /* The state directory shall contain dynamic data that should be
1463 * kept across reboots, and is private to this user */
1465 if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1466 if (!(d = get_pulse_home()))
1467 return NULL;
1469 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1470 * dir then this will break. */
1472 if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0) {
1473 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1474 pa_xfree(d);
1475 return NULL;
1478 return d;
1481 char *pa_get_home_dir_malloc(void) {
1482 char *homedir;
1483 size_t allocated = 128;
1485 for (;;) {
1486 homedir = pa_xmalloc(allocated);
1488 if (!pa_get_home_dir(homedir, allocated)) {
1489 pa_xfree(homedir);
1490 return NULL;
1493 if (strlen(homedir) < allocated - 1)
1494 break;
1496 pa_xfree(homedir);
1497 allocated *= 2;
1500 return homedir;
1503 char *pa_get_binary_name_malloc(void) {
1504 char *t;
1505 size_t allocated = 128;
1507 for (;;) {
1508 t = pa_xmalloc(allocated);
1510 if (!pa_get_binary_name(t, allocated)) {
1511 pa_xfree(t);
1512 return NULL;
1515 if (strlen(t) < allocated - 1)
1516 break;
1518 pa_xfree(t);
1519 allocated *= 2;
1522 return t;
1525 static char* make_random_dir(mode_t m) {
1526 static const char table[] =
1527 "abcdefghijklmnopqrstuvwxyz"
1528 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1529 "0123456789";
1531 char *fn;
1532 size_t pathlen;
1534 fn = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1535 pathlen = strlen(fn);
1537 for (;;) {
1538 size_t i;
1539 int r;
1540 mode_t u;
1541 int saved_errno;
1543 for (i = pathlen - 12; i < pathlen; i++)
1544 fn[i] = table[rand() % (sizeof(table)-1)];
1546 u = umask((~m) & 0777);
1547 #ifndef OS_IS_WIN32
1548 r = mkdir(fn, m);
1549 #else
1550 r = mkdir(fn);
1551 #endif
1553 saved_errno = errno;
1554 umask(u);
1555 errno = saved_errno;
1557 if (r >= 0)
1558 return fn;
1560 if (errno != EEXIST) {
1561 pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
1562 pa_xfree(fn);
1563 return NULL;
1568 static int make_random_dir_and_link(mode_t m, const char *k) {
1569 char *p;
1571 if (!(p = make_random_dir(m)))
1572 return -1;
1574 #ifdef HAVE_SYMLINK
1575 if (symlink(p, k) < 0) {
1576 int saved_errno = errno;
1578 if (errno != EEXIST)
1579 pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno));
1581 rmdir(p);
1582 pa_xfree(p);
1584 errno = saved_errno;
1585 return -1;
1587 #else
1588 pa_xfree(p);
1589 return -1;
1590 #endif
1592 pa_xfree(p);
1593 return 0;
1596 char *pa_get_runtime_dir(void) {
1597 char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
1598 mode_t m;
1600 /* The runtime directory shall contain dynamic data that needs NOT
1601 * to be kept across reboots and is usually private to the user,
1602 * except in system mode, where it might be accessible by other
1603 * users, too. Since we need POSIX locking and UNIX sockets in
1604 * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
1605 * set create a directory in $HOME and link it to a random subdir
1606 * in /tmp, if it was not explicitly configured. */
1608 m = pa_in_system_mode() ? 0755U : 0700U;
1610 /* Use the explicitly configured value if it is set */
1611 d = getenv("PULSE_RUNTIME_PATH");
1612 if (d) {
1614 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
1615 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1616 goto fail;
1619 return pa_xstrdup(d);
1622 /* Use the XDG standard for the runtime directory. */
1623 d = getenv("XDG_RUNTIME_DIR");
1624 if (d) {
1625 k = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", d);
1627 if (pa_make_secure_dir(k, m, (uid_t) -1, (gid_t) -1) < 0) {
1628 free(k);
1629 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1630 goto fail;
1633 return k;
1636 /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
1637 d = get_pulse_home();
1638 if (!d)
1639 goto fail;
1641 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
1642 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1643 pa_xfree(d);
1644 goto fail;
1647 mid = pa_machine_id();
1648 if (!mid) {
1649 pa_xfree(d);
1650 goto fail;
1653 k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-runtime", d, mid);
1654 pa_xfree(d);
1655 pa_xfree(mid);
1657 for (;;) {
1658 /* OK, first let's check if the "runtime" symlink already exists */
1660 p = pa_readlink(k);
1661 if (!p) {
1663 if (errno != ENOENT) {
1664 pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
1665 goto fail;
1668 #ifdef HAVE_SYMLINK
1669 /* Hmm, so the runtime directory didn't exist yet, so let's
1670 * create one in /tmp and symlink that to it */
1672 if (make_random_dir_and_link(0700, k) < 0) {
1674 /* Mhmm, maybe another process was quicker than us,
1675 * let's check if that was valid */
1676 if (errno == EEXIST)
1677 continue;
1679 goto fail;
1681 #else
1682 /* No symlink possible, so let's just create the runtime directly */
1683 if (mkdir(k) < 0)
1684 goto fail;
1685 #endif
1687 return k;
1690 /* Make sure that this actually makes sense */
1691 if (!pa_is_path_absolute(p)) {
1692 pa_log_error("Path %s in link %s is not absolute.", p, k);
1693 errno = ENOENT;
1694 goto fail;
1697 /* Hmm, so this symlink is still around, make sure nobody fools us */
1698 #ifdef HAVE_LSTAT
1700 struct stat st;
1701 if (lstat(p, &st) < 0) {
1703 if (errno != ENOENT) {
1704 pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno));
1705 goto fail;
1708 } else {
1710 if (S_ISDIR(st.st_mode) &&
1711 (st.st_uid == getuid()) &&
1712 ((st.st_mode & 0777) == 0700)) {
1714 pa_xfree(p);
1715 return k;
1718 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1721 #endif
1723 pa_xfree(p);
1724 p = NULL;
1726 /* Hmm, so the link points to some nonexisting or invalid
1727 * dir. Let's replace it by a new link. We first create a
1728 * temporary link and then rename that to allow concurrent
1729 * execution of this function. */
1731 t = pa_sprintf_malloc("%s.tmp", k);
1733 if (make_random_dir_and_link(0700, t) < 0) {
1735 if (errno != EEXIST) {
1736 pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno));
1737 goto fail;
1740 pa_xfree(t);
1741 t = NULL;
1743 /* Hmm, someone else was quicker then us. Let's give
1744 * him some time to finish, and retry. */
1745 pa_msleep(10);
1746 continue;
1749 /* OK, we succeeded in creating the temporary symlink, so
1750 * let's rename it */
1751 if (rename(t, k) < 0) {
1752 pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno));
1753 goto fail;
1756 pa_xfree(t);
1757 return k;
1760 fail:
1761 pa_xfree(p);
1762 pa_xfree(k);
1763 pa_xfree(t);
1765 return NULL;
1768 /* Try to open a configuration file. If "env" is specified, open the
1769 * value of the specified environment variable. Otherwise look for a
1770 * file "local" in the home directory or a file "global" in global
1771 * file system. If "result" is non-NULL, a pointer to a newly
1772 * allocated buffer containing the used configuration file is
1773 * stored there.*/
1774 FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
1775 const char *fn;
1776 FILE *f;
1778 if (env && (fn = getenv(env))) {
1779 if ((f = pa_fopen_cloexec(fn, "r"))) {
1780 if (result)
1781 *result = pa_xstrdup(fn);
1783 return f;
1786 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1787 return NULL;
1790 if (local) {
1791 const char *e;
1792 char *lfn;
1793 char *h;
1795 if ((e = getenv("PULSE_CONFIG_PATH"))) {
1796 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1797 f = pa_fopen_cloexec(fn, "r");
1798 } else if ((h = pa_get_home_dir_malloc())) {
1799 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1800 f = pa_fopen_cloexec(fn, "r");
1801 if (!f) {
1802 free(lfn);
1803 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".config/pulse" PA_PATH_SEP "%s", h, local);
1804 f = pa_fopen_cloexec(fn, "r");
1806 pa_xfree(h);
1807 } else
1808 return NULL;
1810 if (f) {
1811 if (result)
1812 *result = pa_xstrdup(fn);
1814 pa_xfree(lfn);
1815 return f;
1818 if (errno != ENOENT) {
1819 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1820 pa_xfree(lfn);
1821 return NULL;
1824 pa_xfree(lfn);
1827 if (global) {
1828 char *gfn;
1830 #ifdef OS_IS_WIN32
1831 if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
1832 gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
1833 pa_win32_get_toplevel(NULL),
1834 global + strlen(PA_DEFAULT_CONFIG_DIR));
1835 else
1836 #endif
1837 gfn = pa_xstrdup(global);
1839 if ((f = pa_fopen_cloexec(gfn, "r"))) {
1840 if (result)
1841 *result = gfn;
1842 else
1843 pa_xfree(gfn);
1845 return f;
1847 pa_xfree(gfn);
1850 errno = ENOENT;
1851 return NULL;
1854 char *pa_find_config_file(const char *global, const char *local, const char *env) {
1855 const char *fn;
1857 if (env && (fn = getenv(env))) {
1858 if (access(fn, R_OK) == 0)
1859 return pa_xstrdup(fn);
1861 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1862 return NULL;
1865 if (local) {
1866 const char *e;
1867 char *lfn;
1868 char *h;
1870 if ((e = getenv("PULSE_CONFIG_PATH")))
1871 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1872 else if ((h = pa_get_home_dir_malloc())) {
1873 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1874 pa_xfree(h);
1875 } else
1876 return NULL;
1878 if (access(fn, R_OK) == 0) {
1879 char *r = pa_xstrdup(fn);
1880 pa_xfree(lfn);
1881 return r;
1884 if (errno != ENOENT) {
1885 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1886 pa_xfree(lfn);
1887 return NULL;
1890 pa_xfree(lfn);
1893 if (global) {
1894 char *gfn;
1896 #ifdef OS_IS_WIN32
1897 if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
1898 gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
1899 pa_win32_get_toplevel(NULL),
1900 global + strlen(PA_DEFAULT_CONFIG_DIR));
1901 else
1902 #endif
1903 gfn = pa_xstrdup(global);
1905 if (access(gfn, R_OK) == 0)
1906 return gfn;
1907 pa_xfree(gfn);
1910 errno = ENOENT;
1912 return NULL;
1915 /* Format the specified data as a hexademical string */
1916 char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {
1917 size_t i = 0, j = 0;
1918 const char hex[] = "0123456789abcdef";
1920 pa_assert(d);
1921 pa_assert(s);
1922 pa_assert(slength > 0);
1924 while (j+2 < slength && i < dlength) {
1925 s[j++] = hex[*d >> 4];
1926 s[j++] = hex[*d & 0xF];
1928 d++;
1929 i++;
1932 s[j < slength ? j : slength] = 0;
1933 return s;
1936 /* Convert a hexadecimal digit to a number or -1 if invalid */
1937 static int hexc(char c) {
1938 if (c >= '0' && c <= '9')
1939 return c - '0';
1941 if (c >= 'A' && c <= 'F')
1942 return c - 'A' + 10;
1944 if (c >= 'a' && c <= 'f')
1945 return c - 'a' + 10;
1947 errno = EINVAL;
1948 return -1;
1951 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1952 size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) {
1953 size_t j = 0;
1955 pa_assert(p);
1956 pa_assert(d);
1958 while (j < dlength && *p) {
1959 int b;
1961 if ((b = hexc(*(p++))) < 0)
1962 return (size_t) -1;
1964 d[j] = (uint8_t) (b << 4);
1966 if (!*p)
1967 return (size_t) -1;
1969 if ((b = hexc(*(p++))) < 0)
1970 return (size_t) -1;
1972 d[j] |= (uint8_t) b;
1973 j++;
1976 return j;
1979 /* Returns nonzero when *s starts with *pfx */
1980 pa_bool_t pa_startswith(const char *s, const char *pfx) {
1981 size_t l;
1983 pa_assert(s);
1984 pa_assert(pfx);
1986 l = strlen(pfx);
1988 return strlen(s) >= l && strncmp(s, pfx, l) == 0;
1991 /* Returns nonzero when *s ends with *sfx */
1992 pa_bool_t pa_endswith(const char *s, const char *sfx) {
1993 size_t l1, l2;
1995 pa_assert(s);
1996 pa_assert(sfx);
1998 l1 = strlen(s);
1999 l2 = strlen(sfx);
2001 return l1 >= l2 && pa_streq(s + l1 - l2, sfx);
2004 pa_bool_t pa_is_path_absolute(const char *fn) {
2005 pa_assert(fn);
2007 #ifndef OS_IS_WIN32
2008 return *fn == '/';
2009 #else
2010 return strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\';
2011 #endif
2014 char *pa_make_path_absolute(const char *p) {
2015 char *r;
2016 char *cwd;
2018 pa_assert(p);
2020 if (pa_is_path_absolute(p))
2021 return pa_xstrdup(p);
2023 if (!(cwd = pa_getcwd()))
2024 return pa_xstrdup(p);
2026 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", cwd, p);
2027 pa_xfree(cwd);
2028 return r;
2031 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
2032 * if fn is non-null and starts with / return fn
2033 * otherwise append fn to the run time path and return it */
2034 static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {
2035 char *rtp;
2037 rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
2039 if (fn) {
2040 char *r, *canonical_rtp;
2042 if (pa_is_path_absolute(fn)) {
2043 pa_xfree(rtp);
2044 return pa_xstrdup(fn);
2047 if (!rtp)
2048 return NULL;
2050 /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
2051 if ((canonical_rtp = pa_realpath(rtp))) {
2052 if (strlen(rtp) >= strlen(canonical_rtp))
2053 pa_xfree(rtp);
2054 else {
2055 pa_xfree(canonical_rtp);
2056 canonical_rtp = rtp;
2058 } else
2059 canonical_rtp = rtp;
2061 if (prependmid) {
2062 char *mid;
2064 if (!(mid = pa_machine_id())) {
2065 pa_xfree(canonical_rtp);
2066 return NULL;
2069 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-%s", canonical_rtp, mid, fn);
2070 pa_xfree(mid);
2071 } else
2072 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", canonical_rtp, fn);
2074 pa_xfree(canonical_rtp);
2075 return r;
2076 } else
2077 return rtp;
2080 char *pa_runtime_path(const char *fn) {
2081 return get_path(fn, FALSE, TRUE);
2084 char *pa_state_path(const char *fn, pa_bool_t appendmid) {
2085 return get_path(fn, appendmid, FALSE);
2088 /* Convert the string s to a signed integer in *ret_i */
2089 int pa_atoi(const char *s, int32_t *ret_i) {
2090 long l;
2092 pa_assert(s);
2093 pa_assert(ret_i);
2095 if (pa_atol(s, &l) < 0)
2096 return -1;
2098 if ((int32_t) l != l) {
2099 errno = ERANGE;
2100 return -1;
2103 *ret_i = (int32_t) l;
2105 return 0;
2108 /* Convert the string s to an unsigned integer in *ret_u */
2109 int pa_atou(const char *s, uint32_t *ret_u) {
2110 char *x = NULL;
2111 unsigned long l;
2113 pa_assert(s);
2114 pa_assert(ret_u);
2116 errno = 0;
2117 l = strtoul(s, &x, 0);
2119 if (!x || *x || errno) {
2120 if (!errno)
2121 errno = EINVAL;
2122 return -1;
2125 if ((uint32_t) l != l) {
2126 errno = ERANGE;
2127 return -1;
2130 *ret_u = (uint32_t) l;
2132 return 0;
2135 /* Convert the string s to a signed long integer in *ret_l. */
2136 int pa_atol(const char *s, long *ret_l) {
2137 char *x = NULL;
2138 long l;
2140 pa_assert(s);
2141 pa_assert(ret_l);
2143 errno = 0;
2144 l = strtol(s, &x, 0);
2146 if (!x || *x || errno) {
2147 if (!errno)
2148 errno = EINVAL;
2149 return -1;
2152 *ret_l = l;
2154 return 0;
2157 #ifdef HAVE_STRTOF_L
2158 static locale_t c_locale = NULL;
2160 static void c_locale_destroy(void) {
2161 freelocale(c_locale);
2163 #endif
2165 int pa_atod(const char *s, double *ret_d) {
2166 char *x = NULL;
2167 double f;
2169 pa_assert(s);
2170 pa_assert(ret_d);
2172 /* This should be locale independent */
2174 #ifdef HAVE_STRTOF_L
2176 PA_ONCE_BEGIN {
2178 if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL)))
2179 atexit(c_locale_destroy);
2181 } PA_ONCE_END;
2183 if (c_locale) {
2184 errno = 0;
2185 f = strtod_l(s, &x, c_locale);
2186 } else
2187 #endif
2189 errno = 0;
2190 f = strtod(s, &x);
2193 if (!x || *x || errno) {
2194 if (!errno)
2195 errno = EINVAL;
2196 return -1;
2199 *ret_d = f;
2201 return 0;
2204 /* Same as snprintf, but guarantees NUL-termination on every platform */
2205 size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
2206 size_t ret;
2207 va_list ap;
2209 pa_assert(str);
2210 pa_assert(size > 0);
2211 pa_assert(format);
2213 va_start(ap, format);
2214 ret = pa_vsnprintf(str, size, format, ap);
2215 va_end(ap);
2217 return ret;
2220 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2221 size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
2222 int ret;
2224 pa_assert(str);
2225 pa_assert(size > 0);
2226 pa_assert(format);
2228 ret = vsnprintf(str, size, format, ap);
2230 str[size-1] = 0;
2232 if (ret < 0)
2233 return strlen(str);
2235 if ((size_t) ret > size-1)
2236 return size-1;
2238 return (size_t) ret;
2241 /* Truncate the specified string, but guarantee that the string
2242 * returned still validates as UTF8 */
2243 char *pa_truncate_utf8(char *c, size_t l) {
2244 pa_assert(c);
2245 pa_assert(pa_utf8_valid(c));
2247 if (strlen(c) <= l)
2248 return c;
2250 c[l] = 0;
2252 while (l > 0 && !pa_utf8_valid(c))
2253 c[--l] = 0;
2255 return c;
2258 char *pa_getcwd(void) {
2259 size_t l = 128;
2261 for (;;) {
2262 char *p = pa_xmalloc(l);
2263 if (getcwd(p, l))
2264 return p;
2266 if (errno != ERANGE)
2267 return NULL;
2269 pa_xfree(p);
2270 l *= 2;
2274 void *pa_will_need(const void *p, size_t l) {
2275 #ifdef RLIMIT_MEMLOCK
2276 struct rlimit rlim;
2277 #endif
2278 const void *a;
2279 size_t size;
2280 int r = ENOTSUP;
2281 size_t bs;
2283 pa_assert(p);
2284 pa_assert(l > 0);
2286 a = PA_PAGE_ALIGN_PTR(p);
2287 size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
2289 #ifdef HAVE_POSIX_MADVISE
2290 if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
2291 pa_log_debug("posix_madvise() worked fine!");
2292 return (void*) p;
2294 #endif
2296 /* Most likely the memory was not mmap()ed from a file and thus
2297 * madvise() didn't work, so let's misuse mlock() do page this
2298 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2299 * inviting, the man page of mlock() tells us: "All pages that
2300 * contain a part of the specified address range are guaranteed to
2301 * be resident in RAM when the call returns successfully." */
2303 #ifdef RLIMIT_MEMLOCK
2304 pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
2306 if (rlim.rlim_cur < PA_PAGE_SIZE) {
2307 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));
2308 errno = EPERM;
2309 return (void*) p;
2312 bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
2313 #else
2314 bs = PA_PAGE_SIZE*4;
2315 #endif
2317 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r));
2319 #ifdef HAVE_MLOCK
2320 while (size > 0 && bs > 0) {
2322 if (bs > size)
2323 bs = size;
2325 if (mlock(a, bs) < 0) {
2326 bs = PA_PAGE_ALIGN(bs / 2);
2327 continue;
2330 pa_assert_se(munlock(a, bs) == 0);
2332 a = (const uint8_t*) a + bs;
2333 size -= bs;
2335 #endif
2337 if (bs <= 0)
2338 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno));
2339 else
2340 pa_log_debug("mlock() worked fine!");
2342 return (void*) p;
2345 void pa_close_pipe(int fds[2]) {
2346 pa_assert(fds);
2348 if (fds[0] >= 0)
2349 pa_assert_se(pa_close(fds[0]) == 0);
2351 if (fds[1] >= 0)
2352 pa_assert_se(pa_close(fds[1]) == 0);
2354 fds[0] = fds[1] = -1;
2357 char *pa_readlink(const char *p) {
2358 #ifdef HAVE_READLINK
2359 size_t l = 100;
2361 for (;;) {
2362 char *c;
2363 ssize_t n;
2365 c = pa_xmalloc(l);
2367 if ((n = readlink(p, c, l-1)) < 0) {
2368 pa_xfree(c);
2369 return NULL;
2372 if ((size_t) n < l-1) {
2373 c[n] = 0;
2374 return c;
2377 pa_xfree(c);
2378 l *= 2;
2380 #else
2381 return NULL;
2382 #endif
2385 int pa_close_all(int except_fd, ...) {
2386 va_list ap;
2387 unsigned n = 0, i;
2388 int r, *p;
2390 va_start(ap, except_fd);
2392 if (except_fd >= 0)
2393 for (n = 1; va_arg(ap, int) >= 0; n++)
2396 va_end(ap);
2398 p = pa_xnew(int, n+1);
2400 va_start(ap, except_fd);
2402 i = 0;
2403 if (except_fd >= 0) {
2404 int fd;
2405 p[i++] = except_fd;
2407 while ((fd = va_arg(ap, int)) >= 0)
2408 p[i++] = fd;
2410 p[i] = -1;
2412 va_end(ap);
2414 r = pa_close_allv(p);
2415 pa_xfree(p);
2417 return r;
2420 int pa_close_allv(const int except_fds[]) {
2421 #ifndef OS_IS_WIN32
2422 struct rlimit rl;
2423 int maxfd, fd;
2425 #ifdef __linux__
2426 int saved_errno;
2427 DIR *d;
2429 if ((d = opendir("/proc/self/fd"))) {
2431 struct dirent *de;
2433 while ((de = readdir(d))) {
2434 pa_bool_t found;
2435 long l;
2436 char *e = NULL;
2437 int i;
2439 if (de->d_name[0] == '.')
2440 continue;
2442 errno = 0;
2443 l = strtol(de->d_name, &e, 10);
2444 if (errno != 0 || !e || *e) {
2445 closedir(d);
2446 errno = EINVAL;
2447 return -1;
2450 fd = (int) l;
2452 if ((long) fd != l) {
2453 closedir(d);
2454 errno = EINVAL;
2455 return -1;
2458 if (fd < 3)
2459 continue;
2461 if (fd == dirfd(d))
2462 continue;
2464 found = FALSE;
2465 for (i = 0; except_fds[i] >= 0; i++)
2466 if (except_fds[i] == fd) {
2467 found = TRUE;
2468 break;
2471 if (found)
2472 continue;
2474 if (pa_close(fd) < 0) {
2475 saved_errno = errno;
2476 closedir(d);
2477 errno = saved_errno;
2479 return -1;
2483 closedir(d);
2484 return 0;
2487 #endif
2489 if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
2490 maxfd = (int) rl.rlim_max;
2491 else
2492 maxfd = sysconf(_SC_OPEN_MAX);
2494 for (fd = 3; fd < maxfd; fd++) {
2495 int i;
2496 pa_bool_t found;
2498 found = FALSE;
2499 for (i = 0; except_fds[i] >= 0; i++)
2500 if (except_fds[i] == fd) {
2501 found = TRUE;
2502 break;
2505 if (found)
2506 continue;
2508 if (pa_close(fd) < 0 && errno != EBADF)
2509 return -1;
2511 #endif /* !OS_IS_WIN32 */
2513 return 0;
2516 int pa_unblock_sigs(int except, ...) {
2517 va_list ap;
2518 unsigned n = 0, i;
2519 int r, *p;
2521 va_start(ap, except);
2523 if (except >= 1)
2524 for (n = 1; va_arg(ap, int) >= 0; n++)
2527 va_end(ap);
2529 p = pa_xnew(int, n+1);
2531 va_start(ap, except);
2533 i = 0;
2534 if (except >= 1) {
2535 int sig;
2536 p[i++] = except;
2538 while ((sig = va_arg(ap, int)) >= 0)
2539 p[i++] = sig;
2541 p[i] = -1;
2543 va_end(ap);
2545 r = pa_unblock_sigsv(p);
2546 pa_xfree(p);
2548 return r;
2551 int pa_unblock_sigsv(const int except[]) {
2552 #ifndef OS_IS_WIN32
2553 int i;
2554 sigset_t ss;
2556 if (sigemptyset(&ss) < 0)
2557 return -1;
2559 for (i = 0; except[i] > 0; i++)
2560 if (sigaddset(&ss, except[i]) < 0)
2561 return -1;
2563 return sigprocmask(SIG_SETMASK, &ss, NULL);
2564 #else
2565 return 0;
2566 #endif
2569 int pa_reset_sigs(int except, ...) {
2570 va_list ap;
2571 unsigned n = 0, i;
2572 int *p, r;
2574 va_start(ap, except);
2576 if (except >= 1)
2577 for (n = 1; va_arg(ap, int) >= 0; n++)
2580 va_end(ap);
2582 p = pa_xnew(int, n+1);
2584 va_start(ap, except);
2586 i = 0;
2587 if (except >= 1) {
2588 int sig;
2589 p[i++] = except;
2591 while ((sig = va_arg(ap, int)) >= 0)
2592 p[i++] = sig;
2594 p[i] = -1;
2596 va_end(ap);
2598 r = pa_reset_sigsv(p);
2599 pa_xfree(p);
2601 return r;
2604 int pa_reset_sigsv(const int except[]) {
2605 #ifndef OS_IS_WIN32
2606 int sig;
2608 for (sig = 1; sig < NSIG; sig++) {
2609 pa_bool_t reset = TRUE;
2611 switch (sig) {
2612 case SIGKILL:
2613 case SIGSTOP:
2614 reset = FALSE;
2615 break;
2617 default: {
2618 int i;
2620 for (i = 0; except[i] > 0; i++) {
2621 if (sig == except[i]) {
2622 reset = FALSE;
2623 break;
2629 if (reset) {
2630 struct sigaction sa;
2632 memset(&sa, 0, sizeof(sa));
2633 sa.sa_handler = SIG_DFL;
2635 /* On Linux the first two RT signals are reserved by
2636 * glibc, and sigaction() will return EINVAL for them. */
2637 if ((sigaction(sig, &sa, NULL) < 0))
2638 if (errno != EINVAL)
2639 return -1;
2642 #endif
2644 return 0;
2647 void pa_set_env(const char *key, const char *value) {
2648 pa_assert(key);
2649 pa_assert(value);
2651 /* This is not thread-safe */
2653 #ifdef OS_IS_WIN32
2654 SetEnvironmentVariable(key, value);
2655 #else
2656 setenv(key, value, 1);
2657 #endif
2660 void pa_set_env_and_record(const char *key, const char *value) {
2661 pa_assert(key);
2662 pa_assert(value);
2664 /* This is not thread-safe */
2666 pa_set_env(key, value);
2667 recorded_env = pa_strlist_prepend(recorded_env, key);
2670 void pa_unset_env_recorded(void) {
2672 /* This is not thread-safe */
2674 for (;;) {
2675 char *s;
2677 recorded_env = pa_strlist_pop(recorded_env, &s);
2679 if (!s)
2680 break;
2682 #ifdef OS_IS_WIN32
2683 SetEnvironmentVariable(s, NULL);
2684 #else
2685 unsetenv(s);
2686 #endif
2687 pa_xfree(s);
2691 pa_bool_t pa_in_system_mode(void) {
2692 const char *e;
2694 if (!(e = getenv("PULSE_SYSTEM")))
2695 return FALSE;
2697 return !!atoi(e);
2700 /* Checks a whitespace-separated list of words in haystack for needle */
2701 pa_bool_t pa_str_in_list_spaces(const char *haystack, const char *needle) {
2702 char *s;
2703 const char *state = NULL;
2705 if (!haystack || !needle)
2706 return FALSE;
2708 while ((s = pa_split_spaces(haystack, &state))) {
2709 if (pa_streq(needle, s)) {
2710 pa_xfree(s);
2711 return TRUE;
2714 pa_xfree(s);
2717 return FALSE;
2720 char *pa_get_user_name_malloc(void) {
2721 ssize_t k;
2722 char *u;
2724 #ifdef _SC_LOGIN_NAME_MAX
2725 k = (ssize_t) sysconf(_SC_LOGIN_NAME_MAX);
2727 if (k <= 0)
2728 #endif
2729 k = 32;
2731 u = pa_xnew(char, k+1);
2733 if (!(pa_get_user_name(u, k))) {
2734 pa_xfree(u);
2735 return NULL;
2738 return u;
2741 char *pa_get_host_name_malloc(void) {
2742 size_t l;
2744 l = 100;
2745 for (;;) {
2746 char *c;
2748 c = pa_xmalloc(l);
2750 if (!pa_get_host_name(c, l)) {
2752 if (errno != EINVAL && errno != ENAMETOOLONG)
2753 break;
2755 } else if (strlen(c) < l-1) {
2756 char *u;
2758 if (*c == 0) {
2759 pa_xfree(c);
2760 break;
2763 u = pa_utf8_filter(c);
2764 pa_xfree(c);
2765 return u;
2768 /* Hmm, the hostname is as long the space we offered the
2769 * function, we cannot know if it fully fit in, so let's play
2770 * safe and retry. */
2772 pa_xfree(c);
2773 l *= 2;
2776 return NULL;
2779 char *pa_machine_id(void) {
2780 FILE *f;
2781 char *h;
2783 /* The returned value is supposed be some kind of ascii identifier
2784 * that is unique and stable across reboots. */
2786 /* First we try the /etc/machine-id, which is the best option we
2787 * have, since it fits perfectly our needs and is not as volatile
2788 * as the hostname which might be set from dhcp. */
2790 if ((f = pa_fopen_cloexec(PA_MACHINE_ID, "r")) ||
2791 (f = pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK, "r"))) {
2792 char ln[34] = "", *r;
2794 r = fgets(ln, sizeof(ln)-1, f);
2795 fclose(f);
2797 pa_strip_nl(ln);
2799 if (r && ln[0])
2800 return pa_utf8_filter(ln);
2803 if ((h = pa_get_host_name_malloc()))
2804 return h;
2806 #ifndef OS_IS_WIN32
2807 /* If no hostname was set we use the POSIX hostid. It's usually
2808 * the IPv4 address. Might not be that stable. */
2809 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
2810 #else
2811 return NULL;
2812 #endif
2815 char *pa_session_id(void) {
2816 const char *e;
2818 e = getenv("XDG_SESSION_ID");
2819 if (!e)
2820 return NULL;
2822 return pa_utf8_filter(e);
2825 char *pa_uname_string(void) {
2826 #ifdef HAVE_UNAME
2827 struct utsname u;
2829 pa_assert_se(uname(&u) >= 0);
2831 return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
2832 #endif
2833 #ifdef OS_IS_WIN32
2834 OSVERSIONINFO i;
2836 pa_zero(i);
2837 i.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
2838 pa_assert_se(GetVersionEx(&i));
2840 return pa_sprintf_malloc("Windows %d.%d (%d) %s", i.dwMajorVersion, i.dwMinorVersion, i.dwBuildNumber, i.szCSDVersion);
2841 #endif
2844 #ifdef HAVE_VALGRIND_MEMCHECK_H
2845 pa_bool_t pa_in_valgrind(void) {
2846 static int b = 0;
2848 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
2849 * here instead of really checking whether we run in valgrind or
2850 * not. */
2852 if (b < 1)
2853 b = getenv("VALGRIND") ? 2 : 1;
2855 return b > 1;
2857 #endif
2859 unsigned pa_gcd(unsigned a, unsigned b) {
2861 while (b > 0) {
2862 unsigned t = b;
2863 b = a % b;
2864 a = t;
2867 return a;
2870 void pa_reduce(unsigned *num, unsigned *den) {
2872 unsigned gcd = pa_gcd(*num, *den);
2874 if (gcd <= 0)
2875 return;
2877 *num /= gcd;
2878 *den /= gcd;
2880 pa_assert(pa_gcd(*num, *den) == 1);
2883 unsigned pa_ncpus(void) {
2884 long ncpus;
2886 #ifdef _SC_NPROCESSORS_CONF
2887 ncpus = sysconf(_SC_NPROCESSORS_CONF);
2888 #else
2889 ncpus = 1;
2890 #endif
2892 return ncpus <= 0 ? 1 : (unsigned) ncpus;
2895 char *pa_replace(const char*s, const char*a, const char *b) {
2896 pa_strbuf *sb;
2897 size_t an;
2899 pa_assert(s);
2900 pa_assert(a);
2901 pa_assert(b);
2903 an = strlen(a);
2904 sb = pa_strbuf_new();
2906 for (;;) {
2907 const char *p;
2909 if (!(p = strstr(s, a)))
2910 break;
2912 pa_strbuf_putsn(sb, s, p-s);
2913 pa_strbuf_puts(sb, b);
2914 s = p + an;
2917 pa_strbuf_puts(sb, s);
2919 return pa_strbuf_tostring_free(sb);
2922 char *pa_escape(const char *p, const char *chars) {
2923 const char *s;
2924 const char *c;
2925 pa_strbuf *buf = pa_strbuf_new();
2927 for (s = p; *s; ++s) {
2928 if (*s == '\\')
2929 pa_strbuf_putc(buf, '\\');
2930 else if (chars) {
2931 for (c = chars; *c; ++c) {
2932 if (*s == *c) {
2933 pa_strbuf_putc(buf, '\\');
2934 break;
2938 pa_strbuf_putc(buf, *s);
2941 return pa_strbuf_tostring_free(buf);
2944 char *pa_unescape(char *p) {
2945 char *s, *d;
2946 pa_bool_t escaped = FALSE;
2948 for (s = p, d = p; *s; s++) {
2949 if (!escaped && *s == '\\') {
2950 escaped = TRUE;
2951 continue;
2954 *(d++) = *s;
2955 escaped = FALSE;
2958 *d = 0;
2960 return p;
2963 char *pa_realpath(const char *path) {
2964 char *t;
2965 pa_assert(path);
2967 /* We want only absolute paths */
2968 if (path[0] != '/') {
2969 errno = EINVAL;
2970 return NULL;
2973 #if defined(__GLIBC__) || defined(__APPLE__)
2975 char *r;
2977 if (!(r = realpath(path, NULL)))
2978 return NULL;
2980 /* We copy this here in case our pa_xmalloc() is not
2981 * implemented on top of libc malloc() */
2982 t = pa_xstrdup(r);
2983 pa_xfree(r);
2985 #elif defined(PATH_MAX)
2987 char *path_buf;
2988 path_buf = pa_xmalloc(PATH_MAX);
2990 #if defined(OS_IS_WIN32)
2991 if (!(t = _fullpath(path_buf, path, _MAX_PATH))) {
2992 pa_xfree(path_buf);
2993 return NULL;
2995 #else
2996 if (!(t = realpath(path, path_buf))) {
2997 pa_xfree(path_buf);
2998 return NULL;
3000 #endif
3002 #else
3003 #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."
3004 #endif
3006 return t;
3009 void pa_disable_sigpipe(void) {
3011 #ifdef SIGPIPE
3012 struct sigaction sa;
3014 pa_zero(sa);
3016 if (sigaction(SIGPIPE, NULL, &sa) < 0) {
3017 pa_log("sigaction(): %s", pa_cstrerror(errno));
3018 return;
3021 sa.sa_handler = SIG_IGN;
3023 if (sigaction(SIGPIPE, &sa, NULL) < 0) {
3024 pa_log("sigaction(): %s", pa_cstrerror(errno));
3025 return;
3027 #endif
3030 void pa_xfreev(void**a) {
3031 void **p;
3033 if (!a)
3034 return;
3036 for (p = a; *p; p++)
3037 pa_xfree(*p);
3039 pa_xfree(a);
3042 char **pa_split_spaces_strv(const char *s) {
3043 char **t, *e;
3044 unsigned i = 0, n = 8;
3045 const char *state = NULL;
3047 t = pa_xnew(char*, n);
3048 while ((e = pa_split_spaces(s, &state))) {
3049 t[i++] = e;
3051 if (i >= n) {
3052 n *= 2;
3053 t = pa_xrenew(char*, t, n);
3057 if (i <= 0) {
3058 pa_xfree(t);
3059 return NULL;
3062 t[i] = NULL;
3063 return t;
3066 char* pa_maybe_prefix_path(const char *path, const char *prefix) {
3067 pa_assert(path);
3069 if (pa_is_path_absolute(path))
3070 return pa_xstrdup(path);
3072 return pa_sprintf_malloc("%s" PA_PATH_SEP "%s", prefix, path);
3075 size_t pa_pipe_buf(int fd) {
3077 #ifdef _PC_PIPE_BUF
3078 long n;
3080 if ((n = fpathconf(fd, _PC_PIPE_BUF)) >= 0)
3081 return (size_t) n;
3082 #endif
3084 #ifdef PIPE_BUF
3085 return PIPE_BUF;
3086 #else
3087 return 4096;
3088 #endif
3091 void pa_reset_personality(void) {
3093 #ifdef __linux__
3094 if (personality(PER_LINUX) < 0)
3095 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno));
3096 #endif
3100 #if defined(__linux__) && !defined(__OPTIMIZE__)
3102 pa_bool_t pa_run_from_build_tree(void) {
3103 char *rp;
3104 pa_bool_t b = FALSE;
3106 if ((rp = pa_readlink("/proc/self/exe"))) {
3107 b = pa_startswith(rp, PA_BUILDDIR);
3108 pa_xfree(rp);
3111 return b;
3114 #endif
3116 const char *pa_get_temp_dir(void) {
3117 const char *t;
3119 if ((t = getenv("TMPDIR")) &&
3120 pa_is_path_absolute(t))
3121 return t;
3123 if ((t = getenv("TMP")) &&
3124 pa_is_path_absolute(t))
3125 return t;
3127 if ((t = getenv("TEMP")) &&
3128 pa_is_path_absolute(t))
3129 return t;
3131 if ((t = getenv("TEMPDIR")) &&
3132 pa_is_path_absolute(t))
3133 return t;
3135 return "/tmp";
3138 int pa_open_cloexec(const char *fn, int flags, mode_t mode) {
3139 int fd;
3141 #ifdef O_NOCTTY
3142 flags |= O_NOCTTY;
3143 #endif
3145 #ifdef O_CLOEXEC
3146 if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0)
3147 goto finish;
3149 if (errno != EINVAL)
3150 return fd;
3151 #endif
3153 if ((fd = open(fn, flags, mode)) < 0)
3154 return fd;
3156 finish:
3157 /* Some implementations might simply ignore O_CLOEXEC if it is not
3158 * understood, make sure FD_CLOEXEC is enabled anyway */
3160 pa_make_fd_cloexec(fd);
3161 return fd;
3164 int pa_socket_cloexec(int domain, int type, int protocol) {
3165 int fd;
3167 #ifdef SOCK_CLOEXEC
3168 if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0)
3169 goto finish;
3171 if (errno != EINVAL)
3172 return fd;
3173 #endif
3175 if ((fd = socket(domain, type, protocol)) < 0)
3176 return fd;
3178 finish:
3179 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3180 * not understood, make sure FD_CLOEXEC is enabled anyway */
3182 pa_make_fd_cloexec(fd);
3183 return fd;
3186 int pa_pipe_cloexec(int pipefd[2]) {
3187 int r;
3189 #ifdef HAVE_PIPE2
3190 if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0)
3191 goto finish;
3193 if (errno != EINVAL && errno != ENOSYS)
3194 return r;
3196 #endif
3198 if ((r = pipe(pipefd)) < 0)
3199 return r;
3201 finish:
3202 pa_make_fd_cloexec(pipefd[0]);
3203 pa_make_fd_cloexec(pipefd[1]);
3205 return 0;
3208 int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
3209 int fd;
3211 #ifdef HAVE_ACCEPT4
3212 if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0)
3213 goto finish;
3215 if (errno != EINVAL && errno != ENOSYS)
3216 return fd;
3218 #endif
3220 if ((fd = accept(sockfd, addr, addrlen)) < 0)
3221 return fd;
3223 finish:
3224 pa_make_fd_cloexec(fd);
3225 return fd;
3228 FILE* pa_fopen_cloexec(const char *path, const char *mode) {
3229 FILE *f;
3230 char *m;
3232 m = pa_sprintf_malloc("%se", mode);
3234 errno = 0;
3235 if ((f = fopen(path, m))) {
3236 pa_xfree(m);
3237 goto finish;
3240 pa_xfree(m);
3242 if (errno != EINVAL)
3243 return NULL;
3245 if (!(f = fopen(path, mode)))
3246 return NULL;
3248 finish:
3249 pa_make_fd_cloexec(fileno(f));
3250 return f;
3253 void pa_nullify_stdfds(void) {
3255 #ifndef OS_IS_WIN32
3256 pa_close(STDIN_FILENO);
3257 pa_close(STDOUT_FILENO);
3258 pa_close(STDERR_FILENO);
3260 pa_assert_se(open("/dev/null", O_RDONLY) == STDIN_FILENO);
3261 pa_assert_se(open("/dev/null", O_WRONLY) == STDOUT_FILENO);
3262 pa_assert_se(open("/dev/null", O_WRONLY) == STDERR_FILENO);
3263 #else
3264 FreeConsole();
3265 #endif
3269 char *pa_read_line_from_file(const char *fn) {
3270 FILE *f;
3271 char ln[256] = "", *r;
3273 if (!(f = pa_fopen_cloexec(fn, "r")))
3274 return NULL;
3276 r = fgets(ln, sizeof(ln)-1, f);
3277 fclose(f);
3279 if (!r) {
3280 errno = EIO;
3281 return NULL;
3284 pa_strip_nl(ln);
3285 return pa_xstrdup(ln);
3288 pa_bool_t pa_running_in_vm(void) {
3290 #if defined(__i386__) || defined(__x86_64__)
3292 /* Both CPUID and DMI are x86 specific interfaces... */
3294 uint32_t eax = 0x40000000;
3295 union {
3296 uint32_t sig32[3];
3297 char text[13];
3298 } sig;
3300 #ifdef __linux__
3301 const char *const dmi_vendors[] = {
3302 "/sys/class/dmi/id/sys_vendor",
3303 "/sys/class/dmi/id/board_vendor",
3304 "/sys/class/dmi/id/bios_vendor"
3307 unsigned i;
3309 for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) {
3310 char *s;
3312 if ((s = pa_read_line_from_file(dmi_vendors[i]))) {
3314 if (pa_startswith(s, "QEMU") ||
3315 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3316 pa_startswith(s, "VMware") ||
3317 pa_startswith(s, "VMW") ||
3318 pa_startswith(s, "Microsoft Corporation") ||
3319 pa_startswith(s, "innotek GmbH") ||
3320 pa_startswith(s, "Xen")) {
3322 pa_xfree(s);
3323 return TRUE;
3326 pa_xfree(s);
3330 #endif
3332 /* http://lwn.net/Articles/301888/ */
3333 pa_zero(sig);
3335 __asm__ __volatile__ (
3336 /* ebx/rbx is being used for PIC! */
3337 " push %%"PA_REG_b" \n\t"
3338 " cpuid \n\t"
3339 " mov %%ebx, %1 \n\t"
3340 " pop %%"PA_REG_b" \n\t"
3342 : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2])
3343 : "0" (eax)
3346 if (pa_streq(sig.text, "XenVMMXenVMM") ||
3347 pa_streq(sig.text, "KVMKVMKVM") ||
3348 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3349 pa_streq(sig.text, "VMwareVMware") ||
3350 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3351 pa_streq(sig.text, "Microsoft Hv"))
3352 return TRUE;
3354 #endif
3356 return FALSE;