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