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