diff options
author | Mark Johnston <markj@FreeBSD.org> | 2023-01-16 13:02:54 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2023-01-16 13:02:54 +0000 |
commit | 5c2b216a1cd8de3aabfa9e76ca8f38774acd591e (patch) | |
tree | a14d434bdbec09f8e7ab8bbeb9bb6357a21372e1 | |
parent | 228c632ab3f6245df4a08d8692d49c8e12aacc27 (diff) | |
download | src-5c2b216a1cd8de3aabfa9e76ca8f38774acd591e.tar.gz src-5c2b216a1cd8de3aabfa9e76ca8f38774acd591e.zip |
mixer: Fix default_unit switching with mixers that have no devices
Apparently it's possible for a mixer to have no devices:
$ mixer -f /dev/mixer2
pcm2:mixer: <USB audio> at ? kld snd_uaudio (rec)
$
If this is the default sound device, an attempt to change the default
unit using mixer -d fails with a segfault because mod_dunit is called
with a NULL device pointer, which is dereferenced to get the parent
mixer.
ctl_dunit seems to be a dummy, i.e., we don't actually need it and can
simply pass the mixer to mod_dunit() directly. This patch removes that
structure and associated indirection to fix the crash.
Reviewed by: christos, hselasky
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D38060
-rw-r--r-- | usr.sbin/mixer/mixer.c | 19 |
1 files changed, 5 insertions, 14 deletions
diff --git a/usr.sbin/mixer/mixer.c b/usr.sbin/mixer/mixer.c index e216efe3313c..6095f7550ea8 100644 --- a/usr.sbin/mixer/mixer.c +++ b/usr.sbin/mixer/mixer.c @@ -42,8 +42,8 @@ static void printall(struct mixer *, int); static void printminfo(struct mixer *, int); static void printdev(struct mixer *, int); static void printrecsrc(struct mixer *, int); /* XXX: change name */ +static int set_dunit(struct mixer *, int); /* Control handlers */ -static int mod_dunit(struct mix_dev *, void *); static int mod_volume(struct mix_dev *, void *); static int mod_mute(struct mix_dev *, void *); static int mod_recsrc(struct mix_dev *, void *); @@ -51,14 +51,6 @@ static int print_volume(struct mix_dev *, void *); static int print_mute(struct mix_dev *, void *); static int print_recsrc(struct mix_dev *, void *); -static const mix_ctl_t ctl_dunit = { - .parent_dev = NULL, - .id = -1, - .name = "default_unit", - .mod = mod_dunit, - .print = NULL -}; - int main(int argc, char *argv[]) { @@ -125,7 +117,7 @@ main(int argc, char *argv[]) initctls(m); - if (dflag && ctl_dunit.mod(m->dev, &dunit) < 0) + if (dflag && set_dunit(m, dunit) < 0) goto parse; if (sflag) { printrecsrc(m, oflag); @@ -316,20 +308,19 @@ printrecsrc(struct mixer *m, int oflag) } static int -mod_dunit(struct mix_dev *d, void *p) +set_dunit(struct mixer *m, int dunit) { - int dunit = *((int *)p); int n; if ((n = mixer_get_dunit()) < 0) { warn("cannot get default unit"); return (-1); } - if (mixer_set_dunit(d->parent_mixer, dunit) < 0) { + if (mixer_set_dunit(m, dunit) < 0) { warn("cannot set default unit to: %d", dunit); return (-1); } - printf("%s: %d -> %d\n", ctl_dunit.name, n, dunit); + printf("default_unit: %d -> %d\n", n, dunit); return (0); } |