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