git: 30fd79b0c0a3 - main - sndctl(8): Fix dp->realtime
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 21 May 2025 19:31:37 UTC
The branch main has been updated by christos:
URL: https://cgit.FreeBSD.org/src/commit/?id=30fd79b0c0a328536b166e7fa9170b059e711303
commit 30fd79b0c0a328536b166e7fa9170b059e711303
Author: Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2025-05-21 19:31:28 +0000
Commit: Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2025-05-21 19:31:28 +0000
sndctl(8): Fix dp->realtime
Currently it's automatically set to 0 in read_dev() as a result of
allocating dp with calloc().
Sponsored by: The FreeBSD Foundation
MFC after: 1 day
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D50400
---
usr.sbin/sndctl/sndctl.c | 189 ++++++++++++++++++++++++-----------------------
1 file changed, 98 insertions(+), 91 deletions(-)
diff --git a/usr.sbin/sndctl/sndctl.c b/usr.sbin/sndctl/sndctl.c
index 4d3ae0cf526c..156c845481c5 100644
--- a/usr.sbin/sndctl/sndctl.c
+++ b/usr.sbin/sndctl/sndctl.c
@@ -333,6 +333,96 @@ bytes2frames(int bytes, int fmt)
return (bytes / (samplesz * ch));
}
+static int
+sysctl_int(const char *buf, const char *arg, int *var)
+{
+ size_t size;
+ int n, prev;
+
+ size = sizeof(int);
+ /* Read current value. */
+ if (sysctlbyname(buf, &prev, &size, NULL, 0) < 0) {
+ warn("sysctlbyname(%s)", buf);
+ return (-1);
+ }
+
+ /* Read-only. */
+ if (arg != NULL) {
+ errno = 0;
+ n = strtol(arg, NULL, 10);
+ if (errno == EINVAL || errno == ERANGE) {
+ warn("strtol(%s)", arg);
+ return (-1);
+ }
+
+ /* Apply new value. */
+ if (sysctlbyname(buf, NULL, 0, &n, size) < 0) {
+ warn("sysctlbyname(%s, %d)", buf, n);
+ return (-1);
+ }
+ }
+
+ /* Read back applied value for good measure. */
+ if (sysctlbyname(buf, &n, &size, NULL, 0) < 0) {
+ warn("sysctlbyname(%s)", buf);
+ return (-1);
+ }
+
+ if (arg != NULL)
+ printf("%s: %d -> %d\n", buf, prev, n);
+ if (var != NULL)
+ *var = n;
+
+ return (0);
+}
+
+static int
+sysctl_str(const char *buf, const char *arg, char *var, size_t varsz)
+{
+ size_t size;
+ char prev[BUFSIZ];
+ char *tmp;
+
+ /* Read current value. */
+ size = sizeof(prev);
+ if (sysctlbyname(buf, prev, &size, NULL, 0) < 0) {
+ warn("sysctlbyname(%s)", buf);
+ return (-1);
+ }
+
+ /* Read-only. */
+ if (arg != NULL) {
+ size = strlen(arg);
+ /* Apply new value. */
+ if (sysctlbyname(buf, NULL, 0, arg, size) < 0) {
+ warn("sysctlbyname(%s, %s)", buf, arg);
+ return (-1);
+ }
+ /* Get size of new string. */
+ if (sysctlbyname(buf, NULL, &size, NULL, 0) < 0) {
+ warn("sysctlbyname(%s)", buf);
+ return (-1);
+ }
+ }
+
+ if ((tmp = calloc(1, size)) == NULL)
+ err(1, "calloc");
+ /* Read back applied value for good measure. */
+ if (sysctlbyname(buf, tmp, &size, NULL, 0) < 0) {
+ warn("sysctlbyname(%s)", buf);
+ free(tmp);
+ return (-1);
+ }
+
+ if (arg != NULL)
+ printf("%s: %s -> %s\n", buf, prev, tmp);
+ if (var != NULL)
+ strlcpy(var, tmp, varsz);
+ free(tmp);
+
+ return (0);
+}
+
static struct snd_dev *
read_dev(char *path)
{
@@ -343,7 +433,7 @@ read_dev(char *path)
struct snd_dev *dp = NULL;
struct snd_chan *ch;
size_t nitems, nchans, i, j;
- int fd, caps, unit;
+ int fd, caps, unit, t1, t2, t3;
if ((fd = open("/dev/sndstat", O_RDONLY)) < 0)
err(1, "open(/dev/sndstat)");
@@ -456,6 +546,13 @@ read_dev(char *path)
dp->autoconv = (dp->play.vchans || dp->rec.vchans) && !dp->bitperfect;
+ if (sysctl_int("hw.snd.latency", NULL, &t1) ||
+ sysctl_int("hw.snd.latency_profile", NULL, &t2) ||
+ sysctl_int("kern.timecounter.alloweddeviation", NULL, &t3))
+ err(1, "%s: sysctl", dp->name);
+ if (t1 == 0 && t2 == 0 && t3 == 0)
+ dp->realtime = 1;
+
if (!nvlist_exists(nvlist_get_nvlist(di[i],
SNDST_DSPS_PROVIDER_INFO), SNDST_DSPS_SOUND4_CHAN_INFO))
errx(1, "%s: channel info list empty", dp->name);
@@ -658,96 +755,6 @@ print_dev(struct snd_dev *dp)
}
}
-static int
-sysctl_int(const char *buf, const char *arg, int *var)
-{
- size_t size;
- int n, prev;
-
- size = sizeof(int);
- /* Read current value. */
- if (sysctlbyname(buf, &prev, &size, NULL, 0) < 0) {
- warn("sysctlbyname(%s)", buf);
- return (-1);
- }
-
- /* Read-only. */
- if (arg != NULL) {
- errno = 0;
- n = strtol(arg, NULL, 10);
- if (errno == EINVAL || errno == ERANGE) {
- warn("strtol(%s)", arg);
- return (-1);
- }
-
- /* Apply new value. */
- if (sysctlbyname(buf, NULL, 0, &n, size) < 0) {
- warn("sysctlbyname(%s, %d)", buf, n);
- return (-1);
- }
- }
-
- /* Read back applied value for good measure. */
- if (sysctlbyname(buf, &n, &size, NULL, 0) < 0) {
- warn("sysctlbyname(%s)", buf);
- return (-1);
- }
-
- if (arg != NULL)
- printf("%s: %d -> %d\n", buf, prev, n);
- if (var != NULL)
- *var = n;
-
- return (0);
-}
-
-static int
-sysctl_str(const char *buf, const char *arg, char *var, size_t varsz)
-{
- size_t size;
- char prev[BUFSIZ];
- char *tmp;
-
- /* Read current value. */
- size = sizeof(prev);
- if (sysctlbyname(buf, prev, &size, NULL, 0) < 0) {
- warn("sysctlbyname(%s)", buf);
- return (-1);
- }
-
- /* Read-only. */
- if (arg != NULL) {
- size = strlen(arg);
- /* Apply new value. */
- if (sysctlbyname(buf, NULL, 0, arg, size) < 0) {
- warn("sysctlbyname(%s, %s)", buf, arg);
- return (-1);
- }
- /* Get size of new string. */
- if (sysctlbyname(buf, NULL, &size, NULL, 0) < 0) {
- warn("sysctlbyname(%s)", buf);
- return (-1);
- }
- }
-
- if ((tmp = calloc(1, size)) == NULL)
- err(1, "calloc");
- /* Read back applied value for good measure. */
- if (sysctlbyname(buf, tmp, &size, NULL, 0) < 0) {
- warn("sysctlbyname(%s)", buf);
- free(tmp);
- return (-1);
- }
-
- if (arg != NULL)
- printf("%s: %s -> %s\n", buf, prev, tmp);
- if (var != NULL)
- strlcpy(var, tmp, varsz);
- free(tmp);
-
- return (0);
-}
-
static int
mod_bitperfect(struct snd_dev *dp, void *arg)
{