diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2008-11-17 07:04:14 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2008-11-17 07:04:14 +0000 |
commit | c4699bb65b10a9264c14eabe71a08014eb770597 (patch) | |
tree | 0887f548bd384484ab8aa3429a3d4247aab4dc2c | |
parent | f1c0f8ef292dea918f320873df016eedaeb6e2ad (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.c | 29 | ||||
-rw-r--r-- | usr.bin/aucat/aucat.1 | 15 | ||||
-rw-r--r-- | usr.bin/aucat/aucat.c | 41 | ||||
-rw-r--r-- | usr.bin/aucat/sock.c | 7 |
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) { |