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