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
This commit is contained in:
parent
228c632ab3
commit
5c2b216a1c
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user