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