diff --git a/lib/libmixer/Makefile b/lib/libmixer/Makefile --- a/lib/libmixer/Makefile +++ b/lib/libmixer/Makefile @@ -22,6 +22,7 @@ MLINKS+= mixer.3 mixer_set_dunit.3 MLINKS+= mixer.3 mixer_get_mode.3 MLINKS+= mixer.3 mixer_get_nmixers.3 +MLINKS+= mixer.3 mixer_get_path.3 MLINKS+= mixer.3 MIX_ISDEV.3 MLINKS+= mixer.3 MIX_ISMUTE.3 MLINKS+= mixer.3 MIX_ISREC.3 diff --git a/lib/libmixer/Symbol.map b/lib/libmixer/Symbol.map --- a/lib/libmixer/Symbol.map +++ b/lib/libmixer/Symbol.map @@ -19,3 +19,7 @@ mixer_get_mode; mixer_get_nmixers; }; + +FBSD_1.8 { + mixer_get_path; +}; diff --git a/lib/libmixer/mixer.h b/lib/libmixer/mixer.h --- a/lib/libmixer/mixer.h +++ b/lib/libmixer/mixer.h @@ -115,6 +115,7 @@ int mixer_set_dunit(struct mixer *, int); int mixer_get_mode(int); int mixer_get_nmixers(void); +int mixer_get_path(char *, size_t, int); __END_DECLS diff --git a/lib/libmixer/mixer.3 b/lib/libmixer/mixer.3 --- a/lib/libmixer/mixer.3 +++ b/lib/libmixer/mixer.3 @@ -20,7 +20,7 @@ .\" THE SOFTWARE. .\" -.Dd January 19, 2023 +.Dd May 20, 2024 .Dt MIXER 3 .Os .Sh NAME @@ -40,6 +40,7 @@ .Nm mixer_set_dunit , .Nm mixer_get_mode , .Nm mixer_get_nmixers , +.Nm mixer_get_path , .Nm MIX_ISDEV , .Nm MIX_ISMUTE , .Nm MIX_ISREC , @@ -86,6 +87,8 @@ .Ft int .Fn mixer_get_nmixers "void" .Ft int +.Fn mixer_get_path "char * buf" "size_t size" "int unit" +.Ft int .Fn MIX_ISDEV "struct mixer *m" "int devno" .Ft int .Fn MIX_ISMUTE "struct mixer *m" "int devno" @@ -398,6 +401,18 @@ function returns the total number of mixer devices in the system. .Pp The +.Fn mixer_get_path +function writes the path of the mixer device specified in the +.Ar unit +argument to the buffer specified in +.Ar buf . +.Ar unit +can be either -1, in which case +.Fn mixer_get_path +will fetch the path of the default mixer, or between 0 and the maximum mixer +unit. +.Pp +The .Fn MIX_ISDEV macro checks if a device is actually a valid device for a given mixer. It is very unlikely that this macro will ever be needed since the library \ @@ -467,9 +482,10 @@ .Fn mixer_set_mute , .Fn mixer_mod_recsrc , .Fn mixer_get_dunut , -.Fn mixer_set_dunit +.Fn mixer_set_dunit , +.Fn mixer_get_nmixers , and -.Fn mixer_get_nmixers +.Fn mixer_get_path functions return 0 or positive values on success and -1 on failure. .Pp The @@ -539,6 +555,22 @@ (void)mixer_close(m); .Ed +.Ss Loop through all mixer devices in the system +.Bd -literal +struct mixer *m; +char buf[NAME_MAX]; +int n; + +if ((n = mixer_get_nmixers()) < 0) + errx(1, "no mixers present in the system"); +for (i = 0; i < n; i++) { + (void)mixer_get_path(buf, sizeof(buf), i); + if ((m = mixer_open(buf)) == NULL) + continue; + ... + (void)mixer_close(m); +} +.Ed .Sh SEE ALSO .Xr queue 3 , .Xr sysctl 3 , diff --git a/lib/libmixer/mixer.c b/lib/libmixer/mixer.c --- a/lib/libmixer/mixer.c +++ b/lib/libmixer/mixer.c @@ -493,3 +493,25 @@ return (si.nummixers); } + +/* + * Get the full path to a mixer device. + */ +int +mixer_get_path(char *buf, size_t size, int unit) +{ + if (size < strlen(BASEPATH)) { + errno = ENOMEM; + return (-1); + } + if (!(unit == -1 || (unit >= 0 && unit < mixer_get_nmixers()))) { + errno = EINVAL; + return (-1); + } + if (unit == -1) + (void)strlcpy(buf, BASEPATH, size); + else + (void)snprintf(buf, size, BASEPATH "%d", unit); + + return (0); +}