Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
/* 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;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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));
}
Exemplo n.º 14
0
/* 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;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 18
0
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
}
Exemplo n.º 19
0
/* 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
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
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;
}
Exemplo n.º 22
0
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));
}
Exemplo n.º 25
0
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);
}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
Arquivo: util.c Projeto: thewb/mokoiax
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;
}
Exemplo n.º 28
0
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;
}
Exemplo n.º 29
0
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;
}
Exemplo n.º 30
0
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;
}