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