diff options
author | 2019-09-21 04:42:46 +0000 | |
---|---|---|
committer | 2019-09-21 04:42:46 +0000 | |
commit | 731605d74e40baf38ff90558526d98b93c326088 (patch) | |
tree | ed81648641a0cb9aed9152e0927a2da698458e58 | |
parent | Expand scsi_inquiry_data to 96 bytes to include new fields. If the (diff) | |
download | wireguard-openbsd-731605d74e40baf38ff90558526d98b93c326088.tar.xz wireguard-openbsd-731605d74e40baf38ff90558526d98b93c326088.zip |
Allow switching between devices without disconnecting clients.
The new -F option allows alternate device to be specified. If the
device is disconnected, the one given with the last -f or -F options
will be used instead. Similarly, the new -Q option allows an alternate
MIDI port to be specified.
ok mpi@
-rw-r--r-- | usr.bin/sndiod/dev.c | 75 | ||||
-rw-r--r-- | usr.bin/sndiod/dev.h | 5 | ||||
-rw-r--r-- | usr.bin/sndiod/fdpass.c | 15 | ||||
-rw-r--r-- | usr.bin/sndiod/midi.c | 19 | ||||
-rw-r--r-- | usr.bin/sndiod/midi.h | 5 | ||||
-rw-r--r-- | usr.bin/sndiod/miofile.c | 34 | ||||
-rw-r--r-- | usr.bin/sndiod/miofile.h | 3 | ||||
-rw-r--r-- | usr.bin/sndiod/siofile.c | 80 | ||||
-rw-r--r-- | usr.bin/sndiod/siofile.h | 3 | ||||
-rw-r--r-- | usr.bin/sndiod/sndiod.8 | 33 | ||||
-rw-r--r-- | usr.bin/sndiod/sndiod.c | 63 | ||||
-rw-r--r-- | usr.bin/sndiod/utils.c | 29 | ||||
-rw-r--r-- | usr.bin/sndiod/utils.h | 10 |
13 files changed, 336 insertions, 38 deletions
diff --git a/usr.bin/sndiod/dev.c b/usr.bin/sndiod/dev.c index 7fe63983083..1e289f82545 100644 --- a/usr.bin/sndiod/dev.c +++ b/usr.bin/sndiod/dev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.c,v 1.61 2019/09/19 05:10:19 ratchov Exp $ */ +/* $OpenBSD: dev.c,v 1.62 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -969,7 +969,8 @@ dev_new(char *path, struct aparams *par, return NULL; } d = xmalloc(sizeof(struct dev)); - d->path = xstrdup(path); + d->path_list = NULL; + namelist_add(&d->path_list, path); d->num = dev_sndnum++; d->opt_list = NULL; @@ -1174,6 +1175,74 @@ dev_close(struct dev *d) dev_freebufs(d); } +/* + * Close the device, but attempt to migrate everything to a new sndio + * device. + */ +int +dev_reopen(struct dev *d) +{ + struct slot *s; + long long pos; + unsigned int pstate; + int delta; + + /* not opened */ + if (d->pstate == DEV_CFG) + return 1; + + /* save state */ + delta = d->delta; + pstate = d->pstate; + + if (!dev_sio_reopen(d)) + return 0; + + /* reopen returns a stopped device */ + d->pstate = DEV_INIT; + + /* reallocate new buffers, with new parameters */ + dev_freebufs(d); + dev_allocbufs(d); + + /* + * adjust time positions, make anything go back delta ticks, so + * that the new device can start at zero + */ + for (s = d->slot_list; s != NULL; s = s->next) { + pos = (long long)s->delta * d->round + s->delta_rem; + pos -= (long long)delta * s->round; + s->delta_rem = pos % (int)d->round; + s->delta = pos / (int)d->round; + if (log_level >= 3) { + slot_log(s); + log_puts(": adjusted: delta -> "); + log_puti(s->delta); + log_puts(", delta_rem -> "); + log_puti(s->delta_rem); + log_puts("\n"); + } + + /* reinitilize the format conversion chain */ + slot_initconv(s); + } + if (d->tstate == MMC_RUN) { + d->mtc.delta -= delta * MTC_SEC; + if (log_level >= 2) { + dev_log(d); + log_puts(": adjusted mtc: delta ->"); + log_puti(d->mtc.delta); + log_puts("\n"); + } + } + + /* start the device if needed */ + if (pstate == DEV_RUN) + dev_wakeup(d); + + return 1; +} + int dev_ref(struct dev *d) { @@ -1280,7 +1349,7 @@ dev_del(struct dev *d) } midi_del(d->midi); *p = d->next; - xfree(d->path); + namelist_clear(&d->path_list); xfree(d); } diff --git a/usr.bin/sndiod/dev.h b/usr.bin/sndiod/dev.h index bd909060bdf..69a51297f72 100644 --- a/usr.bin/sndiod/dev.h +++ b/usr.bin/sndiod/dev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.h,v 1.21 2019/07/12 06:30:55 ratchov Exp $ */ +/* $OpenBSD: dev.h,v 1.22 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -159,7 +159,7 @@ struct dev { #define DEV_INIT 1 /* stopped */ #define DEV_RUN 2 /* playin & recording */ unsigned int pstate; /* one of above */ - char *path; /* sio path */ + struct name *path_list; /* * actual parameters and runtime state (i.e. once opened) @@ -201,6 +201,7 @@ extern struct dev *dev_list; void dev_log(struct dev *); void dev_close(struct dev *); +int dev_reopen(struct dev *); struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); struct dev *dev_bynum(int); diff --git a/usr.bin/sndiod/fdpass.c b/usr.bin/sndiod/fdpass.c index 42de8e7502f..30ed39f1e14 100644 --- a/usr.bin/sndiod/fdpass.c +++ b/usr.bin/sndiod/fdpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fdpass.c,v 1.6 2019/06/28 13:35:03 deraadt Exp $ */ +/* $OpenBSD: fdpass.c,v 1.7 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2015 Alexandre Ratchov <alex@caoua.org> * @@ -300,6 +300,7 @@ fdpass_in_helper(void *arg) struct fdpass *f = arg; struct dev *d; struct port *p; + struct name *path; if (!fdpass_recv(f, &cmd, &num, &mode, &fd)) return; @@ -314,7 +315,11 @@ fdpass_in_helper(void *arg) fdpass_close(f); return; } - fd = sio_sun_getfd(d->path, mode, 1); + for (path = d->path_list; path != NULL; path = path->next) { + fd = sio_sun_getfd(path->str, mode, 1); + if (fd != -1) + break; + } break; case FDPASS_OPEN_MIDI: p = port_bynum(num); @@ -326,7 +331,11 @@ fdpass_in_helper(void *arg) fdpass_close(f); return; } - fd = mio_rmidi_getfd(p->path, mode, 1); + for (path = p->path_list; path != NULL; path = path->next) { + fd = mio_rmidi_getfd(path->str, mode, 1); + if (fd != -1) + break; + } break; default: fdpass_close(f); diff --git a/usr.bin/sndiod/midi.c b/usr.bin/sndiod/midi.c index c2287f826f3..46ac3929f24 100644 --- a/usr.bin/sndiod/midi.c +++ b/usr.bin/sndiod/midi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.c,v 1.21 2019/08/29 07:19:15 ratchov Exp $ */ +/* $OpenBSD: midi.c,v 1.22 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -438,7 +438,8 @@ port_new(char *path, unsigned int mode, int hold) struct port *c; c = xmalloc(sizeof(struct port)); - c->path = xstrdup(path); + c->path_list = NULL; + namelist_add(&c->path_list, path); c->state = PORT_CFG; c->hold = hold; c->midi = midi_new(&port_midiops, c, mode); @@ -468,7 +469,7 @@ port_del(struct port *c) #endif } *p = c->next; - xfree(c->path); + namelist_clear(&c->path_list); xfree(c); } @@ -593,3 +594,15 @@ port_done(struct port *c) if (c->state == PORT_INIT) port_drain(c); } + +int +port_reopen(struct port *p) +{ + if (p->state == PORT_CFG) + return 1; + + if (!port_mio_reopen(p)) + return 0; + + return 1; +} diff --git a/usr.bin/sndiod/midi.h b/usr.bin/sndiod/midi.h index 91fa81c133d..c9f48875d70 100644 --- a/usr.bin/sndiod/midi.h +++ b/usr.bin/sndiod/midi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.h,v 1.9 2019/08/29 07:11:28 ratchov Exp $ */ +/* $OpenBSD: midi.h,v 1.10 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -88,7 +88,7 @@ struct port { #define PORT_DRAIN 2 unsigned int state; unsigned int num; /* port serial number */ - char *path; + struct name *path_list; int hold; /* hold the port open ? */ struct midi *midi; }; @@ -121,5 +121,6 @@ int port_init(struct port *); void port_done(struct port *); void port_drain(struct port *); int port_close(struct port *); +int port_reopen(struct port *); #endif /* !defined(MIDI_H) */ diff --git a/usr.bin/sndiod/miofile.c b/usr.bin/sndiod/miofile.c index ab32639e00c..3c2d56db4aa 100644 --- a/usr.bin/sndiod/miofile.c +++ b/usr.bin/sndiod/miofile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: miofile.c,v 1.4 2015/12/20 11:38:33 ratchov Exp $ */ +/* $OpenBSD: miofile.c,v 1.5 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -51,7 +51,34 @@ port_mio_open(struct port *p) p->mio.hdl = fdpass_mio_open(p->num, p->midi->mode); if (p->mio.hdl == NULL) return 0; - p->mio.file = file_new(&port_mio_ops, p, p->path, mio_nfds(p->mio.hdl)); + p->mio.file = file_new(&port_mio_ops, p, "port", mio_nfds(p->mio.hdl)); + return 1; +} + +/* + * Open an alternate port. Upon success, close the old port + * and continue using the new one. + */ +int +port_mio_reopen(struct port *p) +{ + struct mio_hdl *hdl; + + hdl = fdpass_mio_open(p->num, p->midi->mode); + if (hdl == NULL) { + if (log_level >= 1) { + port_log(p); + log_puts(": couldn't open an alternate port\n"); + } + return 0; + } + + /* close unused device */ + file_del(p->mio.file); + mio_close(p->mio.hdl); + + p->mio.hdl = hdl; + p->mio.file = file_new(&port_mio_ops, p, "port", mio_nfds(hdl)); return 1; } @@ -129,5 +156,6 @@ port_mio_hup(void *arg) { struct port *p = arg; - port_close(p); + if (!port_reopen(p)) + port_close(p); } diff --git a/usr.bin/sndiod/miofile.h b/usr.bin/sndiod/miofile.h index 128bd32ff08..703caa023d5 100644 --- a/usr.bin/sndiod/miofile.h +++ b/usr.bin/sndiod/miofile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: miofile.h,v 1.1 2012/11/23 07:03:28 ratchov Exp $ */ +/* $OpenBSD: miofile.h,v 1.2 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -25,6 +25,7 @@ struct port_mio { }; int port_mio_open(struct port *); +int port_mio_reopen(struct port *); void port_mio_close(struct port *); #endif /* !defined(MIOFILE_H) */ diff --git a/usr.bin/sndiod/siofile.c b/usr.bin/sndiod/siofile.c index aacf2a1de0c..c720c61bab6 100644 --- a/usr.bin/sndiod/siofile.c +++ b/usr.bin/sndiod/siofile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: siofile.c,v 1.15 2019/08/29 07:05:47 ratchov Exp $ */ +/* $OpenBSD: siofile.c,v 1.16 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -212,7 +212,7 @@ dev_sio_open(struct dev *d) if (!(mode & MODE_REC)) d->mode &= ~MODE_REC; sio_onmove(d->sio.hdl, dev_sio_onmove, d); - d->sio.file = file_new(&dev_sio_ops, d, d->path, sio_nfds(d->sio.hdl)); + d->sio.file = file_new(&dev_sio_ops, d, "dev", sio_nfds(d->sio.hdl)); timo_set(&d->sio.watchdog, dev_sio_timeout, d); return 1; bad_close: @@ -220,6 +220,79 @@ dev_sio_open(struct dev *d) return 0; } +/* + * Open an alternate device. Upon success and if the new device is + * compatible with the old one, close the old device and continue + * using the new one. The new device is not started. + */ +int +dev_sio_reopen(struct dev *d) +{ + struct sio_par par; + struct sio_hdl *hdl; + + hdl = fdpass_sio_open(d->num, d->mode & (MODE_PLAY | MODE_REC)); + if (hdl == NULL) { + if (log_level >= 1) { + dev_log(d); + log_puts(": couldn't open an alternate device\n"); + } + return 0; + } + + sio_initpar(&par); + par.bits = d->par.bits; + par.bps = d->par.bps; + par.sig = d->par.sig; + par.le = d->par.le; + par.msb = d->par.msb; + if (d->mode & SIO_PLAY) + par.pchan = d->pchan; + if (d->mode & SIO_REC) + par.rchan = d->rchan; + par.appbufsz = d->bufsz; + par.round = d->round; + par.rate = d->rate; + if (!sio_setpar(hdl, &par)) + goto bad_close; + if (!sio_getpar(hdl, &par)) + goto bad_close; + + /* check if new parameters are compatible with old ones */ + if (par.round != d->round || par.bufsz != d->bufsz || + par.rate != d->rate) { + if (log_level >= 1) { + dev_log(d); + log_puts(": alternate device not compatible\n"); + } + goto bad_close; + } + + /* close unused device */ + timo_del(&d->sio.watchdog); + file_del(d->sio.file); + sio_close(d->sio.hdl); + + /* update parameters */ + d->par.bits = par.bits; + d->par.bps = par.bps; + d->par.sig = par.sig; + d->par.le = par.le; + d->par.msb = par.msb; + if (d->mode & SIO_PLAY) + d->pchan = par.pchan; + if (d->mode & SIO_REC) + d->rchan = par.rchan; + + d->sio.hdl = hdl; + d->sio.file = file_new(&dev_sio_ops, d, "dev", sio_nfds(hdl)); + sio_onmove(hdl, dev_sio_onmove, d); + return 1; +bad_close: + sio_close(hdl); + return 0; +} + void dev_sio_close(struct dev *d) { @@ -494,5 +567,6 @@ dev_sio_hup(void *arg) log_puts(": disconnected\n"); } #endif - dev_close(d); + if (!dev_reopen(d)) + dev_close(d); } diff --git a/usr.bin/sndiod/siofile.h b/usr.bin/sndiod/siofile.h index a763b3adef2..4cebf879730 100644 --- a/usr.bin/sndiod/siofile.h +++ b/usr.bin/sndiod/siofile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: siofile.h,v 1.3 2013/09/28 18:49:32 ratchov Exp $ */ +/* $OpenBSD: siofile.h,v 1.4 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -38,6 +38,7 @@ struct dev_sio { }; int dev_sio_open(struct dev *); +int dev_sio_reopen(struct dev *); void dev_sio_close(struct dev *); void dev_sio_log(struct dev *); void dev_sio_start(struct dev *); diff --git a/usr.bin/sndiod/sndiod.8 b/usr.bin/sndiod/sndiod.8 index 2945dff5b70..cd643dd08e3 100644 --- a/usr.bin/sndiod/sndiod.8 +++ b/usr.bin/sndiod/sndiod.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sndiod.8,v 1.2 2016/01/18 11:38:07 ratchov Exp $ +.\" $OpenBSD: sndiod.8,v 1.3 2019/09/21 04:42:46 ratchov Exp $ .\" .\" Copyright (c) 2006-2012 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: January 18 2016 $ +.Dd $Mdocdate: September 21 2019 $ .Dt SNDIOD 8 .Os .Sh NAME @@ -29,10 +29,12 @@ .Op Fl C Ar min : Ns Ar max .Op Fl c Ar min : Ns Ar max .Op Fl e Ar enc +.Op Fl F Ar device .Op Fl f Ar device .Op Fl j Ar flag .Op Fl L Ar addr .Op Fl m Ar mode +.Op Fl Q Ar port .Op Fl q Ar port .Op Fl r Ar rate .Op Fl s Ar name @@ -182,6 +184,18 @@ or Only the signedness and the precision are mandatory. Examples: .Va u8 , s16le , s24le3 , s24le4lsb . +.It Fl F Ar device +Specify an alternate device to use. +If doesn't work, the one given with the last +.Fl f +or +.Fl F +options will be used. +For instance, specifying a USB device following a +PCI device allows +.Nm +to use the USB one preferably when it's connected +and to fall back to the PCI one when it's disconnected. .It Fl f Ar device Add this .Xr sndio 7 @@ -245,6 +259,15 @@ but the same sub-device cannot be used for both recording and monitoring. The default is .Ar play , Ns Ar rec (i.e. full-duplex). +.It Fl Q Ar port +Specify an alternate MIDI port to use. +If doesn't work, the one given with the last +.Fl Q +or +.Fl q +options will be used. +For instance, this allows to replace a USB MIDI controller without +the need to restart programs using it. .It Fl q Ar port Expose the given MIDI port. This allows multiple programs to share the port. @@ -376,11 +399,15 @@ is If .Nm is sent -.Dv SIGHUP , .Dv SIGINT or .Dv SIGTERM , it terminates. +If +.Nm +is sent +.Dv SIGHUP , +it reopens all audio devices and MIDI ports. .Pp By default, when the program cannot accept recorded data fast enough or cannot provide data to play fast enough, diff --git a/usr.bin/sndiod/sndiod.c b/usr.bin/sndiod/sndiod.c index 18f171a315a..2046b6c13ad 100644 --- a/usr.bin/sndiod/sndiod.c +++ b/usr.bin/sndiod/sndiod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sndiod.c,v 1.35 2019/06/29 21:23:18 ratchov Exp $ */ +/* $OpenBSD: sndiod.c,v 1.36 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -93,6 +93,7 @@ #endif void sigint(int); +void sighup(int); void opt_ch(int *, int *); void opt_enc(struct aparams *); int opt_mmc(void); @@ -109,12 +110,13 @@ struct opt *mkopt(char *, struct dev *, int, int, int, int, int, int, int, int); unsigned int log_level = 0; -volatile sig_atomic_t quit_flag = 0; +volatile sig_atomic_t quit_flag = 0, reopen_flag = 0; char usagestr[] = "usage: sndiod [-d] [-a flag] [-b nframes] " - "[-C min:max] [-c min:max] [-e enc]\n\t" - "[-f device] [-j flag] [-L addr] [-m mode] [-q port] [-r rate]\n\t" - "[-s name] [-t mode] [-U unit] [-v volume] [-w flag] [-z nframes]\n"; + "[-C min:max] [-c min:max]\n\t" + "[-e enc] [-F device] [-f device] [-j flag] [-L addr] [-m mode]\n\t" + "[-Q port] [-q port] [-r rate] [-s name] [-t mode] [-U unit]\n\t" + "[-v volume] [-w flag] [-z nframes]\n"; /* * SIGINT handler, it raises the quit flag. If the flag is already set, @@ -129,6 +131,16 @@ sigint(int s) quit_flag = 1; } +/* + * SIGHUP handler, it raises the reopen flag, which requests devices + * to be reopened. + */ +void +sighup(int s) +{ + reopen_flag = 1; +} + void opt_ch(int *rcmin, int *rcmax) { @@ -231,6 +243,7 @@ setsig(void) struct sigaction sa; quit_flag = 0; + reopen_flag = 0; sigfillset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = sigint; @@ -238,6 +251,7 @@ setsig(void) err(1, "sigaction(int) failed"); if (sigaction(SIGTERM, &sa, NULL) == -1) err(1, "sigaction(term) failed"); + sa.sa_handler = sighup; if (sigaction(SIGHUP, &sa, NULL) == -1) err(1, "sigaction(hup) failed"); } @@ -294,7 +308,8 @@ mkdev(char *path, struct aparams *par, struct dev *d; for (d = dev_list; d != NULL; d = d->next) { - if (strcmp(d->path, path) == 0) + if (d->path_list->next == NULL && + strcmp(d->path_list->str, path) == 0) return d; } if (!bufsz && !round) { @@ -316,7 +331,8 @@ mkport(char *path, int hold) struct port *c; for (c = port_list; c != NULL; c = c->next) { - if (strcmp(c->path, path) == 0) + if (c->path_list->next == NULL && + strcmp(c->path_list->str, path) == 0) return c; } c = port_new(path, MODE_MIDIMASK, hold); @@ -361,6 +377,7 @@ start_helper(int background) struct dev *d; struct port *p; struct passwd *pw; + struct name *n; int s[2]; pid_t pid; @@ -395,10 +412,14 @@ start_helper(int background) setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) err(1, "cannot drop privileges"); } - for (d = dev_list; d != NULL; d = d->next) - dounveil(d->path, "rsnd/", "/dev/audio"); - for (p = port_list; p != NULL; p = p->next) - dounveil(p->path, "rmidi/", "/dev/rmidi"); + for (d = dev_list; d != NULL; d = d->next) { + for (n = d->path_list; n != NULL; n = n->next) + dounveil(n->str, "rsnd/", "/dev/audio"); + } + for (p = port_list; p != NULL; p = p->next) { + for (n = p->path_list; n != NULL; n = n->next) + dounveil(n->str, "rmidi/", "/dev/rmidi"); + } if (pledge("stdio sendfd rpath wpath", NULL) == -1) err(1, "pledge"); while (file_poll()) @@ -461,7 +482,8 @@ main(int argc, char **argv) mode = MODE_PLAY | MODE_REC; tcpaddr_list = NULL; - while ((c = getopt(argc, argv, "a:b:c:C:de:f:j:L:m:q:r:s:t:U:v:w:x:z:")) != -1) { + while ((c = getopt(argc, argv, + "a:b:c:C:de:F:f:j:L:m:Q:q:r:s:t:U:v:w:x:z:")) != -1) { switch (c) { case 'd': log_level++; @@ -518,6 +540,11 @@ main(int argc, char **argv) case 'q': mkport(optarg, hold); break; + case 'Q': + if (port_list == NULL) + errx(1, "-Q %s: no ports defined", optarg); + namelist_add(&port_list->path_list, optarg); + break; case 'a': hold = opt_onoff(); break; @@ -538,6 +565,11 @@ main(int argc, char **argv) mkdev(optarg, &par, 0, bufsz, round, rate, hold, autovol); break; + case 'F': + if (dev_list == NULL) + errx(1, "-F %s: no devices defined", optarg); + namelist_add(&dev_list->path_list, optarg); + break; default: fputs(usagestr, stderr); return 1; @@ -617,6 +649,13 @@ main(int argc, char **argv) for (;;) { if (quit_flag) break; + if (reopen_flag) { + reopen_flag = 0; + for (d = dev_list; d != NULL; d = d->next) + dev_reopen(d); + for (p = port_list; p != NULL; p = p->next) + port_reopen(p); + } if (!fdpass_peer) break; if (!file_poll()) diff --git a/usr.bin/sndiod/utils.c b/usr.bin/sndiod/utils.c index 175b61bae79..75b709ed612 100644 --- a/usr.bin/sndiod/utils.c +++ b/usr.bin/sndiod/utils.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utils.c,v 1.5 2019/07/05 07:34:40 ratchov Exp $ */ +/* $OpenBSD: utils.c,v 1.6 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2003-2012 Alexandre Ratchov <alex@caoua.org> * @@ -188,3 +188,30 @@ xstrdup(char *s) memcpy(p, s, size); return p; } + +/* + * copy and append the given string to the name list + */ +void +namelist_add(struct name **list, char *str) +{ + struct name *n; + size_t size; + + size = strlen(str) + 1; + n = xmalloc(sizeof(struct name) + size); + memcpy(n->str, str, size); + n->next = *list; + *list = n; +} + +void +namelist_clear(struct name **list) +{ + struct name *n; + + while ((n = *list) != NULL) { + *list = n->next; + xfree(n); + } +} diff --git a/usr.bin/sndiod/utils.h b/usr.bin/sndiod/utils.h index f108ed56c63..62042c96164 100644 --- a/usr.bin/sndiod/utils.h +++ b/usr.bin/sndiod/utils.h @@ -1,4 +1,4 @@ -/* $OpenBSD: utils.h,v 1.3 2013/05/12 04:58:41 ratchov Exp $ */ +/* $OpenBSD: utils.h,v 1.4 2019/09/21 04:42:46 ratchov Exp $ */ /* * Copyright (c) 2003-2012 Alexandre Ratchov <alex@caoua.org> * @@ -20,6 +20,11 @@ #include <stddef.h> +struct name { + struct name *next; + char str[]; +}; + void log_puts(char *); void log_putx(unsigned long); void log_putu(unsigned long); @@ -31,6 +36,9 @@ void *xmalloc(size_t); char *xstrdup(char *); void xfree(void *); +void namelist_add(struct name **, char *); +void namelist_clear(struct name **); + /* * Log levels: * |