]> code.delx.au - pulseaudio/blob - src/pulsecore/core-util.c
Find modules and config files relative to the installed libraries.
[pulseaudio] / src / pulsecore / core-util.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2004 Joe Marcus Clarke
6 Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
7
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.
12
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.
17
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 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
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>
41
42 #ifdef HAVE_LANGINFO_H
43 #include <langinfo.h>
44 #endif
45
46 #ifdef HAVE_UNAME
47 #include <sys/utsname.h>
48 #endif
49
50 #if defined(HAVE_REGEX_H)
51 #include <regex.h>
52 #elif defined(HAVE_PCREPOSIX_H)
53 #include <pcreposix.h>
54 #endif
55
56 #ifdef HAVE_STRTOF_L
57 #include <locale.h>
58 #endif
59
60 #ifdef HAVE_SCHED_H
61 #include <sched.h>
62
63 #if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
64 #define SCHED_RESET_ON_FORK 0x40000000
65 #endif
66 #endif
67
68 #ifdef HAVE_SYS_RESOURCE_H
69 #include <sys/resource.h>
70 #endif
71
72 #ifdef HAVE_SYS_CAPABILITY_H
73 #include <sys/capability.h>
74 #endif
75
76 #ifdef HAVE_SYS_MMAN_H
77 #include <sys/mman.h>
78 #endif
79
80 #ifdef HAVE_PTHREAD
81 #include <pthread.h>
82 #endif
83
84 #ifdef HAVE_NETDB_H
85 #include <netdb.h>
86 #endif
87
88 #ifdef HAVE_WINDOWS_H
89 #include <windows.h>
90 #endif
91
92 #ifndef ENOTSUP
93 #define ENOTSUP 135
94 #endif
95
96 #ifdef HAVE_PWD_H
97 #include <pwd.h>
98 #endif
99
100 #ifdef HAVE_GRP_H
101 #include <grp.h>
102 #endif
103
104 #ifdef HAVE_LIBSAMPLERATE
105 #include <samplerate.h>
106 #endif
107
108 #ifdef __APPLE__
109 #include <xlocale.h>
110 #endif
111
112 #ifdef HAVE_DBUS
113 #include "rtkit.h"
114 #endif
115
116 #ifdef __linux__
117 #include <sys/personality.h>
118 #endif
119
120 #include <pulse/xmalloc.h>
121 #include <pulse/util.h>
122 #include <pulse/utf8.h>
123
124 #include <pulsecore/core-error.h>
125 #include <pulsecore/socket.h>
126 #include <pulsecore/log.h>
127 #include <pulsecore/macro.h>
128 #include <pulsecore/thread.h>
129 #include <pulsecore/strbuf.h>
130 #include <pulsecore/usergroup.h>
131 #include <pulsecore/strlist.h>
132 #include <pulsecore/cpu-x86.h>
133 #include <pulsecore/pipe.h>
134
135 #include "core-util.h"
136
137 /* Not all platforms have this */
138 #ifndef MSG_NOSIGNAL
139 #define MSG_NOSIGNAL 0
140 #endif
141
142 #define NEWLINE "\r\n"
143 #define WHITESPACE "\n\r \t"
144
145 static pa_strlist *recorded_env = NULL;
146
147 #ifdef OS_IS_WIN32
148
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;
152
153 if (!toplevel) {
154 char library_path[MAX_PATH];
155 char *p;
156
157 if (!GetModuleFileName(handle, library_path, MAX_PATH))
158 return NULL;
159
160 toplevel = pa_xstrdup(library_path);
161
162 p = strrchr(toplevel, PA_PATH_SEP_CHAR);
163 if (p)
164 *p = '\0';
165
166 p = strrchr(toplevel, PA_PATH_SEP_CHAR);
167 if (p && (strcmp(p + 1, "bin") == 0))
168 *p = '\0';
169 }
170
171 return toplevel;
172 }
173
174 #endif
175
176 /** Make a file descriptor nonblock. Doesn't do any error checking */
177 void pa_make_fd_nonblock(int fd) {
178
179 #ifdef O_NONBLOCK
180 int v;
181 pa_assert(fd >= 0);
182
183 pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
184
185 if (!(v & O_NONBLOCK))
186 pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0);
187
188 #elif defined(OS_IS_WIN32)
189 u_long arg = 1;
190 if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
191 pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
192 pa_log_warn("Only sockets can be made non-blocking!");
193 }
194 #else
195 pa_log_warn("Non-blocking I/O not supported.!");
196 #endif
197
198 }
199
200 /* Set the FD_CLOEXEC flag for a fd */
201 void pa_make_fd_cloexec(int fd) {
202
203 #ifdef FD_CLOEXEC
204 int v;
205 pa_assert(fd >= 0);
206
207 pa_assert_se((v = fcntl(fd, F_GETFD, 0)) >= 0);
208
209 if (!(v & FD_CLOEXEC))
210 pa_assert_se(fcntl(fd, F_SETFD, v|FD_CLOEXEC) >= 0);
211 #endif
212
213 }
214
215 /** Creates a directory securely */
216 int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
217 struct stat st;
218 int r, saved_errno, fd;
219
220 pa_assert(dir);
221
222 #ifdef OS_IS_WIN32
223 r = mkdir(dir);
224 #else
225 {
226 mode_t u;
227 u = umask((~m) & 0777);
228 r = mkdir(dir, m);
229 umask(u);
230 }
231 #endif
232
233 if (r < 0 && errno != EEXIST)
234 return -1;
235
236 #if defined(HAVE_FSTAT) && !defined(OS_IS_WIN32)
237 if ((fd = open(dir,
238 #ifdef O_CLOEXEC
239 O_CLOEXEC|
240 #endif
241 #ifdef O_NOCTTY
242 O_NOCTTY|
243 #endif
244 #ifdef O_NOFOLLOW
245 O_NOFOLLOW|
246 #endif
247 O_RDONLY)) < 0)
248 goto fail;
249
250 if (fstat(fd, &st) < 0) {
251 pa_assert_se(pa_close(fd) >= 0);
252 goto fail;
253 }
254
255 if (!S_ISDIR(st.st_mode)) {
256 pa_assert_se(pa_close(fd) >= 0);
257 errno = EEXIST;
258 goto fail;
259 }
260
261 #ifdef HAVE_FCHOWN
262 if (uid == (uid_t)-1)
263 uid = getuid();
264 if (gid == (gid_t)-1)
265 gid = getgid();
266 (void) fchown(fd, uid, gid);
267 #endif
268
269 #ifdef HAVE_FCHMOD
270 (void) fchmod(fd, m);
271 #endif
272
273 pa_assert_se(pa_close(fd) >= 0);
274 #endif
275
276 #ifdef HAVE_LSTAT
277 if (lstat(dir, &st) < 0)
278 #else
279 if (stat(dir, &st) < 0)
280 #endif
281 goto fail;
282
283 #ifndef OS_IS_WIN32
284 if (!S_ISDIR(st.st_mode) ||
285 (st.st_uid != uid) ||
286 (st.st_gid != gid) ||
287 ((st.st_mode & 0777) != m)) {
288 errno = EACCES;
289 goto fail;
290 }
291 #else
292 pa_log_warn("Secure directory creation not supported on Win32.");
293 #endif
294
295 return 0;
296
297 fail:
298 saved_errno = errno;
299 rmdir(dir);
300 errno = saved_errno;
301
302 return -1;
303 }
304
305 /* Return a newly allocated sting containing the parent directory of the specified file */
306 char *pa_parent_dir(const char *fn) {
307 char *slash, *dir = pa_xstrdup(fn);
308
309 if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
310 pa_xfree(dir);
311 errno = ENOENT;
312 return NULL;
313 }
314
315 *(slash-1) = 0;
316 return dir;
317 }
318
319 /* Creates a the parent directory of the specified path securely */
320 int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {
321 int ret = -1;
322 char *dir;
323
324 if (!(dir = pa_parent_dir(fn)))
325 goto finish;
326
327 if (pa_make_secure_dir(dir, m, uid, gid) < 0)
328 goto finish;
329
330 ret = 0;
331
332 finish:
333 pa_xfree(dir);
334 return ret;
335 }
336
337 /** Platform independent read function. Necessary since not all
338 * systems treat all file descriptors equal. If type is
339 * non-NULL it is used to cache the type of the fd. This is
340 * useful for making sure that only a single syscall is executed per
341 * function call. The variable pointed to should be initialized to 0
342 * by the caller. */
343 ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
344
345 #ifdef OS_IS_WIN32
346
347 if (!type || *type == 0) {
348 ssize_t r;
349
350 if ((r = recv(fd, buf, count, 0)) >= 0)
351 return r;
352
353 if (WSAGetLastError() != WSAENOTSOCK) {
354 errno = WSAGetLastError();
355 return r;
356 }
357
358 if (type)
359 *type = 1;
360 }
361
362 #endif
363
364 for (;;) {
365 ssize_t r;
366
367 if ((r = read(fd, buf, count)) < 0)
368 if (errno == EINTR)
369 continue;
370
371 return r;
372 }
373 }
374
375 /** Similar to pa_read(), but handles writes */
376 ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
377
378 if (!type || *type == 0) {
379 ssize_t r;
380
381 for (;;) {
382 if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) {
383
384 if (errno == EINTR)
385 continue;
386
387 break;
388 }
389
390 return r;
391 }
392
393 #ifdef OS_IS_WIN32
394 if (WSAGetLastError() != WSAENOTSOCK) {
395 errno = WSAGetLastError();
396 return r;
397 }
398 #else
399 if (errno != ENOTSOCK)
400 return r;
401 #endif
402
403 if (type)
404 *type = 1;
405 }
406
407 for (;;) {
408 ssize_t r;
409
410 if ((r = write(fd, buf, count)) < 0)
411 if (errno == EINTR)
412 continue;
413
414 return r;
415 }
416 }
417
418 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
419 * unless EOF is reached or an error occurred */
420 ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
421 ssize_t ret = 0;
422 int _type;
423
424 pa_assert(fd >= 0);
425 pa_assert(data);
426 pa_assert(size);
427
428 if (!type) {
429 _type = 0;
430 type = &_type;
431 }
432
433 while (size > 0) {
434 ssize_t r;
435
436 if ((r = pa_read(fd, data, size, type)) < 0)
437 return r;
438
439 if (r == 0)
440 break;
441
442 ret += r;
443 data = (uint8_t*) data + r;
444 size -= (size_t) r;
445 }
446
447 return ret;
448 }
449
450 /** Similar to pa_loop_read(), but wraps write() */
451 ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
452 ssize_t ret = 0;
453 int _type;
454
455 pa_assert(fd >= 0);
456 pa_assert(data);
457 pa_assert(size);
458
459 if (!type) {
460 _type = 0;
461 type = &_type;
462 }
463
464 while (size > 0) {
465 ssize_t r;
466
467 if ((r = pa_write(fd, data, size, type)) < 0)
468 return r;
469
470 if (r == 0)
471 break;
472
473 ret += r;
474 data = (const uint8_t*) data + r;
475 size -= (size_t) r;
476 }
477
478 return ret;
479 }
480
481 /** Platform independent read function. Necessary since not all
482 * systems treat all file descriptors equal. */
483 int pa_close(int fd) {
484
485 #ifdef OS_IS_WIN32
486 int ret;
487
488 if ((ret = closesocket(fd)) == 0)
489 return 0;
490
491 if (WSAGetLastError() != WSAENOTSOCK) {
492 errno = WSAGetLastError();
493 return ret;
494 }
495 #endif
496
497 for (;;) {
498 int r;
499
500 if ((r = close(fd)) < 0)
501 if (errno == EINTR)
502 continue;
503
504 return r;
505 }
506 }
507
508 /* Print a warning messages in case that the given signal is not
509 * blocked or trapped */
510 void pa_check_signal_is_blocked(int sig) {
511 #ifdef HAVE_SIGACTION
512 struct sigaction sa;
513 sigset_t set;
514
515 /* If POSIX threads are supported use thread-aware
516 * pthread_sigmask() function, to check if the signal is
517 * blocked. Otherwise fall back to sigprocmask() */
518
519 #ifdef HAVE_PTHREAD
520 if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) {
521 #endif
522 if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) {
523 pa_log("sigprocmask(): %s", pa_cstrerror(errno));
524 return;
525 }
526 #ifdef HAVE_PTHREAD
527 }
528 #endif
529
530 if (sigismember(&set, sig))
531 return;
532
533 /* Check whether the signal is trapped */
534
535 if (sigaction(sig, NULL, &sa) < 0) {
536 pa_log("sigaction(): %s", pa_cstrerror(errno));
537 return;
538 }
539
540 if (sa.sa_handler != SIG_DFL)
541 return;
542
543 pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig));
544 #else /* HAVE_SIGACTION */
545 pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig));
546 #endif
547 }
548
549 /* The following function is based on an example from the GNU libc
550 * documentation. This function is similar to GNU's asprintf(). */
551 char *pa_sprintf_malloc(const char *format, ...) {
552 size_t size = 100;
553 char *c = NULL;
554
555 pa_assert(format);
556
557 for(;;) {
558 int r;
559 va_list ap;
560
561 c = pa_xrealloc(c, size);
562
563 va_start(ap, format);
564 r = vsnprintf(c, size, format, ap);
565 va_end(ap);
566
567 c[size-1] = 0;
568
569 if (r > -1 && (size_t) r < size)
570 return c;
571
572 if (r > -1) /* glibc 2.1 */
573 size = (size_t) r+1;
574 else /* glibc 2.0 */
575 size *= 2;
576 }
577 }
578
579 /* Same as the previous function, but use a va_list instead of an
580 * ellipsis */
581 char *pa_vsprintf_malloc(const char *format, va_list ap) {
582 size_t size = 100;
583 char *c = NULL;
584
585 pa_assert(format);
586
587 for(;;) {
588 int r;
589 va_list aq;
590
591 c = pa_xrealloc(c, size);
592
593 va_copy(aq, ap);
594 r = vsnprintf(c, size, format, aq);
595 va_end(aq);
596
597 c[size-1] = 0;
598
599 if (r > -1 && (size_t) r < size)
600 return c;
601
602 if (r > -1) /* glibc 2.1 */
603 size = (size_t) r+1;
604 else /* glibc 2.0 */
605 size *= 2;
606 }
607 }
608
609 /* Similar to OpenBSD's strlcpy() function */
610 char *pa_strlcpy(char *b, const char *s, size_t l) {
611 size_t k;
612
613 pa_assert(b);
614 pa_assert(s);
615 pa_assert(l > 0);
616
617 k = strlen(s);
618
619 if (k > l-1)
620 k = l-1;
621
622 memcpy(b, s, k);
623 b[k] = 0;
624
625 return b;
626 }
627
628 static int set_scheduler(int rtprio) {
629 #ifdef HAVE_SCHED_H
630 struct sched_param sp;
631 #ifdef HAVE_DBUS
632 int r;
633 DBusError error;
634 DBusConnection *bus;
635
636 dbus_error_init(&error);
637 #endif
638
639 pa_zero(sp);
640 sp.sched_priority = rtprio;
641
642 #ifdef SCHED_RESET_ON_FORK
643 if (pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, &sp) == 0) {
644 pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
645 return 0;
646 }
647 #endif
648
649 if (pthread_setschedparam(pthread_self(), SCHED_RR, &sp) == 0) {
650 pa_log_debug("SCHED_RR worked.");
651 return 0;
652 }
653 #endif /* HAVE_SCHED_H */
654
655 #ifdef HAVE_DBUS
656 /* Try to talk to RealtimeKit */
657
658 if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
659 pa_log("Failed to connect to system bus: %s\n", error.message);
660 dbus_error_free(&error);
661 errno = -EIO;
662 return -1;
663 }
664
665 /* We need to disable exit on disconnect because otherwise
666 * dbus_shutdown will kill us. See
667 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
668 dbus_connection_set_exit_on_disconnect(bus, FALSE);
669
670 r = rtkit_make_realtime(bus, 0, rtprio);
671 dbus_connection_unref(bus);
672
673 if (r >= 0) {
674 pa_log_debug("RealtimeKit worked.");
675 return 0;
676 }
677
678 errno = -r;
679 #else
680 errno = 0;
681 #endif
682
683 return -1;
684 }
685
686 /* Make the current thread a realtime thread, and acquire the highest
687 * rtprio we can get that is less or equal the specified parameter. If
688 * the thread is already realtime, don't do anything. */
689 int pa_make_realtime(int rtprio) {
690
691 #ifdef _POSIX_PRIORITY_SCHEDULING
692 int p;
693
694 if (set_scheduler(rtprio) >= 0) {
695 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio);
696 return 0;
697 }
698
699 for (p = rtprio-1; p >= 1; p--)
700 if (set_scheduler(p) >= 0) {
701 pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p, rtprio);
702 return 0;
703 }
704 #elif defined(OS_IS_WIN32)
705 /* Windows only allows realtime scheduling to be set on a per process basis.
706 * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
707 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) {
708 pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
709 return 0;
710 }
711
712 pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
713 errno = EPERM;
714 #else
715 errno = ENOTSUP;
716 #endif
717 pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno));
718 return -1;
719 }
720
721 static int set_nice(int nice_level) {
722 #ifdef HAVE_DBUS
723 DBusError error;
724 DBusConnection *bus;
725 int r;
726
727 dbus_error_init(&error);
728 #endif
729
730 #ifdef HAVE_SYS_RESOURCE_H
731 if (setpriority(PRIO_PROCESS, 0, nice_level) >= 0) {
732 pa_log_debug("setpriority() worked.");
733 return 0;
734 }
735 #endif
736
737 #ifdef HAVE_DBUS
738 /* Try to talk to RealtimeKit */
739
740 if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
741 pa_log("Failed to connect to system bus: %s\n", error.message);
742 dbus_error_free(&error);
743 errno = -EIO;
744 return -1;
745 }
746
747 /* We need to disable exit on disconnect because otherwise
748 * dbus_shutdown will kill us. See
749 * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
750 dbus_connection_set_exit_on_disconnect(bus, FALSE);
751
752 r = rtkit_make_high_priority(bus, 0, nice_level);
753 dbus_connection_unref(bus);
754
755 if (r >= 0) {
756 pa_log_debug("RealtimeKit worked.");
757 return 0;
758 }
759
760 errno = -r;
761 #endif
762
763 return -1;
764 }
765
766 /* Raise the priority of the current process as much as possible that
767 * is <= the specified nice level..*/
768 int pa_raise_priority(int nice_level) {
769
770 #ifdef HAVE_SYS_RESOURCE_H
771 int n;
772
773 if (set_nice(nice_level) >= 0) {
774 pa_log_info("Successfully gained nice level %i.", nice_level);
775 return 0;
776 }
777
778 for (n = nice_level+1; n < 0; n++)
779 if (set_nice(n) >= 0) {
780 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
781 return 0;
782 }
783
784 pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno));
785 return -1;
786 #endif
787
788 #ifdef OS_IS_WIN32
789 if (nice_level < 0) {
790 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
791 pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
792 errno = EPERM;
793 return -1;
794 }
795
796 pa_log_info("Successfully gained high priority class.");
797 }
798 #endif
799
800 return 0;
801 }
802
803 /* Reset the priority to normal, inverting the changes made by
804 * pa_raise_priority() and pa_make_realtime()*/
805 void pa_reset_priority(void) {
806 #ifdef HAVE_SYS_RESOURCE_H
807 struct sched_param sp;
808
809 setpriority(PRIO_PROCESS, 0, 0);
810
811 pa_zero(sp);
812 pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp);
813 #endif
814
815 #ifdef OS_IS_WIN32
816 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
817 #endif
818 }
819
820 int pa_match(const char *expr, const char *v) {
821 int k;
822 regex_t re;
823 int r;
824
825 if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
826 errno = EINVAL;
827 return -1;
828 }
829
830 if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
831 r = 1;
832 else if (k == REG_NOMATCH)
833 r = 0;
834 else
835 r = -1;
836
837 regfree(&re);
838
839 if (r < 0)
840 errno = EINVAL;
841
842 return r;
843 }
844
845 /* Try to parse a boolean string value.*/
846 int pa_parse_boolean(const char *v) {
847 const char *expr;
848 pa_assert(v);
849
850 /* First we check language independant */
851 if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
852 return 1;
853 else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
854 return 0;
855
856 #ifdef HAVE_LANGINFO_H
857 /* And then we check language dependant */
858 if ((expr = nl_langinfo(YESEXPR)))
859 if (expr[0])
860 if (pa_match(expr, v) > 0)
861 return 1;
862
863 if ((expr = nl_langinfo(NOEXPR)))
864 if (expr[0])
865 if (pa_match(expr, v) > 0)
866 return 0;
867 #endif
868
869 errno = EINVAL;
870 return -1;
871 }
872
873 /* Split the specified string wherever one of the strings in delimiter
874 * occurs. Each time it is called returns a newly allocated string
875 * with pa_xmalloc(). The variable state points to, should be
876 * initiallized to NULL before the first call. */
877 char *pa_split(const char *c, const char *delimiter, const char**state) {
878 const char *current = *state ? *state : c;
879 size_t l;
880
881 if (!*current)
882 return NULL;
883
884 l = strcspn(current, delimiter);
885 *state = current+l;
886
887 if (**state)
888 (*state)++;
889
890 return pa_xstrndup(current, l);
891 }
892
893 /* Split a string into words. Otherwise similar to pa_split(). */
894 char *pa_split_spaces(const char *c, const char **state) {
895 const char *current = *state ? *state : c;
896 size_t l;
897
898 if (!*current || *c == 0)
899 return NULL;
900
901 current += strspn(current, WHITESPACE);
902 l = strcspn(current, WHITESPACE);
903
904 *state = current+l;
905
906 return pa_xstrndup(current, l);
907 }
908
909 PA_STATIC_TLS_DECLARE(signame, pa_xfree);
910
911 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
912 const char *pa_sig2str(int sig) {
913 char *t;
914
915 if (sig <= 0)
916 goto fail;
917
918 #ifdef NSIG
919 if (sig >= NSIG)
920 goto fail;
921 #endif
922
923 #ifdef HAVE_SIG2STR
924 {
925 char buf[SIG2STR_MAX];
926
927 if (sig2str(sig, buf) == 0) {
928 pa_xfree(PA_STATIC_TLS_GET(signame));
929 t = pa_sprintf_malloc("SIG%s", buf);
930 PA_STATIC_TLS_SET(signame, t);
931 return t;
932 }
933 }
934 #else
935
936 switch (sig) {
937 #ifdef SIGHUP
938 case SIGHUP: return "SIGHUP";
939 #endif
940 case SIGINT: return "SIGINT";
941 #ifdef SIGQUIT
942 case SIGQUIT: return "SIGQUIT";
943 #endif
944 case SIGILL: return "SIGULL";
945 #ifdef SIGTRAP
946 case SIGTRAP: return "SIGTRAP";
947 #endif
948 case SIGABRT: return "SIGABRT";
949 #ifdef SIGBUS
950 case SIGBUS: return "SIGBUS";
951 #endif
952 case SIGFPE: return "SIGFPE";
953 #ifdef SIGKILL
954 case SIGKILL: return "SIGKILL";
955 #endif
956 #ifdef SIGUSR1
957 case SIGUSR1: return "SIGUSR1";
958 #endif
959 case SIGSEGV: return "SIGSEGV";
960 #ifdef SIGUSR2
961 case SIGUSR2: return "SIGUSR2";
962 #endif
963 #ifdef SIGPIPE
964 case SIGPIPE: return "SIGPIPE";
965 #endif
966 #ifdef SIGALRM
967 case SIGALRM: return "SIGALRM";
968 #endif
969 case SIGTERM: return "SIGTERM";
970 #ifdef SIGSTKFLT
971 case SIGSTKFLT: return "SIGSTKFLT";
972 #endif
973 #ifdef SIGCHLD
974 case SIGCHLD: return "SIGCHLD";
975 #endif
976 #ifdef SIGCONT
977 case SIGCONT: return "SIGCONT";
978 #endif
979 #ifdef SIGSTOP
980 case SIGSTOP: return "SIGSTOP";
981 #endif
982 #ifdef SIGTSTP
983 case SIGTSTP: return "SIGTSTP";
984 #endif
985 #ifdef SIGTTIN
986 case SIGTTIN: return "SIGTTIN";
987 #endif
988 #ifdef SIGTTOU
989 case SIGTTOU: return "SIGTTOU";
990 #endif
991 #ifdef SIGURG
992 case SIGURG: return "SIGURG";
993 #endif
994 #ifdef SIGXCPU
995 case SIGXCPU: return "SIGXCPU";
996 #endif
997 #ifdef SIGXFSZ
998 case SIGXFSZ: return "SIGXFSZ";
999 #endif
1000 #ifdef SIGVTALRM
1001 case SIGVTALRM: return "SIGVTALRM";
1002 #endif
1003 #ifdef SIGPROF
1004 case SIGPROF: return "SIGPROF";
1005 #endif
1006 #ifdef SIGWINCH
1007 case SIGWINCH: return "SIGWINCH";
1008 #endif
1009 #ifdef SIGIO
1010 case SIGIO: return "SIGIO";
1011 #endif
1012 #ifdef SIGPWR
1013 case SIGPWR: return "SIGPWR";
1014 #endif
1015 #ifdef SIGSYS
1016 case SIGSYS: return "SIGSYS";
1017 #endif
1018 }
1019
1020 #ifdef SIGRTMIN
1021 if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
1022 pa_xfree(PA_STATIC_TLS_GET(signame));
1023 t = pa_sprintf_malloc("SIGRTMIN+%i", sig - SIGRTMIN);
1024 PA_STATIC_TLS_SET(signame, t);
1025 return t;
1026 }
1027 #endif
1028
1029 #endif
1030
1031 fail:
1032
1033 pa_xfree(PA_STATIC_TLS_GET(signame));
1034 t = pa_sprintf_malloc("SIG%i", sig);
1035 PA_STATIC_TLS_SET(signame, t);
1036 return t;
1037 }
1038
1039 #ifdef HAVE_GRP_H
1040
1041 /* Check whether the specified GID and the group name match */
1042 static int is_group(gid_t gid, const char *name) {
1043 struct group *group = NULL;
1044 int r = -1;
1045
1046 errno = 0;
1047 if (!(group = pa_getgrgid_malloc(gid)))
1048 {
1049 if (!errno)
1050 errno = ENOENT;
1051
1052 pa_log("pa_getgrgid_malloc(%u): %s", gid, pa_cstrerror(errno));
1053
1054 goto finish;
1055 }
1056
1057 r = strcmp(name, group->gr_name) == 0;
1058
1059 finish:
1060 pa_getgrgid_free(group);
1061
1062 return r;
1063 }
1064
1065 /* Check the current user is member of the specified group */
1066 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1067 GETGROUPS_T *gids, tgid;
1068 long n = sysconf(_SC_NGROUPS_MAX);
1069 int r = -1, i, k;
1070
1071 pa_assert(n > 0);
1072
1073 gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
1074
1075 if ((n = getgroups((int) n, gids)) < 0) {
1076 pa_log("getgroups(): %s", pa_cstrerror(errno));
1077 goto finish;
1078 }
1079
1080 for (i = 0; i < n; i++) {
1081
1082 if ((k = is_group(gids[i], name)) < 0)
1083 goto finish;
1084 else if (k > 0) {
1085 *gid = gids[i];
1086 r = 1;
1087 goto finish;
1088 }
1089 }
1090
1091 if ((k = is_group(tgid = getgid(), name)) < 0)
1092 goto finish;
1093 else if (k > 0) {
1094 *gid = tgid;
1095 r = 1;
1096 goto finish;
1097 }
1098
1099 r = 0;
1100
1101 finish:
1102
1103 pa_xfree(gids);
1104 return r;
1105 }
1106
1107 /* Check whether the specifc user id is a member of the specified group */
1108 int pa_uid_in_group(uid_t uid, const char *name) {
1109 struct group *group = NULL;
1110 char **i;
1111 int r = -1;
1112
1113 errno = 0;
1114 if (!(group = pa_getgrnam_malloc(name)))
1115 {
1116 if (!errno)
1117 errno = ENOENT;
1118 goto finish;
1119 }
1120
1121 r = 0;
1122 for (i = group->gr_mem; *i; i++) {
1123 struct passwd *pw = NULL;
1124
1125 errno = 0;
1126 if (!(pw = pa_getpwnam_malloc(*i)))
1127 continue;
1128
1129 if (pw->pw_uid == uid)
1130 r = 1;
1131
1132 pa_getpwnam_free(pw);
1133
1134 if (r == 1)
1135 break;
1136 }
1137
1138 finish:
1139 pa_getgrnam_free(group);
1140
1141 return r;
1142 }
1143
1144 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
1145 gid_t pa_get_gid_of_group(const char *name) {
1146 gid_t ret = (gid_t) -1;
1147 struct group *gr = NULL;
1148
1149 errno = 0;
1150 if (!(gr = pa_getgrnam_malloc(name)))
1151 {
1152 if (!errno)
1153 errno = ENOENT;
1154 goto finish;
1155 }
1156
1157 ret = gr->gr_gid;
1158
1159 finish:
1160 pa_getgrnam_free(gr);
1161 return ret;
1162 }
1163
1164 int pa_check_in_group(gid_t g) {
1165 gid_t gids[NGROUPS_MAX];
1166 int r;
1167
1168 if ((r = getgroups(NGROUPS_MAX, gids)) < 0)
1169 return -1;
1170
1171 for (; r > 0; r--)
1172 if (gids[r-1] == g)
1173 return 1;
1174
1175 return 0;
1176 }
1177
1178 #else /* HAVE_GRP_H */
1179
1180 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1181 errno = ENOTSUP;
1182 return -1;
1183
1184 }
1185
1186 int pa_uid_in_group(uid_t uid, const char *name) {
1187 errno = ENOTSUP;
1188 return -1;
1189 }
1190
1191 gid_t pa_get_gid_of_group(const char *name) {
1192 errno = ENOTSUP;
1193 return (gid_t) -1;
1194 }
1195
1196 int pa_check_in_group(gid_t g) {
1197 errno = ENOTSUP;
1198 return -1;
1199 }
1200
1201 #endif
1202
1203 /* Lock or unlock a file entirely.
1204 (advisory on UNIX, mandatory on Windows) */
1205 int pa_lock_fd(int fd, int b) {
1206 #ifdef F_SETLKW
1207 struct flock f_lock;
1208
1209 /* Try a R/W lock first */
1210
1211 f_lock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
1212 f_lock.l_whence = SEEK_SET;
1213 f_lock.l_start = 0;
1214 f_lock.l_len = 0;
1215
1216 if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
1217 return 0;
1218
1219 /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
1220 if (b && errno == EBADF) {
1221 f_lock.l_type = F_RDLCK;
1222 if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
1223 return 0;
1224 }
1225
1226 pa_log("%slock: %s", !b ? "un" : "", pa_cstrerror(errno));
1227 #endif
1228
1229 #ifdef OS_IS_WIN32
1230 HANDLE h = (HANDLE) _get_osfhandle(fd);
1231
1232 if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1233 return 0;
1234 if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1235 return 0;
1236
1237 pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError());
1238
1239 /* FIXME: Needs to set errno! */
1240 #endif
1241
1242 return -1;
1243 }
1244
1245 /* Remove trailing newlines from a string */
1246 char* pa_strip_nl(char *s) {
1247 pa_assert(s);
1248
1249 s[strcspn(s, NEWLINE)] = 0;
1250 return s;
1251 }
1252
1253 char *pa_strip(char *s) {
1254 char *e, *l = NULL;
1255
1256 /* Drops trailing whitespace. Modifies the string in
1257 * place. Returns pointer to first non-space character */
1258
1259 s += strspn(s, WHITESPACE);
1260
1261 for (e = s; *e; e++)
1262 if (!strchr(WHITESPACE, *e))
1263 l = e;
1264
1265 if (l)
1266 *(l+1) = 0;
1267 else
1268 *s = 0;
1269
1270 return s;
1271 }
1272
1273 /* Create a temporary lock file and lock it. */
1274 int pa_lock_lockfile(const char *fn) {
1275 int fd;
1276 pa_assert(fn);
1277
1278 for (;;) {
1279 struct stat st;
1280
1281 if ((fd = pa_open_cloexec(fn, O_CREAT|O_RDWR
1282 #ifdef O_NOFOLLOW
1283 |O_NOFOLLOW
1284 #endif
1285 , S_IRUSR|S_IWUSR)) < 0) {
1286 pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno));
1287 goto fail;
1288 }
1289
1290 if (pa_lock_fd(fd, 1) < 0) {
1291 pa_log_warn("Failed to lock file '%s'.", fn);
1292 goto fail;
1293 }
1294
1295 if (fstat(fd, &st) < 0) {
1296 pa_log_warn("Failed to fstat() file '%s': %s", fn, pa_cstrerror(errno));
1297 goto fail;
1298 }
1299
1300 /* Check whether the file has been removed meanwhile. When yes,
1301 * restart this loop, otherwise, we're done */
1302 if (st.st_nlink >= 1)
1303 break;
1304
1305 if (pa_lock_fd(fd, 0) < 0) {
1306 pa_log_warn("Failed to unlock file '%s'.", fn);
1307 goto fail;
1308 }
1309
1310 if (pa_close(fd) < 0) {
1311 pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno));
1312 fd = -1;
1313 goto fail;
1314 }
1315 }
1316
1317 return fd;
1318
1319 fail:
1320
1321 if (fd >= 0) {
1322 int saved_errno = errno;
1323 pa_close(fd);
1324 errno = saved_errno;
1325 }
1326
1327 return -1;
1328 }
1329
1330 /* Unlock a temporary lcok file */
1331 int pa_unlock_lockfile(const char *fn, int fd) {
1332 int r = 0;
1333 pa_assert(fd >= 0);
1334
1335 if (fn) {
1336 if (unlink(fn) < 0) {
1337 pa_log_warn("Unable to remove lock file '%s': %s", fn, pa_cstrerror(errno));
1338 r = -1;
1339 }
1340 }
1341
1342 if (pa_lock_fd(fd, 0) < 0) {
1343 pa_log_warn("Failed to unlock file '%s'.", fn);
1344 r = -1;
1345 }
1346
1347 if (pa_close(fd) < 0) {
1348 pa_log_warn("Failed to close '%s': %s", fn, pa_cstrerror(errno));
1349 r = -1;
1350 }
1351
1352 return r;
1353 }
1354
1355 static char *get_pulse_home(void) {
1356 char *h;
1357 struct stat st;
1358 char *ret = NULL;
1359
1360 if (!(h = pa_get_home_dir_malloc())) {
1361 pa_log_error("Failed to get home directory.");
1362 return NULL;
1363 }
1364
1365 if (stat(h, &st) < 0) {
1366 pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno));
1367 goto finish;
1368 }
1369
1370 #ifdef HAVE_GETUID
1371 if (st.st_uid != getuid()) {
1372 pa_log_error("Home directory %s not ours.", h);
1373 errno = EACCES;
1374 goto finish;
1375 }
1376 #endif
1377
1378 ret = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
1379
1380 finish:
1381 pa_xfree(h);
1382
1383 return ret;
1384 }
1385
1386 char *pa_get_state_dir(void) {
1387 char *d;
1388
1389 /* The state directory shall contain dynamic data that should be
1390 * kept across reboots, and is private to this user */
1391
1392 if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1393 if (!(d = get_pulse_home()))
1394 return NULL;
1395
1396 /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1397 * dir then this will break. */
1398
1399 if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0) {
1400 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1401 pa_xfree(d);
1402 return NULL;
1403 }
1404
1405 return d;
1406 }
1407
1408 char *pa_get_home_dir_malloc(void) {
1409 char *homedir;
1410 size_t allocated = 128;
1411
1412 for (;;) {
1413 homedir = pa_xmalloc(allocated);
1414
1415 if (!pa_get_home_dir(homedir, allocated)) {
1416 pa_xfree(homedir);
1417 return NULL;
1418 }
1419
1420 if (strlen(homedir) < allocated - 1)
1421 break;
1422
1423 pa_xfree(homedir);
1424 allocated *= 2;
1425 }
1426
1427 return homedir;
1428 }
1429
1430 char *pa_get_binary_name_malloc(void) {
1431 char *t;
1432 size_t allocated = 128;
1433
1434 for (;;) {
1435 t = pa_xmalloc(allocated);
1436
1437 if (!pa_get_binary_name(t, allocated)) {
1438 pa_xfree(t);
1439 return NULL;
1440 }
1441
1442 if (strlen(t) < allocated - 1)
1443 break;
1444
1445 pa_xfree(t);
1446 allocated *= 2;
1447 }
1448
1449 return t;
1450 }
1451
1452 static char* make_random_dir(mode_t m) {
1453 static const char table[] =
1454 "abcdefghijklmnopqrstuvwxyz"
1455 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1456 "0123456789";
1457
1458 char *fn;
1459 size_t pathlen;
1460
1461 fn = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1462 pathlen = strlen(fn);
1463
1464 for (;;) {
1465 size_t i;
1466 int r;
1467 mode_t u;
1468 int saved_errno;
1469
1470 for (i = pathlen - 12; i < pathlen; i++)
1471 fn[i] = table[rand() % (sizeof(table)-1)];
1472
1473 u = umask((~m) & 0777);
1474 #ifndef OS_IS_WIN32
1475 r = mkdir(fn, m);
1476 #else
1477 r = mkdir(fn);
1478 #endif
1479
1480 saved_errno = errno;
1481 umask(u);
1482 errno = saved_errno;
1483
1484 if (r >= 0)
1485 return fn;
1486
1487 if (errno != EEXIST) {
1488 pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
1489 pa_xfree(fn);
1490 return NULL;
1491 }
1492 }
1493 }
1494
1495 static int make_random_dir_and_link(mode_t m, const char *k) {
1496 char *p;
1497
1498 if (!(p = make_random_dir(m)))
1499 return -1;
1500
1501 #ifdef HAVE_SYMLINK
1502 if (symlink(p, k) < 0) {
1503 int saved_errno = errno;
1504
1505 if (errno != EEXIST)
1506 pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno));
1507
1508 rmdir(p);
1509 pa_xfree(p);
1510
1511 errno = saved_errno;
1512 return -1;
1513 }
1514 #else
1515 pa_xfree(p);
1516 return -1;
1517 #endif
1518
1519 pa_xfree(p);
1520 return 0;
1521 }
1522
1523 char *pa_get_runtime_dir(void) {
1524 char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
1525 struct stat st;
1526 mode_t m;
1527
1528 /* The runtime directory shall contain dynamic data that needs NOT
1529 * to be kept accross reboots and is usuallly private to the user,
1530 * except in system mode, where it might be accessible by other
1531 * users, too. Since we need POSIX locking and UNIX sockets in
1532 * this directory, we link it to a random subdir in /tmp, if it
1533 * was not explicitly configured. */
1534
1535 m = pa_in_system_mode() ? 0755U : 0700U;
1536
1537 if ((d = getenv("PULSE_RUNTIME_PATH"))) {
1538
1539 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
1540 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1541 goto fail;
1542 }
1543
1544 return pa_xstrdup(d);
1545 }
1546
1547 if (!(d = get_pulse_home()))
1548 goto fail;
1549
1550 if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
1551 pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1552 pa_xfree(d);
1553 goto fail;
1554 }
1555
1556 if (!(mid = pa_machine_id())) {
1557 pa_xfree(d);
1558 goto fail;
1559 }
1560
1561 k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-runtime", d, mid);
1562 pa_xfree(d);
1563 pa_xfree(mid);
1564
1565 for (;;) {
1566 /* OK, first let's check if the "runtime" symlink is already
1567 * existant */
1568
1569 if (!(p = pa_readlink(k))) {
1570
1571 if (errno != ENOENT) {
1572 pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
1573 goto fail;
1574 }
1575
1576 #ifdef HAVE_SYMLINK
1577 /* Hmm, so the runtime directory didn't exist yet, so let's
1578 * create one in /tmp and symlink that to it */
1579
1580 if (make_random_dir_and_link(0700, k) < 0) {
1581
1582 /* Mhmm, maybe another process was quicker than us,
1583 * let's check if that was valid */
1584 if (errno == EEXIST)
1585 continue;
1586
1587 goto fail;
1588 }
1589 #else
1590 /* No symlink possible, so let's just create the runtime directly */
1591 if (!mkdir(k))
1592 goto fail;
1593 #endif
1594
1595 return k;
1596 }
1597
1598 /* Make sure that this actually makes sense */
1599 if (!pa_is_path_absolute(p)) {
1600 pa_log_error("Path %s in link %s is not absolute.", p, k);
1601 errno = ENOENT;
1602 goto fail;
1603 }
1604
1605 /* Hmm, so this symlink is still around, make sure nobody fools
1606 * us */
1607
1608 #ifdef HAVE_LSTAT
1609 if (lstat(p, &st) < 0) {
1610
1611 if (errno != ENOENT) {
1612 pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno));
1613 goto fail;
1614 }
1615
1616 } else {
1617
1618 if (S_ISDIR(st.st_mode) &&
1619 (st.st_uid == getuid()) &&
1620 ((st.st_mode & 0777) == 0700)) {
1621
1622 pa_xfree(p);
1623 return k;
1624 }
1625
1626 pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1627 }
1628 #endif
1629
1630 pa_xfree(p);
1631 p = NULL;
1632
1633 /* Hmm, so the link points to some nonexisting or invalid
1634 * dir. Let's replace it by a new link. We first create a
1635 * temporary link and then rename that to allow concurrent
1636 * execution of this function. */
1637
1638 t = pa_sprintf_malloc("%s.tmp", k);
1639
1640 if (make_random_dir_and_link(0700, t) < 0) {
1641
1642 if (errno != EEXIST) {
1643 pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno));
1644 goto fail;
1645 }
1646
1647 pa_xfree(t);
1648 t = NULL;
1649
1650 /* Hmm, someone lese was quicker then us. Let's give
1651 * him some time to finish, and retry. */
1652 pa_msleep(10);
1653 continue;
1654 }
1655
1656 /* OK, we succeeded in creating the temporary symlink, so
1657 * let's rename it */
1658 if (rename(t, k) < 0) {
1659 pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno));
1660 goto fail;
1661 }
1662
1663 pa_xfree(t);
1664 return k;
1665 }
1666
1667 fail:
1668 pa_xfree(p);
1669 pa_xfree(k);
1670 pa_xfree(t);
1671
1672 return NULL;
1673 }
1674
1675 /* Try to open a configuration file. If "env" is specified, open the
1676 * value of the specified environment variable. Otherwise look for a
1677 * file "local" in the home directory or a file "global" in global
1678 * file system. If "result" is non-NULL, a pointer to a newly
1679 * allocated buffer containing the used configuration file is
1680 * stored there.*/
1681 FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
1682 const char *fn;
1683 FILE *f;
1684
1685 if (env && (fn = getenv(env))) {
1686 if ((f = pa_fopen_cloexec(fn, "r"))) {
1687 if (result)
1688 *result = pa_xstrdup(fn);
1689
1690 return f;
1691 }
1692
1693 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1694 return NULL;
1695 }
1696
1697 if (local) {
1698 const char *e;
1699 char *lfn;
1700 char *h;
1701
1702 if ((e = getenv("PULSE_CONFIG_PATH")))
1703 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1704 else if ((h = pa_get_home_dir_malloc())) {
1705 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1706 pa_xfree(h);
1707 } else
1708 return NULL;
1709
1710 if ((f = pa_fopen_cloexec(fn, "r"))) {
1711 if (result)
1712 *result = pa_xstrdup(fn);
1713
1714 pa_xfree(lfn);
1715 return f;
1716 }
1717
1718 if (errno != ENOENT) {
1719 pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1720 pa_xfree(lfn);
1721 return NULL;
1722 }
1723
1724 pa_xfree(lfn);
1725 }
1726
1727 if (global) {
1728 char *gfn;
1729
1730 #ifdef OS_IS_WIN32
1731 if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
1732 gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
1733 pa_win32_get_toplevel(NULL),
1734 global + strlen(PA_DEFAULT_CONFIG_DIR));
1735 else
1736 #endif
1737 gfn = pa_xstrdup(global);
1738
1739 if ((f = pa_fopen_cloexec(gfn, "r"))) {
1740 if (result)
1741 *result = gfn;
1742 else
1743 pa_xfree(gfn);
1744
1745 return f;
1746 }
1747 pa_xfree(gfn);
1748 }
1749
1750 errno = ENOENT;
1751 return NULL;
1752 }
1753
1754 char *pa_find_config_file(const char *global, const char *local, const char *env) {
1755 const char *fn;
1756
1757 if (env && (fn = getenv(env))) {
1758 if (access(fn, R_OK) == 0)
1759 return pa_xstrdup(fn);
1760
1761 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1762 return NULL;
1763 }
1764
1765 if (local) {
1766 const char *e;
1767 char *lfn;
1768 char *h;
1769
1770 if ((e = getenv("PULSE_CONFIG_PATH")))
1771 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1772 else if ((h = pa_get_home_dir_malloc())) {
1773 fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1774 pa_xfree(h);
1775 } else
1776 return NULL;
1777
1778 if (access(fn, R_OK) == 0) {
1779 char *r = pa_xstrdup(fn);
1780 pa_xfree(lfn);
1781 return r;
1782 }
1783
1784 if (errno != ENOENT) {
1785 pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1786 pa_xfree(lfn);
1787 return NULL;
1788 }
1789
1790 pa_xfree(lfn);
1791 }
1792
1793 if (global) {
1794 char *gfn;
1795
1796 #ifdef OS_IS_WIN32
1797 if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
1798 gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
1799 pa_win32_get_toplevel(NULL),
1800 global + strlen(PA_DEFAULT_CONFIG_DIR));
1801 else
1802 #endif
1803 gfn = pa_xstrdup(global);
1804
1805 if (access(gfn, R_OK) == 0)
1806 return gfn;
1807 pa_xfree(gfn);
1808 }
1809
1810 errno = ENOENT;
1811
1812 return NULL;
1813 }
1814
1815 /* Format the specified data as a hexademical string */
1816 char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {
1817 size_t i = 0, j = 0;
1818 const char hex[] = "0123456789abcdef";
1819
1820 pa_assert(d);
1821 pa_assert(s);
1822 pa_assert(slength > 0);
1823
1824 while (i < dlength && j+3 <= slength) {
1825 s[j++] = hex[*d >> 4];
1826 s[j++] = hex[*d & 0xF];
1827
1828 d++;
1829 i++;
1830 }
1831
1832 s[j < slength ? j : slength] = 0;
1833 return s;
1834 }
1835
1836 /* Convert a hexadecimal digit to a number or -1 if invalid */
1837 static int hexc(char c) {
1838 if (c >= '0' && c <= '9')
1839 return c - '0';
1840
1841 if (c >= 'A' && c <= 'F')
1842 return c - 'A' + 10;
1843
1844 if (c >= 'a' && c <= 'f')
1845 return c - 'a' + 10;
1846
1847 errno = EINVAL;
1848 return -1;
1849 }
1850
1851 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1852 size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) {
1853 size_t j = 0;
1854
1855 pa_assert(p);
1856 pa_assert(d);
1857
1858 while (j < dlength && *p) {
1859 int b;
1860
1861 if ((b = hexc(*(p++))) < 0)
1862 return (size_t) -1;
1863
1864 d[j] = (uint8_t) (b << 4);
1865
1866 if (!*p)
1867 return (size_t) -1;
1868
1869 if ((b = hexc(*(p++))) < 0)
1870 return (size_t) -1;
1871
1872 d[j] |= (uint8_t) b;
1873 j++;
1874 }
1875
1876 return j;
1877 }
1878
1879 /* Returns nonzero when *s starts with *pfx */
1880 pa_bool_t pa_startswith(const char *s, const char *pfx) {
1881 size_t l;
1882
1883 pa_assert(s);
1884 pa_assert(pfx);
1885
1886 l = strlen(pfx);
1887
1888 return strlen(s) >= l && strncmp(s, pfx, l) == 0;
1889 }
1890
1891 /* Returns nonzero when *s ends with *sfx */
1892 pa_bool_t pa_endswith(const char *s, const char *sfx) {
1893 size_t l1, l2;
1894
1895 pa_assert(s);
1896 pa_assert(sfx);
1897
1898 l1 = strlen(s);
1899 l2 = strlen(sfx);
1900
1901 return l1 >= l2 && strcmp(s+l1-l2, sfx) == 0;
1902 }
1903
1904 pa_bool_t pa_is_path_absolute(const char *fn) {
1905 pa_assert(fn);
1906
1907 #ifndef OS_IS_WIN32
1908 return *fn == '/';
1909 #else
1910 return strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\';
1911 #endif
1912 }
1913
1914 char *pa_make_path_absolute(const char *p) {
1915 char *r;
1916 char *cwd;
1917
1918 pa_assert(p);
1919
1920 if (pa_is_path_absolute(p))
1921 return pa_xstrdup(p);
1922
1923 if (!(cwd = pa_getcwd()))
1924 return pa_xstrdup(p);
1925
1926 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", cwd, p);
1927 pa_xfree(cwd);
1928 return r;
1929 }
1930
1931 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
1932 * if fn is non-null and starts with / return fn
1933 * otherwise append fn to the run time path and return it */
1934 static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {
1935 char *rtp;
1936
1937 rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
1938
1939 if (fn) {
1940 char *r;
1941
1942 if (pa_is_path_absolute(fn))
1943 return pa_xstrdup(fn);
1944
1945 if (!rtp)
1946 return NULL;
1947
1948 if (prependmid) {
1949 char *mid;
1950
1951 if (!(mid = pa_machine_id())) {
1952 pa_xfree(rtp);
1953 return NULL;
1954 }
1955
1956 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-%s", rtp, mid, fn);
1957 pa_xfree(mid);
1958 } else
1959 r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn);
1960
1961 pa_xfree(rtp);
1962 return r;
1963 } else
1964 return rtp;
1965 }
1966
1967 char *pa_runtime_path(const char *fn) {
1968 return get_path(fn, FALSE, TRUE);
1969 }
1970
1971 char *pa_state_path(const char *fn, pa_bool_t appendmid) {
1972 return get_path(fn, appendmid, FALSE);
1973 }
1974
1975 /* Convert the string s to a signed integer in *ret_i */
1976 int pa_atoi(const char *s, int32_t *ret_i) {
1977 char *x = NULL;
1978 long l;
1979
1980 pa_assert(s);
1981 pa_assert(ret_i);
1982
1983 errno = 0;
1984 l = strtol(s, &x, 0);
1985
1986 if (!x || *x || errno) {
1987 if (!errno)
1988 errno = EINVAL;
1989 return -1;
1990 }
1991
1992 if ((int32_t) l != l) {
1993 errno = ERANGE;
1994 return -1;
1995 }
1996
1997 *ret_i = (int32_t) l;
1998
1999 return 0;
2000 }
2001
2002 /* Convert the string s to an unsigned integer in *ret_u */
2003 int pa_atou(const char *s, uint32_t *ret_u) {
2004 char *x = NULL;
2005 unsigned long l;
2006
2007 pa_assert(s);
2008 pa_assert(ret_u);
2009
2010 errno = 0;
2011 l = strtoul(s, &x, 0);
2012
2013 if (!x || *x || errno) {
2014 if (!errno)
2015 errno = EINVAL;
2016 return -1;
2017 }
2018
2019 if ((uint32_t) l != l) {
2020 errno = ERANGE;
2021 return -1;
2022 }
2023
2024 *ret_u = (uint32_t) l;
2025
2026 return 0;
2027 }
2028
2029 #ifdef HAVE_STRTOF_L
2030 static locale_t c_locale = NULL;
2031
2032 static void c_locale_destroy(void) {
2033 freelocale(c_locale);
2034 }
2035 #endif
2036
2037 int pa_atod(const char *s, double *ret_d) {
2038 char *x = NULL;
2039 double f;
2040
2041 pa_assert(s);
2042 pa_assert(ret_d);
2043
2044 /* This should be locale independent */
2045
2046 #ifdef HAVE_STRTOF_L
2047
2048 PA_ONCE_BEGIN {
2049
2050 if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL)))
2051 atexit(c_locale_destroy);
2052
2053 } PA_ONCE_END;
2054
2055 if (c_locale) {
2056 errno = 0;
2057 f = strtod_l(s, &x, c_locale);
2058 } else
2059 #endif
2060 {
2061 errno = 0;
2062 f = strtod(s, &x);
2063 }
2064
2065 if (!x || *x || errno) {
2066 if (!errno)
2067 errno = EINVAL;
2068 return -1;
2069 }
2070
2071 *ret_d = f;
2072
2073 return 0;
2074 }
2075
2076 /* Same as snprintf, but guarantees NUL-termination on every platform */
2077 size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
2078 size_t ret;
2079 va_list ap;
2080
2081 pa_assert(str);
2082 pa_assert(size > 0);
2083 pa_assert(format);
2084
2085 va_start(ap, format);
2086 ret = pa_vsnprintf(str, size, format, ap);
2087 va_end(ap);
2088
2089 return ret;
2090 }
2091
2092 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2093 size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
2094 int ret;
2095
2096 pa_assert(str);
2097 pa_assert(size > 0);
2098 pa_assert(format);
2099
2100 ret = vsnprintf(str, size, format, ap);
2101
2102 str[size-1] = 0;
2103
2104 if (ret < 0)
2105 return strlen(str);
2106
2107 if ((size_t) ret > size-1)
2108 return size-1;
2109
2110 return (size_t) ret;
2111 }
2112
2113 /* Truncate the specified string, but guarantee that the string
2114 * returned still validates as UTF8 */
2115 char *pa_truncate_utf8(char *c, size_t l) {
2116 pa_assert(c);
2117 pa_assert(pa_utf8_valid(c));
2118
2119 if (strlen(c) <= l)
2120 return c;
2121
2122 c[l] = 0;
2123
2124 while (l > 0 && !pa_utf8_valid(c))
2125 c[--l] = 0;
2126
2127 return c;
2128 }
2129
2130 char *pa_getcwd(void) {
2131 size_t l = 128;
2132
2133 for (;;) {
2134 char *p = pa_xmalloc(l);
2135 if (getcwd(p, l))
2136 return p;
2137
2138 if (errno != ERANGE)
2139 return NULL;
2140
2141 pa_xfree(p);
2142 l *= 2;
2143 }
2144 }
2145
2146 void *pa_will_need(const void *p, size_t l) {
2147 #ifdef RLIMIT_MEMLOCK
2148 struct rlimit rlim;
2149 #endif
2150 const void *a;
2151 size_t size;
2152 int r;
2153 size_t bs;
2154
2155 pa_assert(p);
2156 pa_assert(l > 0);
2157
2158 a = PA_PAGE_ALIGN_PTR(p);
2159 size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
2160
2161 #ifdef HAVE_POSIX_MADVISE
2162 if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
2163 pa_log_debug("posix_madvise() worked fine!");
2164 return (void*) p;
2165 }
2166 #endif
2167
2168 /* Most likely the memory was not mmap()ed from a file and thus
2169 * madvise() didn't work, so let's misuse mlock() do page this
2170 * stuff back into RAM. Yeah, let's fuck with the MM! It's so
2171 * inviting, the man page of mlock() tells us: "All pages that
2172 * contain a part of the specified address range are guaranteed to
2173 * be resident in RAM when the call returns successfully." */
2174
2175 #ifdef RLIMIT_MEMLOCK
2176 pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
2177
2178 if (rlim.rlim_cur < PA_PAGE_SIZE) {
2179 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));
2180 errno = EPERM;
2181 return (void*) p;
2182 }
2183
2184 bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
2185 #else
2186 bs = PA_PAGE_SIZE*4;
2187 #endif
2188
2189 pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r));
2190
2191 #ifdef HAVE_MLOCK
2192 while (size > 0 && bs > 0) {
2193
2194 if (bs > size)
2195 bs = size;
2196
2197 if (mlock(a, bs) < 0) {
2198 bs = PA_PAGE_ALIGN(bs / 2);
2199 continue;
2200 }
2201
2202 pa_assert_se(munlock(a, bs) == 0);
2203
2204 a = (const uint8_t*) a + bs;
2205 size -= bs;
2206 }
2207 #endif
2208
2209 if (bs <= 0)
2210 pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno));
2211 else
2212 pa_log_debug("mlock() worked fine!");
2213
2214 return (void*) p;
2215 }
2216
2217 void pa_close_pipe(int fds[2]) {
2218 pa_assert(fds);
2219
2220 if (fds[0] >= 0)
2221 pa_assert_se(pa_close(fds[0]) == 0);
2222
2223 if (fds[1] >= 0)
2224 pa_assert_se(pa_close(fds[1]) == 0);
2225
2226 fds[0] = fds[1] = -1;
2227 }
2228
2229 char *pa_readlink(const char *p) {
2230 #ifdef HAVE_READLINK
2231 size_t l = 100;
2232
2233 for (;;) {
2234 char *c;
2235 ssize_t n;
2236
2237 c = pa_xmalloc(l);
2238
2239 if ((n = readlink(p, c, l-1)) < 0) {
2240 pa_xfree(c);
2241 return NULL;
2242 }
2243
2244 if ((size_t) n < l-1) {
2245 c[n] = 0;
2246 return c;
2247 }
2248
2249 pa_xfree(c);
2250 l *= 2;
2251 }
2252 #else
2253 return NULL;
2254 #endif
2255 }
2256
2257 int pa_close_all(int except_fd, ...) {
2258 va_list ap;
2259 unsigned n = 0, i;
2260 int r, *p;
2261
2262 va_start(ap, except_fd);
2263
2264 if (except_fd >= 0)
2265 for (n = 1; va_arg(ap, int) >= 0; n++)
2266 ;
2267
2268 va_end(ap);
2269
2270 p = pa_xnew(int, n+1);
2271
2272 va_start(ap, except_fd);
2273
2274 i = 0;
2275 if (except_fd >= 0) {
2276 int fd;
2277 p[i++] = except_fd;
2278
2279 while ((fd = va_arg(ap, int)) >= 0)
2280 p[i++] = fd;
2281 }
2282 p[i] = -1;
2283
2284 va_end(ap);
2285
2286 r = pa_close_allv(p);
2287 pa_xfree(p);
2288
2289 return r;
2290 }
2291
2292 int pa_close_allv(const int except_fds[]) {
2293 #ifndef OS_IS_WIN32
2294 struct rlimit rl;
2295 int maxfd, fd;
2296
2297 #ifdef __linux__
2298 int saved_errno;
2299 DIR *d;
2300
2301 if ((d = opendir("/proc/self/fd"))) {
2302
2303 struct dirent *de;
2304
2305 while ((de = readdir(d))) {
2306 pa_bool_t found;
2307 long l;
2308 char *e = NULL;
2309 int i;
2310
2311 if (de->d_name[0] == '.')
2312 continue;
2313
2314 errno = 0;
2315 l = strtol(de->d_name, &e, 10);
2316 if (errno != 0 || !e || *e) {
2317 closedir(d);
2318 errno = EINVAL;
2319 return -1;
2320 }
2321
2322 fd = (int) l;
2323
2324 if ((long) fd != l) {
2325 closedir(d);
2326 errno = EINVAL;
2327 return -1;
2328 }
2329
2330 if (fd < 3)
2331 continue;
2332
2333 if (fd == dirfd(d))
2334 continue;
2335
2336 found = FALSE;
2337 for (i = 0; except_fds[i] >= 0; i++)
2338 if (except_fds[i] == fd) {
2339 found = TRUE;
2340 break;
2341 }
2342
2343 if (found)
2344 continue;
2345
2346 if (pa_close(fd) < 0) {
2347 saved_errno = errno;
2348 closedir(d);
2349 errno = saved_errno;
2350
2351 return -1;
2352 }
2353 }
2354
2355 closedir(d);
2356 return 0;
2357 }
2358
2359 #endif
2360
2361 if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
2362 maxfd = (int) rl.rlim_max;
2363 else
2364 maxfd = sysconf(_SC_OPEN_MAX);
2365
2366 for (fd = 3; fd < maxfd; fd++) {
2367 int i;
2368 pa_bool_t found;
2369
2370 found = FALSE;
2371 for (i = 0; except_fds[i] >= 0; i++)
2372 if (except_fds[i] == fd) {
2373 found = TRUE;
2374 break;
2375 }
2376
2377 if (found)
2378 continue;
2379
2380 if (pa_close(fd) < 0 && errno != EBADF)
2381 return -1;
2382 }
2383 #endif /* !OS_IS_WIN32 */
2384
2385 return 0;
2386 }
2387
2388 int pa_unblock_sigs(int except, ...) {
2389 va_list ap;
2390 unsigned n = 0, i;
2391 int r, *p;
2392
2393 va_start(ap, except);
2394
2395 if (except >= 1)
2396 for (n = 1; va_arg(ap, int) >= 0; n++)
2397 ;
2398
2399 va_end(ap);
2400
2401 p = pa_xnew(int, n+1);
2402
2403 va_start(ap, except);
2404
2405 i = 0;
2406 if (except >= 1) {
2407 int sig;
2408 p[i++] = except;
2409
2410 while ((sig = va_arg(ap, int)) >= 0)
2411 p[i++] = sig;
2412 }
2413 p[i] = -1;
2414
2415 va_end(ap);
2416
2417 r = pa_unblock_sigsv(p);
2418 pa_xfree(p);
2419
2420 return r;
2421 }
2422
2423 int pa_unblock_sigsv(const int except[]) {
2424 #ifndef OS_IS_WIN32
2425 int i;
2426 sigset_t ss;
2427
2428 if (sigemptyset(&ss) < 0)
2429 return -1;
2430
2431 for (i = 0; except[i] > 0; i++)
2432 if (sigaddset(&ss, except[i]) < 0)
2433 return -1;
2434
2435 return sigprocmask(SIG_SETMASK, &ss, NULL);
2436 #else
2437 return 0;
2438 #endif
2439 }
2440
2441 int pa_reset_sigs(int except, ...) {
2442 va_list ap;
2443 unsigned n = 0, i;
2444 int *p, r;
2445
2446 va_start(ap, except);
2447
2448 if (except >= 1)
2449 for (n = 1; va_arg(ap, int) >= 0; n++)
2450 ;
2451
2452 va_end(ap);
2453
2454 p = pa_xnew(int, n+1);
2455
2456 va_start(ap, except);
2457
2458 i = 0;
2459 if (except >= 1) {
2460 int sig;
2461 p[i++] = except;
2462
2463 while ((sig = va_arg(ap, int)) >= 0)
2464 p[i++] = sig;
2465 }
2466 p[i] = -1;
2467
2468 va_end(ap);
2469
2470 r = pa_reset_sigsv(p);
2471 pa_xfree(p);
2472
2473 return r;
2474 }
2475
2476 int pa_reset_sigsv(const int except[]) {
2477 #ifndef OS_IS_WIN32
2478 int sig;
2479
2480 for (sig = 1; sig < NSIG; sig++) {
2481 pa_bool_t reset = TRUE;
2482
2483 switch (sig) {
2484 case SIGKILL:
2485 case SIGSTOP:
2486 reset = FALSE;
2487 break;
2488
2489 default: {
2490 int i;
2491
2492 for (i = 0; except[i] > 0; i++) {
2493 if (sig == except[i]) {
2494 reset = FALSE;
2495 break;
2496 }
2497 }
2498 }
2499 }
2500
2501 if (reset) {
2502 struct sigaction sa;
2503
2504 memset(&sa, 0, sizeof(sa));
2505 sa.sa_handler = SIG_DFL;
2506
2507 /* On Linux the first two RT signals are reserved by
2508 * glibc, and sigaction() will return EINVAL for them. */
2509 if ((sigaction(sig, &sa, NULL) < 0))
2510 if (errno != EINVAL)
2511 return -1;
2512 }
2513 }
2514 #endif
2515
2516 return 0;
2517 }
2518
2519 void pa_set_env(const char *key, const char *value) {
2520 pa_assert(key);
2521 pa_assert(value);
2522
2523 /* This is not thread-safe */
2524
2525 #ifdef OS_IS_WIN32
2526 SetEnvironmentVariable(key, value);
2527 #else
2528 setenv(key, value, 1);
2529 #endif
2530 }
2531
2532 void pa_set_env_and_record(const char *key, const char *value) {
2533 pa_assert(key);
2534 pa_assert(value);
2535
2536 /* This is not thread-safe */
2537
2538 pa_set_env(key, value);
2539 recorded_env = pa_strlist_prepend(recorded_env, key);
2540 }
2541
2542 void pa_unset_env_recorded(void) {
2543
2544 /* This is not thread-safe */
2545
2546 for (;;) {
2547 char *s;
2548
2549 recorded_env = pa_strlist_pop(recorded_env, &s);
2550
2551 if (!s)
2552 break;
2553
2554 #ifdef OS_IS_WIN32
2555 SetEnvironmentVariable(s, NULL);
2556 #else
2557 unsetenv(s);
2558 #endif
2559 pa_xfree(s);
2560 }
2561 }
2562
2563 pa_bool_t pa_in_system_mode(void) {
2564 const char *e;
2565
2566 if (!(e = getenv("PULSE_SYSTEM")))
2567 return FALSE;
2568
2569 return !!atoi(e);
2570 }
2571
2572 char *pa_get_user_name_malloc(void) {
2573 ssize_t k;
2574 char *u;
2575
2576 #ifdef _SC_LOGIN_NAME_MAX
2577 k = (ssize_t) sysconf(_SC_LOGIN_NAME_MAX);
2578
2579 if (k <= 0)
2580 #endif
2581 k = 32;
2582
2583 u = pa_xnew(char, k+1);
2584
2585 if (!(pa_get_user_name(u, k))) {
2586 pa_xfree(u);
2587 return NULL;
2588 }
2589
2590 return u;
2591 }
2592
2593 char *pa_get_host_name_malloc(void) {
2594 size_t l;
2595
2596 l = 100;
2597 for (;;) {
2598 char *c;
2599
2600 c = pa_xmalloc(l);
2601
2602 if (!pa_get_host_name(c, l)) {
2603
2604 if (errno != EINVAL && errno != ENAMETOOLONG)
2605 break;
2606
2607 } else if (strlen(c) < l-1) {
2608 char *u;
2609
2610 if (*c == 0) {
2611 pa_xfree(c);
2612 break;
2613 }
2614
2615 u = pa_utf8_filter(c);
2616 pa_xfree(c);
2617 return u;
2618 }
2619
2620 /* Hmm, the hostname is as long the space we offered the
2621 * function, we cannot know if it fully fit in, so let's play
2622 * safe and retry. */
2623
2624 pa_xfree(c);
2625 l *= 2;
2626 }
2627
2628 return NULL;
2629 }
2630
2631 char *pa_machine_id(void) {
2632 FILE *f;
2633 char *h;
2634
2635 /* The returned value is supposed be some kind of ascii identifier
2636 * that is unique and stable across reboots. */
2637
2638 /* First we try the D-Bus UUID, which is the best option we have,
2639 * since it fits perfectly our needs and is not as volatile as the
2640 * hostname which might be set from dhcp. */
2641
2642 if ((f = pa_fopen_cloexec(PA_MACHINE_ID, "r"))) {
2643 char ln[34] = "", *r;
2644
2645 r = fgets(ln, sizeof(ln)-1, f);
2646 fclose(f);
2647
2648 pa_strip_nl(ln);
2649
2650 if (r && ln[0])
2651 return pa_utf8_filter(ln);
2652 }
2653
2654 if ((h = pa_get_host_name_malloc()))
2655 return h;
2656
2657 #ifndef OS_IS_WIN32
2658 /* If no hostname was set we use the POSIX hostid. It's usually
2659 * the IPv4 address. Might not be that stable. */
2660 return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
2661 #else
2662 return NULL;
2663 #endif
2664 }
2665
2666 char *pa_session_id(void) {
2667 const char *e;
2668
2669 if (!(e = getenv("XDG_SESSION_COOKIE")))
2670 return NULL;
2671
2672 return pa_utf8_filter(e);
2673 }
2674
2675 char *pa_uname_string(void) {
2676 #ifdef HAVE_UNAME
2677 struct utsname u;
2678
2679 pa_assert_se(uname(&u) >= 0);
2680
2681 return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
2682 #endif
2683 #ifdef OS_IS_WIN32
2684 OSVERSIONINFO i;
2685
2686 pa_zero(i);
2687 i.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
2688 pa_assert_se(GetVersionEx(&i));
2689
2690 return pa_sprintf_malloc("Windows %d.%d (%d) %s", i.dwMajorVersion, i.dwMinorVersion, i.dwBuildNumber, i.szCSDVersion);
2691 #endif
2692 }
2693
2694 #ifdef HAVE_VALGRIND_MEMCHECK_H
2695 pa_bool_t pa_in_valgrind(void) {
2696 static int b = 0;
2697
2698 /* To make heisenbugs a bit simpler to find we check for $VALGRIND
2699 * here instead of really checking whether we run in valgrind or
2700 * not. */
2701
2702 if (b < 1)
2703 b = getenv("VALGRIND") ? 2 : 1;
2704
2705 return b > 1;
2706 }
2707 #endif
2708
2709 unsigned pa_gcd(unsigned a, unsigned b) {
2710
2711 while (b > 0) {
2712 unsigned t = b;
2713 b = a % b;
2714 a = t;
2715 }
2716
2717 return a;
2718 }
2719
2720 void pa_reduce(unsigned *num, unsigned *den) {
2721
2722 unsigned gcd = pa_gcd(*num, *den);
2723
2724 if (gcd <= 0)
2725 return;
2726
2727 *num /= gcd;
2728 *den /= gcd;
2729
2730 pa_assert(pa_gcd(*num, *den) == 1);
2731 }
2732
2733 unsigned pa_ncpus(void) {
2734 long ncpus;
2735
2736 #ifdef _SC_NPROCESSORS_CONF
2737 ncpus = sysconf(_SC_NPROCESSORS_CONF);
2738 #else
2739 ncpus = 1;
2740 #endif
2741
2742 return ncpus <= 0 ? 1 : (unsigned) ncpus;
2743 }
2744
2745 char *pa_replace(const char*s, const char*a, const char *b) {
2746 pa_strbuf *sb;
2747 size_t an;
2748
2749 pa_assert(s);
2750 pa_assert(a);
2751 pa_assert(b);
2752
2753 an = strlen(a);
2754 sb = pa_strbuf_new();
2755
2756 for (;;) {
2757 const char *p;
2758
2759 if (!(p = strstr(s, a)))
2760 break;
2761
2762 pa_strbuf_putsn(sb, s, p-s);
2763 pa_strbuf_puts(sb, b);
2764 s = p + an;
2765 }
2766
2767 pa_strbuf_puts(sb, s);
2768
2769 return pa_strbuf_tostring_free(sb);
2770 }
2771
2772 char *pa_escape(const char *p, const char *chars) {
2773 const char *s;
2774 const char *c;
2775 pa_strbuf *buf = pa_strbuf_new();
2776
2777 for (s = p; *s; ++s) {
2778 if (*s == '\\')
2779 pa_strbuf_putc(buf, '\\');
2780 else if (chars) {
2781 for (c = chars; *c; ++c) {
2782 if (*s == *c) {
2783 pa_strbuf_putc(buf, '\\');
2784 break;
2785 }
2786 }
2787 }
2788 pa_strbuf_putc(buf, *s);
2789 }
2790
2791 return pa_strbuf_tostring_free(buf);
2792 }
2793
2794 char *pa_unescape(char *p) {
2795 char *s, *d;
2796 pa_bool_t escaped = FALSE;
2797
2798 for (s = p, d = p; *s; s++) {
2799 if (!escaped && *s == '\\') {
2800 escaped = TRUE;
2801 continue;
2802 }
2803
2804 *(d++) = *s;
2805 escaped = FALSE;
2806 }
2807
2808 *d = 0;
2809
2810 return p;
2811 }
2812
2813 char *pa_realpath(const char *path) {
2814 char *t;
2815 pa_assert(path);
2816
2817 /* We want only abolsute paths */
2818 if (path[0] != '/') {
2819 errno = EINVAL;
2820 return NULL;
2821 }
2822
2823 #if defined(__GLIBC__) || defined(__APPLE__)
2824 {
2825 char *r;
2826
2827 if (!(r = realpath(path, NULL)))
2828 return NULL;
2829
2830 /* We copy this here in case our pa_xmalloc() is not
2831 * implemented on top of libc malloc() */
2832 t = pa_xstrdup(r);
2833 pa_xfree(r);
2834 }
2835 #elif defined(PATH_MAX)
2836 {
2837 char *path_buf;
2838 path_buf = pa_xmalloc(PATH_MAX);
2839
2840 #if defined(OS_IS_WIN32)
2841 if (!(t = _fullpath(path_buf, path, _MAX_PATH))) {
2842 pa_xfree(path_buf);
2843 return NULL;
2844 }
2845 #else
2846 if (!(t = realpath(path, path_buf))) {
2847 pa_xfree(path_buf);
2848 return NULL;
2849 }
2850 #endif
2851 }
2852 #else
2853 #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."
2854 #endif
2855
2856 return t;
2857 }
2858
2859 void pa_disable_sigpipe(void) {
2860
2861 #ifdef SIGPIPE
2862 struct sigaction sa;
2863
2864 pa_zero(sa);
2865
2866 if (sigaction(SIGPIPE, NULL, &sa) < 0) {
2867 pa_log("sigaction(): %s", pa_cstrerror(errno));
2868 return;
2869 }
2870
2871 sa.sa_handler = SIG_IGN;
2872
2873 if (sigaction(SIGPIPE, &sa, NULL) < 0) {
2874 pa_log("sigaction(): %s", pa_cstrerror(errno));
2875 return;
2876 }
2877 #endif
2878 }
2879
2880 void pa_xfreev(void**a) {
2881 void **p;
2882
2883 if (!a)
2884 return;
2885
2886 for (p = a; *p; p++)
2887 pa_xfree(*p);
2888
2889 pa_xfree(a);
2890 }
2891
2892 char **pa_split_spaces_strv(const char *s) {
2893 char **t, *e;
2894 unsigned i = 0, n = 8;
2895 const char *state = NULL;
2896
2897 t = pa_xnew(char*, n);
2898 while ((e = pa_split_spaces(s, &state))) {
2899 t[i++] = e;
2900
2901 if (i >= n) {
2902 n *= 2;
2903 t = pa_xrenew(char*, t, n);
2904 }
2905 }
2906
2907 if (i <= 0) {
2908 pa_xfree(t);
2909 return NULL;
2910 }
2911
2912 t[i] = NULL;
2913 return t;
2914 }
2915
2916 char* pa_maybe_prefix_path(const char *path, const char *prefix) {
2917 pa_assert(path);
2918
2919 if (pa_is_path_absolute(path))
2920 return pa_xstrdup(path);
2921
2922 return pa_sprintf_malloc("%s" PA_PATH_SEP "%s", prefix, path);
2923 }
2924
2925 size_t pa_pipe_buf(int fd) {
2926
2927 #ifdef _PC_PIPE_BUF
2928 long n;
2929
2930 if ((n = fpathconf(fd, _PC_PIPE_BUF)) >= 0)
2931 return (size_t) n;
2932 #endif
2933
2934 #ifdef PIPE_BUF
2935 return PIPE_BUF;
2936 #else
2937 return 4096;
2938 #endif
2939 }
2940
2941 void pa_reset_personality(void) {
2942
2943 #ifdef __linux__
2944 if (personality(PER_LINUX) < 0)
2945 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno));
2946 #endif
2947
2948 }
2949
2950 #if defined(__linux__) && !defined(__OPTIMIZE__)
2951
2952 pa_bool_t pa_run_from_build_tree(void) {
2953 char *rp;
2954 pa_bool_t b = FALSE;
2955
2956 /* We abuse __OPTIMIZE__ as a check whether we are a debug build
2957 * or not. */
2958
2959 if ((rp = pa_readlink("/proc/self/exe"))) {
2960 b = pa_startswith(rp, PA_BUILDDIR);
2961 pa_xfree(rp);
2962 }
2963
2964 return b;
2965 }
2966
2967 #endif
2968
2969 const char *pa_get_temp_dir(void) {
2970 const char *t;
2971
2972 if ((t = getenv("TMPDIR")) &&
2973 pa_is_path_absolute(t))
2974 return t;
2975
2976 if ((t = getenv("TMP")) &&
2977 pa_is_path_absolute(t))
2978 return t;
2979
2980 if ((t = getenv("TEMP")) &&
2981 pa_is_path_absolute(t))
2982 return t;
2983
2984 if ((t = getenv("TEMPDIR")) &&
2985 pa_is_path_absolute(t))
2986 return t;
2987
2988 return "/tmp";
2989 }
2990
2991 int pa_open_cloexec(const char *fn, int flags, mode_t mode) {
2992 int fd;
2993
2994 #ifdef O_NOCTTY
2995 flags |= O_NOCTTY;
2996 #endif
2997
2998 #ifdef O_CLOEXEC
2999 if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0)
3000 goto finish;
3001
3002 if (errno != EINVAL)
3003 return fd;
3004 #endif
3005
3006 if ((fd = open(fn, flags, mode)) < 0)
3007 return fd;
3008
3009 finish:
3010 /* Some implementations might simply ignore O_CLOEXEC if it is not
3011 * understood, make sure FD_CLOEXEC is enabled anyway */
3012
3013 pa_make_fd_cloexec(fd);
3014 return fd;
3015 }
3016
3017 int pa_socket_cloexec(int domain, int type, int protocol) {
3018 int fd;
3019
3020 #ifdef SOCK_CLOEXEC
3021 if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0)
3022 goto finish;
3023
3024 if (errno != EINVAL)
3025 return fd;
3026 #endif
3027
3028 if ((fd = socket(domain, type, protocol)) < 0)
3029 return fd;
3030
3031 finish:
3032 /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3033 * not understood, make sure FD_CLOEXEC is enabled anyway */
3034
3035 pa_make_fd_cloexec(fd);
3036 return fd;
3037 }
3038
3039 int pa_pipe_cloexec(int pipefd[2]) {
3040 int r;
3041
3042 #ifdef HAVE_PIPE2
3043 if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0)
3044 goto finish;
3045
3046 if (errno != EINVAL && errno != ENOSYS)
3047 return r;
3048
3049 #endif
3050
3051 if ((r = pipe(pipefd)) < 0)
3052 return r;
3053
3054 finish:
3055 pa_make_fd_cloexec(pipefd[0]);
3056 pa_make_fd_cloexec(pipefd[1]);
3057
3058 return 0;
3059 }
3060
3061 int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
3062 int fd;
3063
3064 #ifdef HAVE_ACCEPT4
3065 if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0)
3066 goto finish;
3067
3068 if (errno != EINVAL && errno != ENOSYS)
3069 return fd;
3070
3071 #endif
3072
3073 if ((fd = accept(sockfd, addr, addrlen)) < 0)
3074 return fd;
3075
3076 finish:
3077 pa_make_fd_cloexec(fd);
3078 return fd;
3079 }
3080
3081 FILE* pa_fopen_cloexec(const char *path, const char *mode) {
3082 FILE *f;
3083 char *m;
3084
3085 m = pa_sprintf_malloc("%se", mode);
3086
3087 errno = 0;
3088 if ((f = fopen(path, m))) {
3089 pa_xfree(m);
3090 goto finish;
3091 }
3092
3093 pa_xfree(m);
3094
3095 if (errno != EINVAL)
3096 return NULL;
3097
3098 if (!(f = fopen(path, mode)))
3099 return NULL;
3100
3101 finish:
3102 pa_make_fd_cloexec(fileno(f));
3103 return f;
3104 }
3105
3106 void pa_nullify_stdfds(void) {
3107
3108 #ifndef OS_IS_WIN32
3109 pa_close(STDIN_FILENO);
3110 pa_close(STDOUT_FILENO);
3111 pa_close(STDERR_FILENO);
3112
3113 pa_assert_se(open("/dev/null", O_RDONLY) == STDIN_FILENO);
3114 pa_assert_se(open("/dev/null", O_WRONLY) == STDOUT_FILENO);
3115 pa_assert_se(open("/dev/null", O_WRONLY) == STDERR_FILENO);
3116 #else
3117 FreeConsole();
3118 #endif
3119
3120 }
3121
3122 char *pa_read_line_from_file(const char *fn) {
3123 FILE *f;
3124 char ln[256] = "", *r;
3125
3126 if (!(f = pa_fopen_cloexec(fn, "r")))
3127 return NULL;
3128
3129 r = fgets(ln, sizeof(ln)-1, f);
3130 fclose(f);
3131
3132 if (!r) {
3133 errno = EIO;
3134 return NULL;
3135 }
3136
3137 pa_strip_nl(ln);
3138 return pa_xstrdup(ln);
3139 }
3140
3141 pa_bool_t pa_running_in_vm(void) {
3142
3143 #if defined(__i386__) || defined(__x86_64__)
3144
3145 /* Both CPUID and DMI are x86 specific interfaces... */
3146
3147 uint32_t eax = 0x40000000;
3148 union {
3149 uint32_t sig32[3];
3150 char text[13];
3151 } sig;
3152
3153 #ifdef __linux__
3154 const char *const dmi_vendors[] = {
3155 "/sys/class/dmi/id/sys_vendor",
3156 "/sys/class/dmi/id/board_vendor",
3157 "/sys/class/dmi/id/bios_vendor"
3158 };
3159
3160 unsigned i;
3161
3162 for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) {
3163 char *s;
3164
3165 if ((s = pa_read_line_from_file(dmi_vendors[i]))) {
3166
3167 if (pa_startswith(s, "QEMU") ||
3168 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3169 pa_startswith(s, "VMware") ||
3170 pa_startswith(s, "VMW") ||
3171 pa_startswith(s, "Microsoft Corporation") ||
3172 pa_startswith(s, "innotek GmbH") ||
3173 pa_startswith(s, "Xen")) {
3174
3175 pa_xfree(s);
3176 return TRUE;
3177 }
3178
3179 pa_xfree(s);
3180 }
3181 }
3182
3183 #endif
3184
3185 /* http://lwn.net/Articles/301888/ */
3186 pa_zero(sig);
3187
3188 __asm__ __volatile__ (
3189 /* ebx/rbx is being used for PIC! */
3190 " push %%"PA_REG_b" \n\t"
3191 " cpuid \n\t"
3192 " mov %%ebx, %1 \n\t"
3193 " pop %%"PA_REG_b" \n\t"
3194
3195 : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2])
3196 : "0" (eax)
3197 );
3198
3199 if (pa_streq(sig.text, "XenVMMXenVMM") ||
3200 pa_streq(sig.text, "KVMKVMKVM") ||
3201 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3202 pa_streq(sig.text, "VMwareVMware") ||
3203 /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
3204 pa_streq(sig.text, "Microsoft Hv"))
3205 return TRUE;
3206
3207 #endif
3208
3209 return FALSE;
3210 }