aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2023-01-16 13:02:54 +0000
committerMark Johnston <markj@FreeBSD.org>2023-01-16 13:02:54 +0000
commit5c2b216a1cd8de3aabfa9e76ca8f38774acd591e (patch)
treea14d434bdbec09f8e7ab8bbeb9bb6357a21372e1
parent228c632ab3f6245df4a08d8692d49c8e12aacc27 (diff)
downloadsrc-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.c19
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);
}