summaryrefslogtreecommitdiffstats
path: root/lib/libsndio
diff options
context:
space:
mode:
authorratchov <ratchov@openbsd.org>2015-11-18 09:35:59 +0000
committerratchov <ratchov@openbsd.org>2015-11-18 09:35:59 +0000
commit413b52fd8add49d18bc904ca3c39d6de7ed154af (patch)
tree30d98dd4f87829e911538e3e4d1200ee117c71a5 /lib/libsndio
parentDon't update activity time twice for new sessions, and add some logging. (diff)
downloadwireguard-openbsd-413b52fd8add49d18bc904ca3c39d6de7ed154af.tar.xz
wireguard-openbsd-413b52fd8add49d18bc904ca3c39d6de7ed154af.zip
Split function to initialize the raw device in two parts, one to open
the device node, the other to do the initialization. This will allow with minimal changes, work to be done in two process sharing the fd. No behaviour change.
Diffstat (limited to 'lib/libsndio')
-rw-r--r--lib/libsndio/sio_sun.c67
1 files changed, 44 insertions, 23 deletions
diff --git a/lib/libsndio/sio_sun.c b/lib/libsndio/sio_sun.c
index ffbdd6300a0..8487db07019 100644
--- a/lib/libsndio/sio_sun.c
+++ b/lib/libsndio/sio_sun.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sio_sun.c,v 1.20 2015/11/17 16:07:42 ratchov Exp $ */
+/* $OpenBSD: sio_sun.c,v 1.21 2015/11/18 09:35:59 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -58,6 +58,8 @@ static size_t sio_sun_write(struct sio_hdl *, const void *, size_t);
static int sio_sun_nfds(struct sio_hdl *);
static int sio_sun_pollfd(struct sio_hdl *, struct pollfd *, int);
static int sio_sun_revents(struct sio_hdl *, struct pollfd *);
+static int sio_sun_getfd(const char *, unsigned int, int);
+static struct sio_hdl *sio_sun_fdopen(int, unsigned int, int);
static struct sio_ops sio_sun_ops = {
sio_sun_close,
@@ -328,46 +330,51 @@ sio_sun_getcap(struct sio_hdl *sh, struct sio_cap *cap)
#undef NRATES
}
-struct sio_hdl *
-_sio_sun_open(const char *str, unsigned int mode, int nbio)
+static int
+sio_sun_getfd(const char *str, unsigned int mode, int nbio)
{
- int fd, flags;
- struct audio_info aui;
- struct sio_sun_hdl *hdl;
- struct sio_par par;
char path[DEVPATH_MAX];
unsigned int devnum;
+ int fd, flags;
switch (*str) {
case '/':
str++;
break;
default:
- DPRINTF("_sio_sun_open: %s: '/<devnum>' expected\n", str);
- return NULL;
+ DPRINTF("sio_sun_getfd: %s: '/<devnum>' expected\n", str);
+ return -1;
}
str = _sndio_parsenum(str, &devnum, 255);
if (str == NULL || *str != '\0') {
- DPRINTF("_sio_sun_open: can't determine device number\n");
- return NULL;
+ DPRINTF("sio_sun_getfd: can't determine device number\n");
+ return -1;
}
- hdl = malloc(sizeof(struct sio_sun_hdl));
- if (hdl == NULL)
- return NULL;
- _sio_create(&hdl->sio, &sio_sun_ops, mode, nbio);
-
snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum);
if (mode == (SIO_PLAY | SIO_REC))
flags = O_RDWR;
else
flags = (mode & SIO_PLAY) ? O_WRONLY : O_RDONLY;
-
while ((fd = open(path, flags | O_NONBLOCK | O_CLOEXEC)) < 0) {
if (errno == EINTR)
continue;
DPERROR(path);
- goto bad_free;
+ return -1;
}
+ return fd;
+}
+
+static struct sio_hdl *
+sio_sun_fdopen(int fd, unsigned int mode, int nbio)
+{
+ struct audio_info aui;
+ struct sio_sun_hdl *hdl;
+ struct sio_par par;
+
+ hdl = malloc(sizeof(struct sio_sun_hdl));
+ if (hdl == NULL)
+ return NULL;
+ _sio_create(&hdl->sio, &sio_sun_ops, mode, nbio);
/*
* pause the device
@@ -379,7 +386,7 @@ _sio_sun_open(const char *str, unsigned int mode, int nbio)
aui.record.pause = 1;
if (ioctl(fd, AUDIO_SETINFO, &aui) < 0) {
DPERROR("sio_open_sun: setinfo");
- goto bad_close;
+ goto bad_free;
}
hdl->fd = fd;
@@ -397,16 +404,30 @@ _sio_sun_open(const char *str, unsigned int mode, int nbio)
par.bits = 16;
par.appbufsz = 1200;
if (!sio_setpar(&hdl->sio, &par))
- goto bad_close;
+ goto bad_free;
return (struct sio_hdl *)hdl;
- bad_close:
- while (close(fd) < 0 && errno == EINTR)
- ; /* retry */
bad_free:
free(hdl);
return NULL;
}
+struct sio_hdl *
+_sio_sun_open(const char *str, unsigned int mode, int nbio)
+{
+ struct sio_hdl *hdl;
+ int fd;
+
+ fd = sio_sun_getfd(str, mode, nbio);
+ if (fd < 0)
+ return NULL;
+ hdl = sio_sun_fdopen(fd, mode, nbio);
+ if (hdl != NULL)
+ return hdl;
+ while (close(fd) < 0 && errno == EINTR)
+ ; /* retry */
+ return NULL;
+}
+
static void
sio_sun_close(struct sio_hdl *sh)
{