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