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