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