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