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