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