From 03f9565ef8aaa4e0c0c25318854a5097f16b0589 Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Sat, 14 Oct 2000 19:43:14 +0000 Subject: [PATCH] More diagnostics. Fixed shm use. --- aserver/aserver.c | 77 ++++++++++++----------------- include/pcm.h | 2 +- src/pcm/pcm.c | 15 ++++-- src/pcm/pcm_file.c | 4 +- src/pcm/pcm_hw.c | 113 +++++++++++++++++++++++++------------------ src/pcm/pcm_local.h | 6 ++- src/pcm/pcm_plugin.c | 40 ++++++++++----- src/pcm/pcm_shm.c | 28 +++++------ 8 files changed, 156 insertions(+), 129 deletions(-) diff --git a/aserver/aserver.c b/aserver/aserver.c index 8cda2b3b..2ac9683e 100644 --- a/aserver/aserver.c +++ b/aserver/aserver.c @@ -53,7 +53,7 @@ char *command; } while (0) #endif -#define SYSERR(string) ERROR(string ": %s", strerror(errno)) +#define SYSERROR(string) ERROR(string ": %s", strerror(errno)) int make_local_socket(const char *filename) { @@ -65,7 +65,7 @@ int make_local_socket(const char *filename) sock = socket(PF_LOCAL, SOCK_STREAM, 0); if (sock < 0) { int result = -errno; - SYSERR("socket"); + SYSERROR("socket failed"); return result; } @@ -76,7 +76,7 @@ int make_local_socket(const char *filename) if (bind(sock, (struct sockaddr *) addr, size) < 0) { int result = -errno; - SYSERR("bind"); + SYSERROR("bind failed"); return result; } @@ -91,7 +91,7 @@ int make_inet_socket(int port) sock = socket(PF_INET, SOCK_STREAM, 0); if (sock < 0) { int result = -errno; - SYSERR("socket"); + SYSERROR("socket failed"); return result; } @@ -101,7 +101,7 @@ int make_inet_socket(int port) if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { int result = -errno; - SYSERR("bind"); + SYSERROR("bind failed"); return result; } @@ -135,7 +135,7 @@ int send_fd(int socket, void *data, size_t len, int fd) ret = sendmsg(socket, &msghdr, 0 ); if (ret < 0) { - SYSERR("sendmsg"); + SYSERROR("sendmsg failed"); return -errno; } return ret; @@ -253,13 +253,13 @@ int pcm_handler(waiter_t *waiter, unsigned short events) if (events & POLLIN) { n = write(client->poll_fd, buf, 1); if (n != 1) { - SYSERR("write"); + SYSERROR("write failed"); return -errno; } } else if (events & POLLOUT) { n = read(client->poll_fd, buf, 1); if (n != 1) { - SYSERR("read"); + SYSERROR("read failed"); return -errno; } } @@ -283,7 +283,7 @@ int pcm_shm_open(client_t *client, int *cookie) shmid = shmget(IPC_PRIVATE, PCM_SHM_SIZE, 0666); if (shmid < 0) { result = -errno; - SYSERR("shmget"); + SYSERROR("shmget failed"); goto _err; } client->transport.shm.ctrl_id = shmid; @@ -291,7 +291,7 @@ int pcm_shm_open(client_t *client, int *cookie) if (client->transport.shm.ctrl == (void*) -1) { result = -errno; shmctl(shmid, IPC_RMID, 0); - SYSERR("shmat"); + SYSERROR("shmat failed"); goto _err; } *cookie = shmid; @@ -314,14 +314,14 @@ int pcm_shm_close(client_t *client) err = snd_pcm_close(client->device.pcm.handle); ctrl->result = err; if (err < 0) - SYSERR("snd_pcm_close"); + ERROR("snd_pcm_close"); if (client->transport.shm.ctrl) { err = shmdt((void *)client->transport.shm.ctrl); if (err < 0) - SYSERR("shmdt"); + SYSERROR("shmdt failed"); err = shmctl(client->transport.shm.ctrl_id, IPC_RMID, 0); if (err < 0) - SYSERR("shmctl"); + SYSERROR("shmctl IPC_RMID failed"); client->transport.shm.ctrl = 0; } client->open = 0; @@ -452,27 +452,12 @@ int pcm_shm_cmd(client_t *client) } case SND_PCM_IOCTL_MMAP_INFO: { - snd_pcm_mmap_info_t *i; unsigned int index = ctrl->u.mmap_info.index; + snd_pcm_mmap_info_t *i = &pcm->mmap_info[index]; if (index >= pcm->mmap_info_count) { ctrl->result = -EINVAL; break; } - i = &pcm->mmap_info[index]; - if (i->type == SND_PCM_MMAP_USER) { - void *ptr; - int shmid = shmget(IPC_PRIVATE, i->size, 0666); - if (shmid < 0) { - SYSERR("shmget"); - return -EINVAL; - } - ptr = shmat(shmid, i->addr, 0); - if (ptr != i->addr) { - SYSERR("shmat"); - return -EINVAL; - } - i->u.user.shmid = shmid; - } ctrl->u.mmap_info = *i; ctrl->u.mmap_info.index = index; ctrl->result = 0; @@ -526,7 +511,7 @@ int ctl_handler(waiter_t *waiter, unsigned short events) if (events & POLLIN) { n = write(client->poll_fd, buf, 1); if (n != 1) { - SYSERR("write"); + SYSERROR("write failed"); return -errno; } } @@ -550,7 +535,7 @@ int ctl_shm_open(client_t *client, int *cookie) shmid = shmget(IPC_PRIVATE, CTL_SHM_SIZE, 0666); if (shmid < 0) { result = -errno; - SYSERR("shmget"); + SYSERROR("shmget failed"); goto _err; } client->transport.shm.ctrl_id = shmid; @@ -558,7 +543,7 @@ int ctl_shm_open(client_t *client, int *cookie) if (!client->transport.shm.ctrl) { result = -errno; shmctl(shmid, IPC_RMID, 0); - SYSERR("shmat"); + SYSERROR("shmat failed"); goto _err; } *cookie = shmid; @@ -583,14 +568,14 @@ int ctl_shm_close(client_t *client) err = snd_ctl_close(client->device.control.handle); ctrl->result = err; if (err < 0) - SYSERR("snd_ctl_close"); + ERROR("snd_ctl_close"); if (client->transport.shm.ctrl) { err = shmdt((void *)client->transport.shm.ctrl); if (err < 0) - SYSERR("shmdt"); + SYSERROR("shmdt failed"); err = shmctl(client->transport.shm.ctrl_id, IPC_RMID, 0); if (err < 0) - SYSERR("shmctl"); + SYSERROR("shmctl failed"); client->transport.shm.ctrl = 0; } client->open = 0; @@ -679,7 +664,7 @@ int snd_client_open(client_t *client) memset(&ans, 0, sizeof(ans)); err = read(client->ctrl_fd, &req, sizeof(req)); if (err < 0) { - SYSERR("read"); + SYSERROR("read failed"); exit(1); } if (err != sizeof(req)) { @@ -689,7 +674,7 @@ int snd_client_open(client_t *client) name = alloca(req.namelen); err = read(client->ctrl_fd, name, req.namelen); if (err < 0) { - SYSERR("read"); + SYSERROR("read failed"); exit(1); } if (err != req.namelen) { @@ -738,7 +723,7 @@ int snd_client_open(client_t *client) _answer: err = write(client->ctrl_fd, &ans, sizeof(ans)); if (err != sizeof(ans)) { - SYSERR("write"); + SYSERROR("write failed"); exit(1); } return 0; @@ -834,7 +819,7 @@ int local_handler(waiter_t *waiter, unsigned short events ATTRIBUTE_UNUSED) sock = accept(waiter->fd, 0, 0); if (sock < 0) { int result = -errno; - SYSERR("accept"); + SYSERROR("accept failed"); return result; } else { client_t *client = calloc(1, sizeof(*client)); @@ -853,7 +838,7 @@ int inet_handler(waiter_t *waiter, unsigned short events ATTRIBUTE_UNUSED) sock = accept(waiter->fd, 0, 0); if (sock < 0) { int result = -errno; - SYSERR("accept"); + SYSERROR("accept failed"); return result; } else { inet_pending_t *pending = calloc(1, sizeof(*pending)); @@ -878,12 +863,12 @@ int server(char *sockname, int port) return sock; if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { int result = -errno; - SYSERR("fcntl"); + SYSERROR("fcntl O_NONBLOCK failed"); return result; } if (listen(sock, 4) < 0) { int result = -errno; - SYSERR("listen"); + SYSERROR("listen failed"); return result; } add_waiter(sock, POLLIN, local_handler, NULL); @@ -894,12 +879,12 @@ int server(char *sockname, int port) return sock; if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { int result = -errno; - SYSERR("fcntl"); + SYSERROR("fcntl failed"); return result; } if (listen(sock, 4) < 0) { int result = -errno; - SYSERR("listen"); + SYSERROR("listen failed"); return result; } add_waiter(sock, POLLIN, inet_handler, NULL); @@ -912,7 +897,7 @@ int server(char *sockname, int port) err = poll(pollfds, pollfds_count, -1); } while (err == 0); if (err < 0) { - SYSERR("poll"); + SYSERROR("poll failed"); continue; } @@ -926,7 +911,7 @@ int server(char *sockname, int port) continue; err = w->handler(w, pfd->revents); if (err < 0) - SYSERR("handler"); + ERROR("waiter handler failed"); } } } diff --git a/include/pcm.h b/include/pcm.h index d0414943..0b07f2b5 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -119,7 +119,7 @@ typedef enum { SND_PCM_TYPE_LBSERVER, } snd_pcm_type_t; -extern void snd_pcm_error(const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((weak, format (printf, 4, 5))); +extern void snd_pcm_error(const char *file, int line, const char *function, int err, const char *fmt, ...) __attribute__ ((weak, format (printf, 5, 6))); int snd_pcm_open(snd_pcm_t **pcm, char *name, int stream, int mode); diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index e1a797e0..b33ca052 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -295,8 +295,10 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2) int fd2 = snd_pcm_link_descriptor(pcm2); if (fd1 < 0 || fd2 < 0) return -ENOSYS; - if (ioctl(fd1, SND_PCM_IOCTL_LINK, fd2) < 0) + if (ioctl(fd1, SND_PCM_IOCTL_LINK, fd2) < 0) { + SYSERR("SND_PCM_IOCTL_LINK failed"); return -errno; + } return 0; } @@ -309,11 +311,12 @@ int snd_pcm_unlink(snd_pcm_t *pcm) fd = snd_pcm_poll_descriptor(pcm); break; default: - errno = -ENOSYS; - return -1; + return -ENOSYS; } - if (ioctl(fd, SND_PCM_IOCTL_UNLINK) < 0) + if (ioctl(fd, SND_PCM_IOCTL_UNLINK) < 0) { + SYSERR("SND_PCM_IOCTL_UNLINK failed"); return -errno; + } return 0; } @@ -1047,12 +1050,14 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, return err; } -void snd_pcm_error(const char *file, int line, const char *function, const char *fmt, ...) +void snd_pcm_error(const char *file, int line, const char *function, int err, const char *fmt, ...) { va_list arg; va_start(arg, fmt); fprintf(stderr, "ALSA PCM lib %s:%i:(%s) ", file, line, function); vfprintf(stderr, fmt, arg); + if (err) + fprintf(stderr, ": %s", snd_strerror(err)); putc('\n', stderr); va_end(arg); } diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c index 60277300..530f238e 100644 --- a/src/pcm/pcm_file.c +++ b/src/pcm/pcm_file.c @@ -347,8 +347,10 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, char *name, char *fname, int fd, snd_pcm assert(pcmp && slave); if (fname) { fd = open(fname, O_WRONLY|O_CREAT, 0666); - if (fd < 0) + if (fd < 0) { + SYSERR("open %s failed", fname); return -errno; + } } file = calloc(1, sizeof(snd_pcm_file_t)); if (!file) { diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index 3b1166a6..01757758 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "pcm_local.h" #ifndef F_SETSIG @@ -52,7 +53,7 @@ static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock) int fd = hw->fd; if ((flags = fcntl(fd, F_GETFL)) < 0) { - ERR("F_GETFL failed"); + SYSERR("F_GETFL failed"); return -errno; } if (nonblock) @@ -60,7 +61,7 @@ static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock) else flags &= ~O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) < 0) { - ERR("F_SETFL for O_NONBLOCK failed"); + SYSERR("F_SETFL for O_NONBLOCK failed"); return -errno; } return 0; @@ -73,7 +74,7 @@ static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid) int fd = hw->fd; if ((flags = fcntl(fd, F_GETFL)) < 0) { - ERR("F_GETFL failed"); + SYSERR("F_GETFL failed"); return -errno; } if (sig >= 0) @@ -81,7 +82,7 @@ static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid) else flags &= ~O_ASYNC; if (fcntl(fd, F_SETFL, flags) < 0) { - ERR("F_SETFL for O_ASYNC failed"); + SYSERR("F_SETFL for O_ASYNC failed"); return -errno; } if (sig < 0) @@ -89,13 +90,13 @@ static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid) if (sig == 0) sig = SIGIO; if (fcntl(fd, F_SETSIG, sig) < 0) { - ERR("F_SETSIG failed"); + SYSERR("F_SETSIG failed"); return -errno; } if (pid == 0) pid = getpid(); if (fcntl(fd, F_SETOWN, pid) < 0) { - ERR("F_SETOWN failed"); + SYSERR("F_SETOWN failed"); return -errno; } return 0; @@ -106,7 +107,7 @@ static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_INFO, info) < 0) { - ERR("SND_PCM_IOCTL_INFO failed"); + SYSERR("SND_PCM_IOCTL_INFO failed"); return -errno; } return 0; @@ -117,7 +118,7 @@ static int snd_pcm_hw_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t * info) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_PARAMS_INFO, info) < 0) { - ERR("SND_PCM_IOCTL_PARAMS_INFO failed"); + SYSERR("SND_PCM_IOCTL_PARAMS_INFO failed"); return -errno; } return 0; @@ -128,7 +129,7 @@ static int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_params_t * params) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_PARAMS, params) < 0) { - ERR("SND_PCM_IOCTL_PARAMS failed"); + SYSERR("SND_PCM_IOCTL_PARAMS failed"); return -errno; } return 0; @@ -139,7 +140,7 @@ static int snd_pcm_hw_setup(snd_pcm_t *pcm, snd_pcm_setup_t * setup) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_SETUP, setup) < 0) { - ERR("SND_PCM_IOCTL_SETUP failed"); + SYSERR("SND_PCM_IOCTL_SETUP failed"); return -errno; } if (setup->mmap_shape == SND_PCM_MMAP_UNSPECIFIED) { @@ -156,7 +157,7 @@ static int snd_pcm_hw_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, info) < 0) { - ERR("SND_PCM_IOCTL_CHANNEL_INFO failed"); + SYSERR("SND_PCM_IOCTL_CHANNEL_INFO failed"); return -errno; } return 0; @@ -167,7 +168,7 @@ static int snd_pcm_hw_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_PARAMS, params) < 0) { - ERR("SND_PCM_IOCTL_CHANNEL_PARAMS failed"); + SYSERR("SND_PCM_IOCTL_CHANNEL_PARAMS failed"); return -errno; } return 0; @@ -178,7 +179,7 @@ static int snd_pcm_hw_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * se snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0) { - ERR("SND_PCM_IOCTL_CHANNEL_SETUP failed"); + SYSERR("SND_PCM_IOCTL_CHANNEL_SETUP failed"); return -errno; } if (!pcm->mmap_info) @@ -206,7 +207,7 @@ static int snd_pcm_hw_status(snd_pcm_t *pcm, snd_pcm_status_t * status) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_STATUS, status) < 0) { - ERR("SND_PCM_IOCTL_STATUS failed"); + SYSERR("SND_PCM_IOCTL_STATUS failed"); return -errno; } return 0; @@ -223,7 +224,7 @@ static int snd_pcm_hw_delay(snd_pcm_t *pcm, ssize_t *delayp) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_DELAY, delayp) < 0) { - ERR("SND_PCM_IOCTL_DELAY failed"); + SYSERR("SND_PCM_IOCTL_DELAY failed"); return -errno; } return 0; @@ -234,7 +235,7 @@ static int snd_pcm_hw_prepare(snd_pcm_t *pcm) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_PREPARE) < 0) { - ERR("SND_PCM_IOCTL_PREPARE failed"); + SYSERR("SND_PCM_IOCTL_PREPARE failed"); return -errno; } return 0; @@ -245,7 +246,7 @@ static int snd_pcm_hw_start(snd_pcm_t *pcm) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_START) < 0) { - ERR("SND_PCM_IOCTL_START failed"); + SYSERR("SND_PCM_IOCTL_START failed"); return -errno; } return 0; @@ -256,7 +257,7 @@ static int snd_pcm_hw_drop(snd_pcm_t *pcm) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_DROP) < 0) { - ERR("SND_PCM_IOCTL_DROP failed"); + SYSERR("SND_PCM_IOCTL_DROP failed"); return -errno; } return 0; @@ -267,7 +268,7 @@ static int snd_pcm_hw_drain(snd_pcm_t *pcm) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_DRAIN) < 0) { - ERR("SND_PCM_IOCTL_DRAIN failed"); +// SYSERR("SND_PCM_IOCTL_DRAIN failed"); return -errno; } return 0; @@ -278,7 +279,7 @@ static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable) snd_pcm_hw_t *hw = pcm->private; int fd = hw->fd; if (ioctl(fd, SND_PCM_IOCTL_PAUSE, enable) < 0) { - ERR("SND_PCM_IOCTL_PAUSE failed"); + SYSERR("SND_PCM_IOCTL_PAUSE failed"); return -errno; } return 0; @@ -365,7 +366,7 @@ static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm) ptr = mmap(NULL, sizeof(snd_pcm_mmap_status_t), PROT_READ, MAP_FILE|MAP_SHARED, hw->fd, SND_PCM_MMAP_OFFSET_STATUS); if (ptr == MAP_FAILED || ptr == NULL) { - ERR("status mmap failed"); + SYSERR("status mmap failed"); return -errno; } hw->mmap_status = ptr; @@ -380,7 +381,7 @@ static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm) ptr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, hw->fd, SND_PCM_MMAP_OFFSET_CONTROL); if (ptr == MAP_FAILED || ptr == NULL) { - ERR("control mmap failed"); + SYSERR("control mmap failed"); return -errno; } hw->mmap_control = ptr; @@ -391,35 +392,41 @@ static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm) static int snd_pcm_hw_mmap(snd_pcm_t *pcm) { snd_pcm_hw_t *hw = pcm->private; - pcm->mmap_info = calloc(1, sizeof(*pcm->mmap_info)); - if (!pcm->mmap_info) + snd_pcm_mmap_info_t *i = calloc(1, sizeof(*i)); + if (!i) return -ENOMEM; - pcm->mmap_info_count = 1; if (pcm->setup.mmap_shape == SND_PCM_MMAP_UNSPECIFIED) { - pcm->mmap_info->type = SND_PCM_MMAP_USER; - pcm->mmap_info->size = snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size); - pcm->mmap_info->addr = valloc(pcm->mmap_info->size); - if (!pcm->mmap_info->addr) { - free(pcm->mmap_info); - pcm->mmap_info = 0; - return -ENOMEM; + i->type = SND_PCM_MMAP_USER; + i->size = snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size); + i->u.user.shmid = shmget(IPC_PRIVATE, i->size, 0666); + if (i->u.user.shmid < 0) { + SYSERR("shmget failed"); + free(i); + return -errno; + } + i->addr = shmat(i->u.user.shmid, 0, 0); + if (i->addr == (void*) -1) { + SYSERR("shmat failed"); + free(i); + return -errno; } } else { - pcm->mmap_info->type = SND_PCM_MMAP_KERNEL; - pcm->mmap_info->size = pcm->setup.mmap_bytes; - pcm->mmap_info->addr = mmap(NULL, pcm->setup.mmap_bytes, + i->type = SND_PCM_MMAP_KERNEL; + i->size = pcm->setup.mmap_bytes; + i->addr = mmap(NULL, pcm->setup.mmap_bytes, PROT_WRITE | PROT_READ, MAP_FILE|MAP_SHARED, hw->fd, SND_PCM_MMAP_OFFSET_DATA); - if (pcm->mmap_info->addr == MAP_FAILED || - pcm->mmap_info->addr == NULL) { - ERR("data mmap failed"); - free(pcm->mmap_info); - pcm->mmap_info = 0; + if (i->addr == MAP_FAILED || + i->addr == NULL) { + SYSERR("data mmap failed"); + free(i); return -errno; } - pcm->mmap_info->u.kernel.fd = hw->fd; + i->u.kernel.fd = hw->fd; } + pcm->mmap_info = i; + pcm->mmap_info_count = 1; return 0; } @@ -427,7 +434,7 @@ static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm) { snd_pcm_hw_t *hw = pcm->private; if (munmap((void*)hw->mmap_status, sizeof(*hw->mmap_status)) < 0) { - ERR("status munmap failed"); + SYSERR("status munmap failed"); return -errno; } return 0; @@ -437,7 +444,7 @@ static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm) { snd_pcm_hw_t *hw = pcm->private; if (munmap(hw->mmap_control, sizeof(*hw->mmap_control)) < 0) { - ERR("control munmap failed"); + SYSERR("control munmap failed"); return -errno; } return 0; @@ -445,13 +452,21 @@ static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm) static int snd_pcm_hw_munmap(snd_pcm_t *pcm) { - if (pcm->setup.mmap_shape == SND_PCM_MMAP_UNSPECIFIED) - free(pcm->mmap_info->addr); - else + if (pcm->setup.mmap_shape == SND_PCM_MMAP_UNSPECIFIED) { + if (shmdt(pcm->mmap_info->addr) < 0) { + SYSERR("shmdt failed"); + return -errno; + } + if (shmctl(pcm->mmap_info->u.user.shmid, IPC_RMID, 0) < 0) { + SYSERR("shmctl IPC_RMID failed"); + return -errno; + } + } else { if (munmap(pcm->mmap_info->addr, pcm->mmap_info->size) < 0) { - ERR("data munmap failed"); + SYSERR("data munmap failed"); return -errno; } + } pcm->mmap_info_count = 0; free(pcm->mmap_info); pcm->mmap_info = 0; @@ -464,7 +479,7 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm) int fd = hw->fd; free(hw); if (close(fd)) { - ERR("close failed\n"); + SYSERR("close failed\n"); return -errno; } snd_pcm_hw_munmap_status(pcm); @@ -608,6 +623,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev if ((fd = open(filename, fmode)) < 0) return -errno; if (ioctl(fd, SND_PCM_IOCTL_PVERSION, &ver) < 0) { + SYSERR("SND_PCM_IOCTL_PVERSION failed"); ret = -errno; goto _err; } @@ -618,6 +634,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev if (subdevice >= 0) { memset(&info, 0, sizeof(info)); if (ioctl(fd, SND_PCM_IOCTL_INFO, &info) < 0) { + SYSERR("SND_PCM_IOCTL_INFO failed"); ret = -errno; goto _err; } diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 6763c853..58c8e81c 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -27,9 +27,11 @@ #include "asoundlib.h" #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) -#define ERR(...) snd_pcm_error(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) +#define ERR(...) snd_pcm_error(__FILE__, __LINE__, __FUNCTION__, 0, __VA_ARGS__) +#define SYSERR(...) snd_pcm_error(__FILE__, __LINE__, __FUNCTION__, errno, __VA_ARGS__) #else -#define ERR(args...) snd_pcm_error(__FILE__, __LINE__, __FUNCTION__, ##args) +#define ERR(args...) snd_pcm_error(__FILE__, __LINE__, __FUNCTION__, 0, ##args) +#define SYSERR(args...) snd_pcm_error(__FILE__, __LINE__, __FUNCTION__, errno, ##args) #endif typedef struct { diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c index 18c553a0..bf56c8bd 100644 --- a/src/pcm/pcm_plugin.c +++ b/src/pcm/pcm_plugin.c @@ -19,9 +19,10 @@ * */ +#include +#include #include "pcm_local.h" #include "pcm_plugin.h" -#include int snd_pcm_plugin_close(snd_pcm_t *pcm) { @@ -307,21 +308,29 @@ int snd_pcm_plugin_mmap(snd_pcm_t *pcm) { snd_pcm_plugin_t *plugin = pcm->private; snd_pcm_t *slave = plugin->slave; + snd_pcm_mmap_info_t *i; int err = snd_pcm_mmap(slave); if (err < 0) return err; - pcm->mmap_info = calloc(1, sizeof(*pcm->mmap_info)); - if (!pcm->mmap_info) - return -ENOMEM; - pcm->mmap_info_count = 1; - pcm->mmap_info->type = SND_PCM_MMAP_USER; - pcm->mmap_info->size = pcm->setup.buffer_size; - pcm->mmap_info->addr = valloc(snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size)); - if (!pcm->mmap_info->addr) { - free(pcm->mmap_info); - pcm->mmap_info = 0; + i = calloc(1, sizeof(*i)); + if (!i) return -ENOMEM; + i->type = SND_PCM_MMAP_USER; + i->size = snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size); + i->u.user.shmid = shmget(IPC_PRIVATE, i->size, 0666); + if (i->u.user.shmid < 0) { + SYSERR("shmget failed"); + free(i); + return -errno; } + i->addr = shmat(i->u.user.shmid, 0, 0); + if (i->addr == (void*) -1) { + SYSERR("shmat failed"); + free(i); + return -errno; + } + pcm->mmap_info = i; + pcm->mmap_info_count = 1; return 0; } @@ -332,7 +341,14 @@ int snd_pcm_plugin_munmap(snd_pcm_t *pcm) int err = snd_pcm_munmap(slave); if (err < 0) return err; - free(pcm->mmap_info->addr); + if (shmdt(pcm->mmap_info->addr) < 0) { + SYSERR("shmdt failed"); + return -errno; + } + if (shmctl(pcm->mmap_info->u.user.shmid, IPC_RMID, 0) < 0) { + SYSERR("shmctl IPC_RMID failed"); + return -errno; + } free(pcm->mmap_info); pcm->mmap_info_count = 0; pcm->mmap_info = 0; diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c index 766e7bad..ced92da2 100644 --- a/src/pcm/pcm_shm.c +++ b/src/pcm/pcm_shm.c @@ -71,7 +71,7 @@ int receive_fd(int socket, void *data, size_t len, int *fd) ret = recvmsg(socket, &msghdr, 0); if (ret < 0) { - ERR("recvmsg failed"); + SYSERR("recvmsg failed"); return -errno; } *fd = *fds; @@ -385,14 +385,14 @@ static int snd_pcm_shm_mmap(snd_pcm_t *pcm) fd, SND_PCM_MMAP_OFFSET_DATA); close(fd); if (ptr == MAP_FAILED || ptr == NULL) { - ERR("mmap failed"); + SYSERR("mmap failed"); free(pcm->mmap_info); return -errno; } } else { ptr = shmat(i->u.user.shmid, 0, 0); if (ptr == (void*)-1) { - ERR("shmat failed"); + SYSERR("shmat failed"); free(pcm->mmap_info); return -errno; } @@ -417,12 +417,12 @@ static int snd_pcm_shm_munmap(snd_pcm_t *pcm) if (i->type == SND_PCM_MMAP_KERNEL) { err = munmap(i->addr, i->size); if (err < 0) - ERR("munmap failed"); + SYSERR("munmap failed"); return -errno; } else { err = shmdt(i->addr); if (err < 0) - ERR("shmdt failed"); + SYSERR("shmdt failed"); return -errno; } } @@ -531,7 +531,7 @@ static int make_local_socket(const char *filename) sock = socket(PF_LOCAL, SOCK_STREAM, 0); if (sock < 0) { - ERR("socket failed"); + SYSERR("socket failed"); return -errno; } @@ -539,7 +539,7 @@ static int make_local_socket(const char *filename) memcpy(addr->sun_path, filename, l); if (connect(sock, (struct sockaddr *) addr, size) < 0) { - ERR("connect failed"); + SYSERR("connect failed"); return -errno; } return sock; @@ -556,7 +556,7 @@ static int make_inet_socket(const char *host, int port) sock = socket(PF_INET, SOCK_STREAM, 0); if (sock < 0) { - ERR("socket failed"); + SYSERR("socket failed"); return -errno; } @@ -565,7 +565,7 @@ static int make_inet_socket(const char *host, int port) memcpy(&addr.sin_addr, h->h_addr_list[0], sizeof(struct in_addr)); if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - ERR("connect failed"); + SYSERR("connect failed"); return -errno; } return sock; @@ -604,7 +604,7 @@ int snd_pcm_shm_open(snd_pcm_t **pcmp, char *name, char *socket, char *sname, in req->namelen = snamelen; err = write(sock, req, reqlen); if (err < 0) { - ERR("write error"); + SYSERR("write error"); result = -errno; goto _err; } @@ -615,7 +615,7 @@ int snd_pcm_shm_open(snd_pcm_t **pcmp, char *name, char *socket, char *sname, in } err = read(sock, &ans, sizeof(ans)); if (err < 0) { - ERR("read error"); + SYSERR("read error"); result = -errno; goto _err; } @@ -630,7 +630,7 @@ int snd_pcm_shm_open(snd_pcm_t **pcmp, char *name, char *socket, char *sname, in ctrl = shmat(ans.cookie, 0, 0); if (!ctrl) { - ERR("shmat error"); + SYSERR("shmat error"); result = -errno; goto _err; } @@ -691,7 +691,7 @@ int is_local(struct hostent *hent) s = socket(PF_INET, SOCK_STREAM, 0); if (s < 0) { - ERR("socket failed"); + SYSERR("socket failed"); return -errno; } @@ -700,7 +700,7 @@ int is_local(struct hostent *hent) while (1) { err = ioctl(s, SIOCGIFCONF, &conf); if (err < 0) { - ERR("SIOCGIFCONF failed"); + SYSERR("SIOCGIFCONF failed"); return -errno; } if ((size_t)conf.ifc_len < numreqs * sizeof(struct ifreq)) -- 2.47.1