summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2008-11-17 07:04:14 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2008-11-17 07:04:14 +0000
commitc4699bb65b10a9264c14eabe71a08014eb770597 (patch)
tree0887f548bd384484ab8aa3429a3d4247aab4dc2c
parentf1c0f8ef292dea918f320873df016eedaeb6e2ad (diff)
allow aucat to run as server in play-only and record-only mode, so
it can be used on play-only, record-only and half-duplex devices. ok jakemsr
-rw-r--r--lib/libsndio/aucat.c29
-rw-r--r--usr.bin/aucat/aucat.115
-rw-r--r--usr.bin/aucat/aucat.c41
-rw-r--r--usr.bin/aucat/sock.c7
4 files changed, 70 insertions, 22 deletions
diff --git a/lib/libsndio/aucat.c b/lib/libsndio/aucat.c
index c9aa1752423..d3add816a06 100644
--- a/lib/libsndio/aucat.c
+++ b/lib/libsndio/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.3 2008/11/16 21:18:30 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.4 2008/11/17 07:04:13 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -75,6 +75,7 @@ struct sio_hdl *
sio_open_aucat(char *path, unsigned mode, int nbio)
{
int s;
+ struct sio_cap cap;
struct aucat_hdl *hdl;
struct sockaddr_un ca;
socklen_t len = sizeof(struct sockaddr_un);
@@ -87,19 +88,14 @@ sio_open_aucat(char *path, unsigned mode, int nbio)
sio_create(&hdl->sa, &aucat_ops, mode, nbio);
s = socket(AF_UNIX, SOCK_STREAM, 0);
- if (s < 0) {
- free(hdl);
- return NULL;
- }
+ if (s < 0)
+ goto bad_free;
ca.sun_family = AF_UNIX;
memcpy(ca.sun_path, path, strlen(path) + 1);
while (connect(s, (struct sockaddr *)&ca, len) < 0) {
if (errno == EINTR)
continue;
- while (close(s) < 0 && errno == EINTR)
- ; /* retry */
- free(hdl);
- return NULL;
+ goto bad_connect;
}
hdl->fd = s;
hdl->rstate = STATE_IDLE;
@@ -108,7 +104,18 @@ sio_open_aucat(char *path, unsigned mode, int nbio)
hdl->wtodo = 0xdeadbeef;
hdl->curvol = SIO_MAXVOL;
hdl->reqvol = SIO_MAXVOL;
+ if (!sio_getcap(&hdl->sa, &cap))
+ goto bad_connect;
+ if (((mode & SIO_PLAY) && cap.confs[0].pchan == 0) ||
+ ((mode & SIO_REC) && cap.confs[0].rchan == 0))
+ goto bad_connect;
return (struct sio_hdl *)hdl;
+ bad_connect:
+ while (close(s) < 0 && errno == EINTR)
+ ; /* retry */
+ bad_free:
+ free(hdl);
+ return NULL;
}
/*
@@ -393,8 +400,8 @@ aucat_getcap(struct sio_hdl *sh, struct sio_cap *cap)
cap->pchan[0] = hdl->rmsg.u.cap.pchan;
cap->rate[0] = hdl->rmsg.u.cap.rate;
cap->confs[0].enc = 1;
- cap->confs[0].pchan = (hdl->sa.mode & SIO_PLAY) ? 1 : 0;
- cap->confs[0].rchan = (hdl->sa.mode & SIO_REC) ? 1 : 0;
+ cap->confs[0].rchan = (hdl->rmsg.u.cap.rchan > 0) ? 1 : 0;
+ cap->confs[0].pchan = (hdl->rmsg.u.cap.pchan > 0) ? 1 : 0;
cap->confs[0].rate = 1;
cap->nconf = 1;
return 1;
diff --git a/usr.bin/aucat/aucat.1 b/usr.bin/aucat/aucat.1
index bf5ffac93ed..e54c6eeb7a5 100644
--- a/usr.bin/aucat/aucat.1
+++ b/usr.bin/aucat/aucat.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: aucat.1,v 1.36 2008/11/16 20:46:16 ratchov Exp $
+.\" $OpenBSD: aucat.1,v 1.37 2008/11/17 07:04:13 ratchov Exp $
.\"
.\" Copyright (c) 2006 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: November 16 2008 $
+.Dd $Mdocdate: November 17 2008 $
.Dt AUCAT 1
.Os
.Sh NAME
@@ -31,6 +31,7 @@
.Op Fl f Ar device
.Op Fl h Ar fmt
.Op Fl i Ar file
+.Op Fl m Ar mode
.Op Fl o Ar file
.Op Fl r Ar rate
.Op Fl s Ar file
@@ -91,6 +92,16 @@ The default socket path is
but other paths can be used with the
.Fl s
option.
+.It Fl m Ar mode
+Set the server mode.
+Valid modes are
+.Va play ,
+.Va rec ,
+and
+.Va duplex ,
+for play-only, record-only and full-duplex, respectively.
+The default is
+.Va duplex .
.It Fl o Ar file
Add this file to the list of files in which to store recorded samples.
If the option argument is
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index ac09696e513..b29b8f7550b 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.42 2008/11/16 20:44:03 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.43 2008/11/17 07:04:13 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -66,6 +66,9 @@
#include "listen.h"
#include "dev.h"
+#define MODE_PLAY 1
+#define MODE_REC 2
+
int debug_level = 0;
volatile int quit_flag = 0;
@@ -173,6 +176,18 @@ opt_xrun(void)
errx(1, "%s: onderrun/overrun policy", optarg);
}
+int
+opt_mode(void)
+{
+ if (strcmp("play", optarg) == 0)
+ return MODE_PLAY;
+ if (strcmp("rec", optarg) == 0)
+ return MODE_REC;
+ if (strcmp("duplex", optarg) == 0)
+ return MODE_PLAY | MODE_REC;
+ errx(1, "%s: bad mode", optarg);
+}
+
/*
* Arguments of -i, -o and -s options are stored in a list.
*/
@@ -302,7 +317,7 @@ main(int argc, char **argv)
struct farglist ifiles, ofiles, sfiles;
struct aparams ipar, opar, dipar, dopar;
struct sigaction sa;
- unsigned bufsz;
+ unsigned bufsz, mode;
char *devpath, *dbgenv;
const char *errstr;
extern char *malloc_options;
@@ -329,9 +344,13 @@ main(int argc, char **argv)
xrun = XRUN_IGNORE;
volctl = MIDI_MAXCTL;
bufsz = 44100 * 4 / 15; /* XXX: use milliseconds, not frames */
+ mode = 0;
- while ((c = getopt(argc, argv, "b:c:C:e:r:h:x:v:i:o:f:lus:")) != -1) {
+ while ((c = getopt(argc, argv, "b:c:C:e:r:h:x:v:i:o:f:m:lus:")) != -1) {
switch (c) {
+ case 'm':
+ mode = opt_mode();
+ break;
case 'h':
hdr = opt_hdr();
break;
@@ -416,10 +435,17 @@ main(int argc, char **argv)
exit(1);
}
- if (l_flag && (!SLIST_EMPTY(&ofiles) || !SLIST_EMPTY(&ifiles)))
- errx(1, "can't use -l and -s with -o or -i");
if (!l_flag && !SLIST_EMPTY(&sfiles))
errx(1, "can't use -s without -l");
+ if ((l_flag || mode != 0) &&
+ (!SLIST_EMPTY(&ofiles) || !SLIST_EMPTY(&ifiles)))
+ errx(1, "can't use -l, -m and -s with -o or -i");
+ if (!mode) {
+ if (l_flag || !SLIST_EMPTY(&ifiles))
+ mode |= MODE_PLAY;
+ if (l_flag || !SLIST_EMPTY(&ofiles))
+ mode |= MODE_REC;
+ }
if (!u_flag && !l_flag) {
/*
@@ -470,14 +496,13 @@ main(int argc, char **argv)
DPRINTF("sigaction(usr2) failed1n");
#endif
filelist_init();
-
/*
* Open the device. Give half of the buffer to the device,
* the other half is for the socket/files
*/
dev_init(devpath,
- (l_flag || !SLIST_EMPTY(&ofiles)) ? &dipar : NULL,
- (l_flag || !SLIST_EMPTY(&ifiles)) ? &dopar : NULL,
+ (mode & MODE_REC) ? &dipar : NULL,
+ (mode & MODE_PLAY) ? &dopar : NULL,
bufsz, l_flag);
/*
diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c
index 26f345937b8..c3e652b0ade 100644
--- a/usr.bin/aucat/sock.c
+++ b/usr.bin/aucat/sock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.c,v 1.7 2008/11/16 20:44:03 ratchov Exp $ */
+/* $OpenBSD: sock.c,v 1.8 2008/11/17 07:04:13 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -700,6 +700,11 @@ sock_execmsg(struct sock *f)
aproc_del(f->pipe.file.rproc);
return 0;
}
+ if (!(f->mode & AMSG_PLAY)) {
+ DPRINTF("sock_execmsg: %p: DATA, not allowed\n", f);
+ aproc_del(f->pipe.file.rproc);
+ return 0;
+ }
f->rstate = SOCK_RDATA;
f->rtodo = m->u.data.size;
if (f->rtodo == 0) {