pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) { pa_socket_server *ss; int fd = -1; struct sockaddr_in sa; int on = 1; pa_assert(m); pa_assert(port); if ((fd = pa_socket_cloexec(PF_INET, SOCK_STREAM, 0)) < 0) { pa_log("socket(PF_INET): %s", pa_cstrerror(errno)); goto fail; } #ifdef SO_REUSEADDR if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(on)) < 0) pa_log("setsockopt(): %s", pa_cstrerror(errno)); #endif pa_make_tcp_socket_low_delay(fd); memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(port); sa.sin_addr.s_addr = htonl(address); if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { if (errno == EADDRINUSE && fallback) { sa.sin_port = 0; if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) >= 0) goto good; } pa_log("bind(): %s", pa_cstrerror(errno)); goto fail; good: ; } if (listen(fd, 5) < 0) { pa_log("listen(): %s", pa_cstrerror(errno)); goto fail; } if ((ss = pa_socket_server_new(m, fd))) { ss->type = SOCKET_SERVER_IPV4; ss->tcpwrap_service = pa_xstrdup(tcpwrap_service); } return ss; fail: if (fd >= 0) pa_close(fd); return NULL; }
pa_inotify *pa_inotify_start(const char *filename, void *userdata, pa_inotify_cb cb, pa_core *core) { pa_inotify *i = pa_xnew0(pa_inotify, 1); pa_assert(i); i->core = core; pa_core_ref(core); i->filename = pa_xstrdup(filename); i->callback_data = userdata; i->callback = cb; i->fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK); if (i->fd < 0) { pa_log("inotify_init1() failed: %s", pa_cstrerror(errno)); pa_inotify_stop(i); return NULL; } if (inotify_add_watch(i->fd, filename, IN_DELETE_SELF|IN_MOVE_SELF) < 0) { pa_log("inotify_add_watch() failed: %s", pa_cstrerror(errno)); pa_inotify_stop(i); return NULL; } pa_assert_se(i->io_event = core->mainloop->io_new(core->mainloop, i->fd, PA_IO_EVENT_INPUT, inotify_cb, i)); return i; }
static void save(struct userdata *u) { FILE *f; if (!u->modified) return; if (u->sink_filename) { if ((f = pa_fopen_cloexec(u->sink_filename, "w"))) { pa_sink *s = pa_namereg_get_default_sink(u->core); fprintf(f, "%s\n", s ? s->name : ""); fclose(f); } else pa_log("Failed to save default sink: %s", pa_cstrerror(errno)); } if (u->source_filename) { if ((f = pa_fopen_cloexec(u->source_filename, "w"))) { pa_source *s = pa_namereg_get_default_source(u->core); fprintf(f, "%s\n", s ? s->name : ""); fclose(f); } else pa_log("Failed to save default source: %s", pa_cstrerror(errno)); } u->modified = false; }
static int privatemem_create(pa_shm *m, size_t size) { pa_assert(m); pa_assert(size > 0); m->type = PA_MEM_TYPE_PRIVATE; m->id = 0; m->size = size; m->do_unlink = false; m->fd = -1; #ifdef MAP_ANONYMOUS if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) { pa_log("mmap() failed: %s", pa_cstrerror(errno)); return -1; } #elif defined(HAVE_POSIX_MEMALIGN) { int r; if ((r = posix_memalign(&m->ptr, PA_PAGE_SIZE, size)) < 0) { pa_log("posix_memalign() failed: %s", pa_cstrerror(r)); return r; } } #else m->ptr = pa_xmalloc(m->size); #endif return 0; }
void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn) { FILE *f; void *p; pa_assert(c); pa_assert(fn); /* Only for debugging purposes */ f = pa_fopen_cloexec(fn, "a"); if (!f) { pa_log_warn("Failed to open '%s': %s", fn, pa_cstrerror(errno)); return; } p = pa_memblock_acquire(c->memblock); if (fwrite((uint8_t*) p + c->index, 1, c->length, f) != c->length) pa_log_warn("Failed to write to '%s': %s", fn, pa_cstrerror(errno)); pa_memblock_release(c->memblock); fclose(f); }
static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { pa_bluetooth_device *d = t->device; struct sockaddr_sco addr; int err, i; int sock; bdaddr_t src; bdaddr_t dst; const char *src_addr, *dst_addr; src_addr = d->adapter->address; dst_addr = d->address; /* don't use ba2str to avoid -lbluetooth */ for (i = 5; i >= 0; i--, src_addr += 3) src.b[i] = strtol(src_addr, NULL, 16); for (i = 5; i >= 0; i--, dst_addr += 3) dst.b[i] = strtol(dst_addr, NULL, 16); sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); if (sock < 0) { pa_log_error("socket(SEQPACKET, SCO) %s", pa_cstrerror(errno)); return -1; } memset(&addr, 0, sizeof(addr)); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, &src); if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { pa_log_error("bind(): %s", pa_cstrerror(errno)); goto fail_close; } memset(&addr, 0, sizeof(addr)); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, &dst); pa_log_info ("doing connect\n"); err = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) { pa_log_error("connect(): %s", pa_cstrerror(errno)); goto fail_close; } /* The "48" below is hardcoded until we get meaningful MTU values exposed * by the kernel */ if (imtu) *imtu = 48; if (omtu) *omtu = 48; return sock; fail_close: close(sock); return -1; }
static int do_write(struct userdata *u) { ssize_t r; pa_assert(u); if (!pa_iochannel_is_writable(u->io)) return 0; if (u->write_data) { pa_assert(u->write_index < u->write_length); if ((r = pa_iochannel_write(u->io, (uint8_t*) u->write_data + u->write_index, u->write_length - u->write_index)) <= 0) { pa_log("write() failed: %s", pa_cstrerror(errno)); return -1; } u->write_index += (size_t) r; pa_assert(u->write_index <= u->write_length); if (u->write_index == u->write_length) { pa_xfree(u->write_data); u->write_data = NULL; u->write_index = u->write_length = 0; } } if (!u->write_data && u->state == STATE_PREPARE) { int so_sndbuf = 0; socklen_t sl = sizeof(int); /* OK, we're done with sending all control data we need to, so * let's hand the socket over to the IO thread now */ pa_assert(u->fd < 0); u->fd = pa_iochannel_get_send_fd(u->io); pa_iochannel_set_noclose(u->io, TRUE); pa_iochannel_free(u->io); u->io = NULL; pa_make_tcp_socket_low_delay(u->fd); if (getsockopt(u->fd, SOL_SOCKET, SO_SNDBUF, &so_sndbuf, &sl) < 0) pa_log_warn("getsockopt(SO_SNDBUF) failed: %s", pa_cstrerror(errno)); else { pa_log_debug("SO_SNDBUF is %zu.", (size_t) so_sndbuf); pa_sink_set_max_request(u->sink, PA_MAX((size_t) so_sndbuf, u->block_size)); } pa_log_debug("Connection authenticated, handing fd to IO thread..."); pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_PASS_SOCKET, NULL, 0, NULL, NULL); u->state = STATE_RUNNING; } return 0; }
static int open_pid_file(const char *fn, int mode) { int fd; pa_assert(fn); for (;;) { struct stat st; if ((fd = pa_open_cloexec(fn, mode #ifdef O_NOFOLLOW |O_NOFOLLOW #endif , S_IRUSR|S_IWUSR )) < 0) { if (mode != O_RDONLY || errno != ENOENT) pa_log_warn("Failed to open PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } /* Try to lock the file. If that fails, go without */ if (pa_lock_fd(fd, 1) < 0) goto fail; if (fstat(fd, &st) < 0) { pa_log_warn("Failed to fstat() PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } /* Does the file still exist in the file system? When yes, we're done, otherwise restart */ if (st.st_nlink >= 1) break; if (pa_lock_fd(fd, 0) < 0) goto fail; if (pa_close(fd) < 0) { pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno)); fd = -1; goto fail; } } return fd; fail: if (fd >= 0) { int saved_errno = errno; pa_lock_fd(fd, 0); pa_close(fd); errno = saved_errno; } return -1; }
/* Load an authorization cookie from file fn and store it in data. If * the cookie file doesn't exist, create it */ static int load(const char *fn, void *data, size_t length) { int fd = -1; int writable = 1; int unlock = 0, ret = -1; ssize_t r; pa_assert(fn); pa_assert(data); pa_assert(length > 0); if ((fd = pa_open_cloexec(fn, O_RDWR|O_CREAT|O_BINARY, S_IRUSR|S_IWUSR)) < 0) { if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY)) < 0) { pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } else writable = 0; } unlock = pa_lock_fd(fd, 1) >= 0; if ((r = pa_loop_read(fd, data, length, NULL)) < 0) { pa_log("Failed to read cookie file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } if ((size_t) r != length) { pa_log_debug("Got %d bytes from cookie file '%s', expected %d", (int) r, fn, (int) length); if (!writable) { pa_log_warn("Unable to write cookie to read-only file"); goto finish; } if (generate(fd, data, length) < 0) goto finish; } ret = 0; finish: if (fd >= 0) { if (unlock) pa_lock_fd(fd, 0); if (pa_close(fd) < 0) { pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno)); ret = -1; } } return ret; }
static int sco_do_connect(pa_bluetooth_transport *t) { pa_bluetooth_device *d = t->device; struct sockaddr_sco addr; socklen_t len; int err, i; int sock; bdaddr_t src; bdaddr_t dst; const char *src_addr, *dst_addr; src_addr = d->adapter->address; dst_addr = d->address; /* don't use ba2str to avoid -lbluetooth */ for (i = 5; i >= 0; i--, src_addr += 3) src.b[i] = strtol(src_addr, NULL, 16); for (i = 5; i >= 0; i--, dst_addr += 3) dst.b[i] = strtol(dst_addr, NULL, 16); sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); if (sock < 0) { pa_log_error("socket(SEQPACKET, SCO) %s", pa_cstrerror(errno)); return -1; } len = sizeof(addr); memset(&addr, 0, len); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, &src); if (bind(sock, (struct sockaddr *) &addr, len) < 0) { pa_log_error("bind(): %s", pa_cstrerror(errno)); goto fail_close; } memset(&addr, 0, len); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, &dst); pa_log_info("doing connect"); err = connect(sock, (struct sockaddr *) &addr, len); if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) { pa_log_error("connect(): %s", pa_cstrerror(errno)); goto fail_close; } return sock; fail_close: close(sock); return -1; }
int pa_shm_attach(pa_shm *m, unsigned id, bool writable) { char fn[32]; int fd = -1; int prot; struct stat st; pa_assert(m); segment_name(fn, sizeof(fn), m->id = id); if ((fd = shm_open(fn, writable ? O_RDWR : O_RDONLY, 0)) < 0) { if (errno != EACCES && errno != ENOENT) pa_log("shm_open() failed: %s", pa_cstrerror(errno)); goto fail; } if (fstat(fd, &st) < 0) { pa_log("fstat() failed: %s", pa_cstrerror(errno)); goto fail; } if (st.st_size <= 0 || st.st_size > (off_t) (MAX_SHM_SIZE+SHM_MARKER_SIZE) || PA_ALIGN((size_t) st.st_size) != (size_t) st.st_size) { pa_log("Invalid shared memory segment size"); goto fail; } m->size = (size_t) st.st_size; prot = writable ? PROT_READ | PROT_WRITE : PROT_READ; if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), prot, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) { pa_log("mmap() failed: %s", pa_cstrerror(errno)); goto fail; } m->do_unlink = false; m->shared = true; pa_assert_se(pa_close(fd) == 0); return 0; fail: if (fd >= 0) pa_close(fd); return -1; }
pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *filename) { int fd = -1; struct sockaddr_un sa; pa_socket_server *s; pa_assert(m); pa_assert(filename); if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) { pa_log("socket(): %s", pa_cstrerror(errno)); goto fail; } memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_UNIX; pa_strlcpy(sa.sun_path, filename, sizeof(sa.sun_path)); pa_make_socket_low_delay(fd); if (bind(fd, (struct sockaddr*) &sa, (socklen_t) SUN_LEN(&sa)) < 0) { pa_log("bind(): %s", pa_cstrerror(errno)); goto fail; } /* Allow access from all clients. Sockets like this one should * always be put inside a directory with proper access rights, * because not all OS check the access rights on the socket * inodes. */ chmod(filename, 0777); if (listen(fd, 5) < 0) { pa_log("listen(): %s", pa_cstrerror(errno)); goto fail; } pa_assert_se(s = pa_socket_server_new(m, fd)); s->filename = pa_xstrdup(filename); s->type = SOCKET_SERVER_UNIX; return s; fail: if (fd >= 0) pa_close(fd); return NULL; }
static void set_microphone_gain(pa_bluetooth_transport *t, uint16_t gain) { struct transport_data *trd = t->userdata; char buf[512]; ssize_t len, written; if (t->microphone_gain == gain) return; t->microphone_gain = gain; /* If we are in the AG role, we send a command to the head set to change * the microphone gain. In the HS role, source and sink are swapped, so * in this case we notify the AG that the speaker gain has changed */ if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT) { len = sprintf(buf, "\r\n+VGM=%d\r\n", gain); pa_log_debug("RFCOMM >> +VGM=%d", gain); } else { len = sprintf(buf, "\r\nAT+VGS=%d\r\n", gain); pa_log_debug("RFCOMM >> AT+VGS=%d", gain); } written = write (trd->rfcomm_fd, buf, len); if (written != len) pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno)); }
/* Read the PID data from the file descriptor fd, and return it. If no * pid could be read, return 0, on failure (pid_t) -1 */ static pid_t read_pid(const char *fn, int fd) { ssize_t r; char t[20], *e; uint32_t pid; pa_assert(fn); pa_assert(fd >= 0); if ((r = pa_loop_read(fd, t, sizeof(t)-1, NULL)) < 0) { pa_log_warn("Failed to read PID file '%s': %s", fn, pa_cstrerror(errno)); return (pid_t) -1; } if (r == 0) return (pid_t) 0; t[r] = 0; if ((e = strchr(t, '\n'))) *e = 0; if (pa_atou(t, &pid) < 0) { pa_log_warn("Failed to parse PID file '%s'", fn); errno = EINVAL; return (pid_t) -1; } return (pid_t) pid; }
int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; uint32_t pid = 0; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs)) || pa_modargs_get_value_u32(ma, "pid", &pid) < 0 || !pid) { pa_log("Failed to parse module arguments"); goto finish; } if (kill((pid_t) pid, SIGUSR1) < 0) pa_log_warn("kill(%u) failed: %s", pid, pa_cstrerror(errno)); pa_module_unload_request(m, true); ret = 0; finish: if (ma) pa_modargs_free(ma); return ret; }
static int detect_solaris(pa_core *c, int just_one) { struct stat s; const char *dev; char args[64]; dev = getenv("AUDIODEV"); if (!dev) dev = "/dev/audio"; if (stat(dev, &s) < 0) { if (errno != ENOENT) pa_log_error("failed to open device %s: %s", dev, pa_cstrerror(errno)); return -1; } if (!S_ISCHR(s.st_mode)) return 0; pa_snprintf(args, sizeof(args), "device=%s", dev); if (!pa_module_load(c, "module-solaris", args)) return 0; return 1; }
int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; int32_t fd = -1; char x = 1; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs)) || pa_modargs_get_value_s32(ma, "fd", &fd) < 0 || fd < 0) { pa_log("Failed to parse module arguments"); goto finish; } if (pa_loop_write(fd, &x, sizeof(x), NULL) != sizeof(x)) pa_log_warn("write(%u, 1, 1) failed: %s", fd, pa_cstrerror(errno)); pa_assert_se(pa_close(fd) == 0); pa_module_unload_request(m, true); ret = 0; finish: if (ma) pa_modargs_free(ma); return ret; }
void pa_rtclock_hrtimer_enable(void) { #ifdef PR_SET_TIMERSLACK int slack_ns; if ((slack_ns = prctl(PR_GET_TIMERSLACK, 0, 0, 0, 0)) < 0) { pa_log_info("PR_GET_TIMERSLACK/PR_SET_TIMERSLACK not supported."); return; } pa_log_debug("Timer slack is set to %i us.", (int) (slack_ns/PA_NSEC_PER_USEC)); if (slack_ns > TIMER_SLACK_NS) { slack_ns = TIMER_SLACK_NS; pa_log_debug("Setting timer slack to %i us.", (int) (slack_ns/PA_NSEC_PER_USEC)); if (prctl(PR_SET_TIMERSLACK, slack_ns, 0, 0, 0) < 0) { pa_log_warn("PR_SET_TIMERSLACK failed: %s", pa_cstrerror(errno)); return; } } #elif defined(OS_IS_WIN32) LARGE_INTEGER freq; pa_assert_se(QueryPerformanceFrequency(&freq)); counter_freq = freq.QuadPart; #endif }
/* Raise the priority of the current process as much as possible that * is <= the specified nice level..*/ int pa_raise_priority(int nice_level) { #ifdef HAVE_SYS_RESOURCE_H if (setpriority(PRIO_PROCESS, 0, nice_level) < 0) { int n; for (n = nice_level+1; n < 0; n++) { if (setpriority(PRIO_PROCESS, 0, n) == 0) { pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level); return 0; } } pa_log_warn("setpriority(): %s", pa_cstrerror(errno)); return -1; } pa_log_info("Successfully gained nice level %i.", nice_level); #endif #ifdef OS_IS_WIN32 if (nice_level < 0) { if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) { pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError()); return .-1; } else
static int do_read(struct userdata *u) { pa_assert(u); if (!pa_iochannel_is_readable(u->io)) return 0; if (u->state == STATE_AUTH || u->state == STATE_LATENCY) { ssize_t r; if (!u->read_data) return 0; pa_assert(u->read_index < u->read_length); if ((r = pa_iochannel_read(u->io, (uint8_t*) u->read_data + u->read_index, u->read_length - u->read_index)) <= 0) { pa_log("read() failed: %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } u->read_index += (size_t) r; pa_assert(u->read_index <= u->read_length); if (u->read_index == u->read_length) return handle_response(u); } return 0; }
static int do_write(connection *c) { pa_memchunk chunk; ssize_t r; void *p; connection_assert_ref(c); if (!c->source_output) return 0; if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) { /* pa_log("peek failed"); */ return 0; } pa_assert(chunk.memblock); pa_assert(chunk.length); p = pa_memblock_acquire(chunk.memblock); r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length); pa_memblock_release(chunk.memblock); pa_memblock_unref(chunk.memblock); if (r < 0) { pa_log("write(): %s", pa_cstrerror(errno)); return -1; } pa_memblockq_drop(c->output_memblockq, (size_t) r); return 1; }
static int proc_name_ours(pid_t pid, const char *procname) { #ifdef __linux__ char bn[PATH_MAX]; FILE *f; pa_snprintf(bn, sizeof(bn), "/proc/%lu/stat", (unsigned long) pid); if (!(f = pa_fopen_cloexec(bn, "r"))) { pa_log_info("Failed to open %s: %s", bn, pa_cstrerror(errno)); return -1; } else { char *expected; pa_bool_t good; char stored[64]; if (!(fgets(stored, sizeof(stored), f))) { int saved_errno = feof(f) ? EINVAL : errno; pa_log_info("Failed to read from %s: %s", bn, feof(f) ? "EOF" : pa_cstrerror(errno)); fclose(f); errno = saved_errno; return -1; } fclose(f); expected = pa_sprintf_malloc("%lu (%s)", (unsigned long) pid, procname); good = pa_startswith(stored, expected); pa_xfree(expected); /*#if !defined(__OPTIMIZE__)*/ if (!good) { /* libtool likes to rename our binary names ... */ expected = pa_sprintf_malloc("%lu (lt-%s)", (unsigned long) pid, procname); good = pa_startswith(stored, expected); pa_xfree(expected); } /*#endif*/ return !!good; } #else return 1; #endif }
static void load(struct userdata *u) { FILE *f; /* We never overwrite manually configured settings */ if (u->core->configured_default_sink) pa_log_info("Manually configured default sink, not overwriting."); else if ((f = pa_fopen_cloexec(u->sink_filename, "r"))) { char ln[256] = ""; if (fgets(ln, sizeof(ln)-1, f)) pa_strip_nl(ln); fclose(f); if (!ln[0]) pa_log_info("No previous default sink setting, ignoring."); else if (!pa_namereg_is_valid_name(ln)) pa_log_warn("Invalid sink name: %s", ln); else { pa_log_info("Restoring default sink '%s'.", ln); pa_core_set_configured_default_sink(u->core, ln); } } else if (errno != ENOENT) pa_log("Failed to load default sink: %s", pa_cstrerror(errno)); if (u->core->configured_default_source) pa_log_info("Manually configured default source, not overwriting."); else if ((f = pa_fopen_cloexec(u->source_filename, "r"))) { char ln[256] = ""; if (fgets(ln, sizeof(ln)-1, f)) pa_strip_nl(ln); fclose(f); if (!ln[0]) pa_log_info("No previous default source setting, ignoring."); else if (!pa_namereg_is_valid_name(ln)) pa_log_warn("Invalid source name: %s", ln); else { pa_log_info("Restoring default source '%s'.", ln); pa_core_set_configured_default_source(u->core, ln); } } else if (errno != ENOENT) pa_log("Failed to load default source: %s", pa_cstrerror(errno)); }
static void load(struct userdata *u) { FILE *f; /* We never overwrite manually configured settings */ if (u->core->default_sink) pa_log_info("Manually configured default sink, not overwriting."); else if ((f = pa_fopen_cloexec(u->sink_filename, "r"))) { char ln[256] = ""; pa_sink *s; if (fgets(ln, sizeof(ln)-1, f)) pa_strip_nl(ln); fclose(f); if (!ln[0]) pa_log_info("No previous default sink setting, ignoring."); else if ((s = pa_namereg_get(u->core, ln, PA_NAMEREG_SINK))) { pa_namereg_set_default_sink(u->core, s); pa_log_info("Restored default sink '%s'.", ln); } else pa_log_info("Saved default sink '%s' not existent, not restoring default sink setting.", ln); } else if (errno != ENOENT) pa_log("Failed to load default sink: %s", pa_cstrerror(errno)); if (u->core->default_source) pa_log_info("Manually configured default source, not overwriting."); else if ((f = pa_fopen_cloexec(u->source_filename, "r"))) { char ln[256] = ""; pa_source *s; if (fgets(ln, sizeof(ln)-1, f)) pa_strip_nl(ln); fclose(f); if (!ln[0]) pa_log_info("No previous default source setting, ignoring."); else if ((s = pa_namereg_get(u->core, ln, PA_NAMEREG_SOURCE))) { pa_namereg_set_default_source(u->core, s); pa_log_info("Restored default source '%s'.", ln); } else pa_log_info("Saved default source '%s' not existent, not restoring default source setting.", ln); } else if (errno != ENOENT) pa_log("Failed to load default sink: %s", pa_cstrerror(errno)); }
void pa_fdsem_wait(pa_fdsem *f) { pa_assert(f); flush(f); if (pa_atomic_cmpxchg(&f->data->signalled, 1, 0)) return; pa_atomic_inc(&f->data->waiting); while (!pa_atomic_cmpxchg(&f->data->signalled, 1, 0)) { char x[10]; ssize_t r; #ifdef HAVE_SYS_EVENTFD_H if (f->efd >= 0) { uint64_t u; if ((r = pa_read(f->efd, &u, sizeof(u), NULL)) != sizeof(u)) { if (r >= 0 || errno != EINTR) { pa_log_error("Invalid read from eventfd: %s", r < 0 ? pa_cstrerror(errno) : "EOF"); pa_assert_not_reached(); } continue; } r = (ssize_t) u; } else #endif if ((r = pa_read(f->fds[0], &x, sizeof(x), NULL)) <= 0) { if (r >= 0 || errno != EINTR) { pa_log_error("Invalid read from pipe: %s", r < 0 ? pa_cstrerror(errno) : "EOF"); pa_assert_not_reached(); } continue; } pa_atomic_sub(&f->data->in_pipe, (int) r); } pa_assert_se(pa_atomic_dec(&f->data->waiting) >= 1); }
int pa_shm_attach_ro(pa_shm *m, unsigned id) { char fn[32]; int fd = -1; struct stat st; pa_assert(m); segment_name(fn, sizeof(fn), m->id = id); if ((fd = shm_open(fn, O_RDONLY, 0)) < 0) { if (errno != EACCES) pa_log("shm_open() failed: %s", pa_cstrerror(errno)); goto fail; } if (fstat(fd, &st) < 0) { pa_log("fstat() failed: %s", pa_cstrerror(errno)); goto fail; } if (st.st_size <= 0 || st.st_size > (off_t) (MAX_SHM_SIZE+SHM_MARKER_SIZE) || PA_ALIGN((size_t) st.st_size) != (size_t) st.st_size) { pa_log("Invalid shared memory segment size"); goto fail; } m->size = (size_t) st.st_size; if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) { pa_log("mmap() failed: %s", pa_cstrerror(errno)); goto fail; } m->do_unlink = FALSE; m->shared = TRUE; pa_assert_se(pa_close(fd) == 0); return 0; fail: if (fd >= 0) pa_close(fd); return -1; }
char *pa_get_user_name(char *s, size_t l) { const char *p; char buf[1024]; #ifdef HAVE_PWD_H struct passwd pw, *r; #endif pa_assert(s); pa_assert(l > 0); if (!(p = (getuid() == 0 ? "root" : NULL)) && !(p = getenv("USER")) && !(p = getenv("LOGNAME")) && !(p = getenv("USERNAME"))) { #ifdef HAVE_PWD_H #ifdef HAVE_GETPWUID_R if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) { #else /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) * that do not support getpwuid_r. */ if ((r = getpwuid(getuid())) == NULL) { #endif pa_snprintf(s, l, "%lu", (unsigned long) getuid()); return s; } p = r->pw_name; #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */ DWORD size = sizeof(buf); if (!GetUserName(buf, &size)) return NULL; p = buf; #else /* HAVE_PWD_H */ return NULL; #endif /* HAVE_PWD_H */ } return pa_strlcpy(s, p, l); } char *pa_get_host_name(char *s, size_t l) { pa_assert(s); pa_assert(l > 0); if (gethostname(s, l) < 0) { pa_log("gethostname(): %s", pa_cstrerror(errno)); return NULL; } s[l-1] = 0; return s; }
static int detect_alsa(pa_core *c, int just_one) { FILE *f; int n = 0, n_sink = 0, n_source = 0; if (!(f = pa_fopen_cloexec("/proc/asound/devices", "r"))) { if (errno != ENOENT) pa_log_error("open(\"/proc/asound/devices\") failed: %s", pa_cstrerror(errno)); return -1; } while (!feof(f)) { char line[64], args[64]; unsigned device, subdevice; int is_sink; if (!fgets(line, sizeof(line), f)) break; line[strcspn(line, "\r\n")] = 0; if (pa_endswith(line, "digital audio playback")) is_sink = 1; else if (pa_endswith(line, "digital audio capture")) is_sink = 0; else continue; if (just_one && is_sink && n_sink >= 1) continue; if (just_one && !is_sink && n_source >= 1) continue; if (sscanf(line, " %*i: [%u- %u]: ", &device, &subdevice) != 2) continue; /* Only one sink per device */ if (subdevice != 0) continue; pa_snprintf(args, sizeof(args), "device_id=%u", device); if (!pa_module_load(c, is_sink ? "module-alsa-sink" : "module-alsa-source", args)) continue; n++; if (is_sink) n_sink++; else n_source++; } fclose(f); return n; }
static pa_usec_t io_sink_get_latency(struct userdata *u) { pa_usec_t r = 0; pa_assert(u); if (u->use_getodelay) { int arg; #if defined(__NetBSD__) && !defined(SNDCTL_DSP_GETODELAY) #if defined(AUDIO_GETBUFINFO) struct audio_info info; if (syscall(SYS_ioctl, u->fd, AUDIO_GETBUFINFO, &info) < 0) { pa_log_info("Device doesn't support AUDIO_GETBUFINFO: %s", pa_cstrerror(errno)); u->use_getodelay = 0; } else { arg = info.play.seek + info.blocksize / 2; r = pa_bytes_to_usec((size_t) arg, &u->sink->sample_spec); } #else pa_log_info("System doesn't support AUDIO_GETBUFINFO"); u->use_getodelay = 0; #endif #else if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) { pa_log_info("Device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno)); u->use_getodelay = 0; } else r = pa_bytes_to_usec((size_t) arg, &u->sink->sample_spec); #endif } if (!u->use_getodelay && u->use_getospace) { struct audio_buf_info info; if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); u->use_getospace = 0; } else r = pa_bytes_to_usec((size_t) info.bytes, &u->sink->sample_spec); } if (u->memchunk.memblock) r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); return r; }
static int sco_listen(pa_bluetooth_transport *t) { struct transport_data *trd = t->userdata; struct sockaddr_sco addr; int sock, i; bdaddr_t src; const char *src_addr; sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO); if (sock < 0) { pa_log_error("socket(SEQPACKET, SCO) %s", pa_cstrerror(errno)); return -1; } src_addr = t->device->adapter->address; /* don't use ba2str to avoid -lbluetooth */ for (i = 5; i >= 0; i--, src_addr += 3) src.b[i] = strtol(src_addr, NULL, 16); /* Bind to local address */ memset(&addr, 0, sizeof(addr)); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, &src); if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { pa_log_error("bind(): %s", pa_cstrerror(errno)); goto fail_close; } pa_log_info ("doing listen"); if (listen(sock, 1) < 0) { pa_log_error("listen(): %s", pa_cstrerror(errno)); goto fail_close; } trd->sco_fd = sock; trd->sco_io = trd->mainloop->io_new(trd->mainloop, sock, PA_IO_EVENT_INPUT, sco_io_callback, t); return sock; fail_close: close(sock); return -1; }