示例#1
0
文件: pid.c 项目: KimT/pulseaudio_kt
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;
}
示例#2
0
static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
    pa_socket_server *s = userdata;
    pa_iochannel *io;
    int nfd;

    pa_assert(s);
    pa_assert(PA_REFCNT_VALUE(s) >= 1);
    pa_assert(s->mainloop == mainloop);
    pa_assert(s->io_event == e);
    pa_assert(e);
    pa_assert(fd >= 0);
    pa_assert(fd == s->fd);

    pa_socket_server_ref(s);

    if ((nfd = pa_accept_cloexec(fd, NULL, NULL)) < 0) {
        pa_log("accept(): %s", pa_cstrerror(errno));
        goto finish;
    }

    if (!s->on_connection) {
        pa_close(nfd);
        goto finish;
    }

#ifdef HAVE_LIBWRAP

    if (s->tcpwrap_service) {
        struct request_info req;

        request_init(&req, RQ_DAEMON, s->tcpwrap_service, RQ_FILE, nfd, NULL);
        fromhost(&req);
        if (!hosts_access(&req)) {
            pa_log_warn("TCP connection refused by tcpwrap.");
            pa_close(nfd);
            goto finish;
        }

        pa_log_info("TCP connection accepted by tcpwrap.");
    }
#endif

    /* There should be a check for socket type here */
    if (s->type == SOCKET_SERVER_IPV4)
        pa_make_tcp_socket_low_delay(fd);
    else
        pa_make_socket_low_delay(fd);

    pa_assert_se(io = pa_iochannel_new(s->mainloop, nfd, nfd));
    s->on_connection(s, io, s->userdata);

finish:
    pa_socket_server_unref(s);
}
示例#3
0
void pa_iochannel_free(pa_iochannel*io) {
    pa_assert(io);

    delete_events(io);

    if (!io->no_close) {
        if (io->ifd >= 0)
            pa_close(io->ifd);
        if (io->ofd >= 0 && io->ofd != io->ifd)
            pa_close(io->ofd);
    }

    pa_xfree(io);
}
示例#4
0
static void unref(pa_bool_t after_fork) {

    pa_assert(n_ref > 0);
    pa_assert(pipe_fd[0] >= 0);
    pa_assert(pipe_fd[1] >= 0);
    pa_assert(lock_fd_mutex);

    n_ref--;

    if (n_ref > 0)
        return;

    if (thread) {
        pa_thread_free(thread);
        thread = NULL;
    }

    pa_mutex_lock(lock_fd_mutex);

    pa_assert(state != STATE_TAKEN);

    if (state == STATE_OWNING) {

        pa_assert(lock_fd >= 0);

        if (after_fork)
            pa_close(lock_fd);
        else {
            char *lf;

            if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK)))
                pa_log_warn(_("Cannot access autospawn lock."));

            pa_unlock_lockfile(lf, lock_fd);
            pa_xfree(lf);
        }
    }

    lock_fd = -1;
    state = STATE_IDLE;

    pa_mutex_unlock(lock_fd_mutex);

    pa_mutex_free(lock_fd_mutex);
    lock_fd_mutex = NULL;

    pa_close(pipe_fd[0]);
    pa_close(pipe_fd[1]);
    pipe_fd[0] = pipe_fd[1] = -1;
}
示例#5
0
文件: shm.c 项目: Elemecca/pulseaudio
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;
}
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__done(pa_module *m) {
    struct userdata *u;

    pa_assert(m);

    if (!(u = m->userdata))
        return;

    if (u->udev_io)
        m->core->mainloop->io_free(u->udev_io);

    if (u->monitor)
        udev_monitor_unref(u->monitor);

    if (u->udev)
        udev_unref(u->udev);

    if (u->inotify_io)
        m->core->mainloop->io_free(u->inotify_io);

    if (u->inotify_fd >= 0)
        pa_close(u->inotify_fd);

    if (u->devices) {
        struct device *d;

        while ((d = pa_hashmap_steal_first(u->devices)))
            device_free(d);

        pa_hashmap_free(u->devices, NULL, NULL);
    }

    pa_xfree(u);
}
void pa__done(pa_module *m) {
    struct userdata *u;

    pa_assert(m);

    if (!(u = m->userdata))
        return;

    if (u->udev_io)
        m->core->mainloop->io_free(u->udev_io);

    if (u->monitor)
        udev_monitor_unref(u->monitor);

    if (u->udev)
        udev_unref(u->udev);

    if (u->inotify_io)
        m->core->mainloop->io_free(u->inotify_io);

    if (u->inotify_fd >= 0)
        pa_close(u->inotify_fd);

    if (u->devices)
        pa_hashmap_free(u->devices);

    pa_xfree(u);
}
示例#9
0
static void inotify_cb(
        pa_mainloop_api *a,
        pa_io_event *e,
        int fd,
        pa_io_event_flags_t events,
        void *userdata) {

    struct {
        struct inotify_event event;
        char name[NAME_MAX+1];
    } buf;

    pa_inotify *i = userdata;
    int pid_fd;

    pa_assert(i);

    if (pa_read(fd, &buf, sizeof(buf), NULL) < (int) sizeof(buf.event))
        pa_log_warn("inotify did not read a full event.");
    else
        pa_log_debug("inotify callback, event mask: 0x%x", (int) buf.event.mask);

    pid_fd = pa_open_cloexec(i->filename, O_RDONLY
#ifdef O_NOFOLLOW
                       |O_NOFOLLOW
#endif
                       , S_IRUSR);

    if (pid_fd < 0) {
        if (i->callback)
            i->callback(i->callback_data);
    } else
        pa_close(pid_fd);
}
示例#10
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;
}
示例#11
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;
}
示例#12
0
void pa_log_set_fd(int fd) {
    if (fd >= 0)
        log_fd = fd;
    else if (log_fd >= 0) {
        pa_close(log_fd);
        log_fd = -1;
    }
}
示例#13
0
文件: pid.c 项目: KimT/pulseaudio_kt
/* Kill a current running daemon. Return non-zero on success, -1
 * otherwise. If successful *pid contains the PID of the daemon
 * process. */
int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {
    int fd = -1;
    char *fn;
    int ret = -1;
    pid_t _pid;
#ifdef __linux__
    char *e = NULL;
#endif

    if (!pid)
        pid = &_pid;

    if (!(fn = pa_runtime_path("pid")))
        goto fail;

    if ((fd = open_pid_file(fn, O_RDONLY)) < 0) {

        if (errno == ENOENT)
            errno = ESRCH;

        goto fail;
    }

    if ((*pid = read_pid(fn, fd)) == (pid_t) -1)
        goto fail;

    if (procname) {
        int ours;

        if ((ours = proc_name_ours(*pid, procname)) < 0)
            goto fail;

        if (!ours) {
            errno = ESRCH;
            goto fail;
        }
    }

    ret = kill(*pid, sig);

fail:

    if (fd >= 0) {
        int saved_errno = errno;
        pa_lock_fd(fd, 0);
        pa_close(fd);
        errno = saved_errno;
    }

#ifdef __linux__
    pa_xfree(e);
#endif

    pa_xfree(fn);

    return ret;

}
示例#14
0
文件: main.c 项目: EQ4/WaveformPlot
int main(int argc, const char * argv[])
{
    plotter_init();
    pa_init();
    getchar();
    pa_close();
    plotter_close();
    return 0;
}
示例#15
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;
}
示例#16
0
void pa_fdsem_free(pa_fdsem *f) {
    pa_assert(f);

#ifdef HAVE_SYS_EVENTFD_H
    if (f->efd >= 0)
        pa_close(f->efd);
#endif
    pa_close_pipe(f->fds);

    pa_xfree(f);
}
示例#17
0
static char *get_cpuinfo(void) {
    char *cpuinfo;
    int n, fd;

    cpuinfo = pa_xmalloc(MAX_BUFFER);

    if ((fd = pa_open_cloexec("/proc/cpuinfo", O_RDONLY, 0)) < 0) {
        pa_xfree(cpuinfo);
        return NULL;
    }

    if ((n = pa_read(fd, cpuinfo, MAX_BUFFER-1, NULL)) < 0) {
        pa_xfree(cpuinfo);
        pa_close(fd);
        return NULL;
    }
    cpuinfo[n] = 0;
    pa_close(fd);

    return cpuinfo;
}
示例#18
0
void pa_inotify_stop(pa_inotify *i) {

    pa_assert(i);

    if (i->io_event)
        i->core->mainloop->io_free(i->io_event);
    if (i->fd)
        pa_close(i->fd);
    pa_xfree(i->filename);
    if (i->core)
        pa_core_unref(i->core);
    pa_xfree(i);
}
示例#19
0
static void socket_server_free(pa_socket_server*s) {
    pa_assert(s);

    if (s->filename) {
        unlink(s->filename);
        pa_xfree(s->filename);
    }

    pa_close(s->fd);

    pa_xfree(s->tcpwrap_service);

    s->mainloop->io_free(s->io_event);
    pa_xfree(s);
}
示例#20
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;
}
示例#21
0
文件: module-oss.c 项目: Thread974/pa
/* Called from IO context */
static int suspend(struct userdata *u) {
    pa_assert(u);
    pa_assert(u->fd >= 0);

    pa_log_info("Suspending...");

    if (u->out_mmap_memblocks) {
        unsigned i;
        for (i = 0; i < u->out_nfrags; i++)
            if (u->out_mmap_memblocks[i]) {
                pa_memblock_unref_fixed(u->out_mmap_memblocks[i]);
                u->out_mmap_memblocks[i] = NULL;
            }
    }

    if (u->in_mmap_memblocks) {
        unsigned i;
        for (i = 0; i < u->in_nfrags; i++)
            if (u->in_mmap_memblocks[i]) {
                pa_memblock_unref_fixed(u->in_mmap_memblocks[i]);
                u->in_mmap_memblocks[i] = NULL;
            }
    }

    if (u->in_mmap && u->in_mmap != MAP_FAILED) {
        munmap(u->in_mmap, u->in_hwbuf_size);
        u->in_mmap = NULL;
    }

    if (u->out_mmap && u->out_mmap != MAP_FAILED) {
        munmap(u->out_mmap, u->out_hwbuf_size);
        u->out_mmap = NULL;
    }

    /* Let's suspend */
    ioctl(u->fd, SNDCTL_DSP_SYNC, NULL);
    pa_close(u->fd);
    u->fd = -1;

    if (u->rtpoll_item) {
        pa_rtpoll_item_free(u->rtpoll_item);
        u->rtpoll_item = NULL;
    }

    pa_log_info("Device suspended...");

    return 0;
}
示例#22
0
文件: main.c 项目: EQ4/IIR_Biquad
int main(int argc, const char * argv[])
{
    float coeffs[NUM_COEFFS] = {0.00460399444634034,
                                0.00920798889268068,
                                0.00460399444634034,
                                -1.7990948352036205,
                                0.8175108129889816};
    int i;
    for (i=0; i<FILTERS;i++) {
        bq[i] = bq_new(coeffs);
    }
    pa_init();
    getchar();
    pa_close();
    free(bq);
    return 0;
}
void pa__done(pa_module*m) {
    struct userdata *u;

    pa_assert(m);

    if (!(u = m->userdata))
        return;

    if (u->io)
        m->core->mainloop->io_free(u->io);

    if (u->fd >= 0)
        pa_assert_se(pa_close(u->fd) == 0);

    pa_xfree(u->sink_name);
    pa_xfree(u);
}
示例#24
0
void pa__done(pa_module*m) {
    struct userdata *u;
    pa_assert(m);

    if (!(u = m->userdata))
        return;

    if (u->sink)
        pa_sink_unlink(u->sink);

    if (u->thread) {
        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
        pa_thread_free(u->thread);
    }

    pa_thread_mq_done(&u->thread_mq);

    if (u->sink)
        pa_sink_unref(u->sink);

    if (u->rtpoll_item)
        pa_rtpoll_item_free(u->rtpoll_item);

    if (u->rtpoll)
        pa_rtpoll_free(u->rtpoll);

    if (u->raw_memchunk.memblock)
        pa_memblock_unref(u->raw_memchunk.memblock);

    if (u->encoded_memchunk.memblock)
        pa_memblock_unref(u->encoded_memchunk.memblock);

    if (u->raop)
        pa_raop_client_free(u->raop);

    pa_xfree(u->read_data);
    pa_xfree(u->write_data);

    if (u->smoother)
        pa_smoother_free(u->smoother);

    if (u->fd >= 0)
        pa_close(u->fd);

    pa_xfree(u);
}
示例#25
0
/* Store the specified cookie in the specified cookie file */
int pa_authkey_save(const char *fn, const void *data, size_t length) {
    int fd = -1;
    int unlock = 0, ret = -1;
    ssize_t r;
    char *p;

    pa_assert(fn);
    pa_assert(data);
    pa_assert(length > 0);

    if (!(p = normalize_path(fn)))
        return -2;

    if ((fd = pa_open_cloexec(p, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
        pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
        goto finish;
    }

    unlock = pa_lock_fd(fd, 1) >= 0;

    if ((r = pa_loop_write(fd, data, length, NULL)) < 0 || (size_t) r != length) {
        pa_log("Failed to read cookie file '%s': %s", fn, pa_cstrerror(errno));
        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;
        }
    }

    pa_xfree(p);

    return ret;
}
示例#26
0
static int suspend(struct userdata *u) {
    pa_assert(u);
    pa_assert(u->fd >= 0);

    pa_log_info("Suspending...");

    ioctl(u->fd, I_FLUSH, FLUSHRW);
    pa_close(u->fd);
    u->fd = -1;

    if (u->rtpoll_item) {
        pa_rtpoll_item_free(u->rtpoll_item);
        u->rtpoll_item = NULL;
    }

    pa_log_info("Device suspended.");

    return 0;
}
示例#27
0
static int setup_inotify(struct userdata *u) {
    char *dev_snd;
    int r;

    if (u->inotify_fd >= 0)
        return 0;

    if ((u->inotify_fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
        pa_log("inotify_init1() failed: %s", pa_cstrerror(errno));
        return -1;
    }

    dev_snd = pa_sprintf_malloc("%s/snd", udev_get_dev_path(u->udev));
    r = inotify_add_watch(u->inotify_fd, dev_snd, IN_ATTRIB|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF);
    pa_xfree(dev_snd);

    if (r < 0) {
        int saved_errno = errno;

        pa_close(u->inotify_fd);
        u->inotify_fd = -1;

        if (saved_errno == ENOENT) {
            pa_log_debug("/dev/snd/ is apparently not existing yet, retrying to create inotify watch later.");
            return 0;
        }

        if (saved_errno == ENOSPC) {
            pa_log("You apparently ran out of inotify watches, probably because Tracker/Beagle took them all away. "
                   "I wished people would do their homework first and fix inotify before using it for watching whole "
                   "directory trees which is something the current inotify is certainly not useful for. "
                   "Please make sure to drop the Tracker/Beagle guys a line complaining about their broken use of inotify.");
            return 0;
        }

        pa_log("inotify_add_watch() failed: %s", pa_cstrerror(saved_errno));
        return -1;
    }

    pa_assert_se(u->inotify_io = u->core->mainloop->io_new(u->core->mainloop, u->inotify_fd, PA_IO_EVENT_INPUT, inotify_cb, u));

    return 0;
}
示例#28
0
static int random_proper(void *ret_data, size_t length) {
#ifdef OS_IS_WIN32
    pa_assert(ret_data);
    pa_assert(length > 0);

    return -1;

#else /* OS_IS_WIN32 */

    int fd, ret = -1;
    ssize_t r = 0;
    const char *const * device;

    pa_assert(ret_data);
    pa_assert(length > 0);

    device = devices;

    while (*device) {
        ret = 0;

        if ((fd = open(*device, O_RDONLY
#ifdef O_NOCTTY
                       | O_NOCTTY
#endif
             )) >= 0) {

            if ((r = pa_loop_read(fd, ret_data, length, NULL)) < 0 || (size_t) r != length)
                ret = -1;

            pa_close(fd);
        } else
            ret = -1;

        if (ret == 0)
            break;

        device++;
    }

    return ret;
#endif /* OS_IS_WIN32 */
}
示例#29
0
void pa__done(pa_module *m) {
    struct userdata *u;

    pa_assert(m);

    if (!(u = m->userdata))
        return;

    if (u->source)
        pa_source_unlink(u->source);

    if (u->thread) {
        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
        pa_thread_free(u->thread);
    }

    pa_thread_mq_done(&u->thread_mq);

    if (u->source)
        pa_source_unref(u->source);

    if (u->memchunk.memblock)
        pa_memblock_unref(u->memchunk.memblock);

    if (u->rtpoll_item)
        pa_rtpoll_item_free(u->rtpoll_item);

    if (u->rtpoll)
        pa_rtpoll_free(u->rtpoll);

    if (u->filename) {
        unlink(u->filename);
        pa_xfree(u->filename);
    }

    if (u->fd >= 0)
        pa_assert_se(pa_close(u->fd) == 0);

    pa_xfree(u);
}
示例#30
0
void pa_shm_free(pa_shm *m) {
    pa_assert(m);
    pa_assert(m->ptr);
    pa_assert(m->size > 0);

#ifdef MAP_FAILED
    pa_assert(m->ptr != MAP_FAILED);
#endif

    if (m->type == PA_MEM_TYPE_PRIVATE) {
        privatemem_free(m);
        goto finish;
    }

#if defined(HAVE_SHM_OPEN) || defined(HAVE_MEMFD)
    if (munmap(m->ptr, PA_PAGE_ALIGN(m->size)) < 0)
        pa_log("munmap() failed: %s", pa_cstrerror(errno));

#ifdef HAVE_SHM_OPEN
    if (m->type == PA_MEM_TYPE_SHARED_POSIX && m->do_unlink) {
        char fn[32];

        segment_name(fn, sizeof(fn), m->id);
        if (shm_unlink(fn) < 0)
            pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno));
    }
#endif
#ifdef HAVE_MEMFD
    if (m->type == PA_MEM_TYPE_SHARED_MEMFD && m->fd != -1)
        pa_assert_se(pa_close(m->fd) == 0);
#endif

#else
    /* We shouldn't be here without shm or memfd support */
    pa_assert_not_reached();
#endif

finish:
    pa_zero(*m);
}