summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2020-12-14 11:10:30 -0500
committerRich Felker <dalias@aerifal.cx>2020-12-14 20:36:13 -0500
commit3953aecbef11f3e8f5ae9388873dfaa554874309 (patch)
tree9d1c6d2a899495ac5202912afba0d1f175a7feeb
parent30f55067a6dcba602797c24e020a6a9c8ba22180 (diff)
downloadmusl-3953aecbef11f3e8f5ae9388873dfaa554874309.tar.gz
fix VIDIOC_DQEVENT (v4l2) ioctl fallback for pre-5.6 kernels
commit 2412638bb39eb799b2600393bbd71cca8ae96bb2 got the size of struct v4l2_event wrong and failed to account for the fact that the old struct might be either 120 bytes with time misaligned mod 8, or 128 bytes with time aligned mod 8, due to the contained union having 64-bit members whose alignment is arch-dependent. rather than adding new logic to handle the differences, use an actual stripped-down version of the structure in question to derive the ioctl number, size, and offsets.
-rw-r--r--src/misc/ioctl.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/misc/ioctl.c b/src/misc/ioctl.c
index 26481c6d..49282811 100644
--- a/src/misc/ioctl.c
+++ b/src/misc/ioctl.c
@@ -4,6 +4,7 @@
#include <time.h>
#include <sys/time.h>
#include <stddef.h>
+#include <stdint.h>
#include <string.h>
#include "syscall.h"
@@ -28,6 +29,12 @@ struct ioctl_compat_map {
* number producing macros; only size of result is meaningful. */
#define new_misaligned(n) struct { int i; time_t t; char c[(n)-4]; }
+struct v4l2_event {
+ uint32_t a;
+ uint64_t b[8];
+ uint32_t c[2], ts[2], d[9];
+};
+
static const struct ioctl_compat_map compat_map[] = {
{ SIOCGSTAMP, SIOCGSTAMP_OLD, 8, R, 0, OFFS(0, 4) },
{ SIOCGSTAMPNS, SIOCGSTAMPNS_OLD, 8, R, 0, OFFS(0, 4) },
@@ -55,7 +62,8 @@ static const struct ioctl_compat_map compat_map[] = {
{ _IOWR('V', 93, new_misaligned(68)), _IOWR('V', 93, char[68]), 68, WR, 1, OFFS(20, 24) },
/* VIDIOC_DQEVENT */
- { _IOR('V', 89, new_misaligned(96)), _IOR('V', 89, char[96]), 96, R, 0, OFFS(76,80) },
+ { _IOR('V', 89, new_misaligned(120)), _IOR('V', 89, struct v4l2_event), sizeof(struct v4l2_event),
+ R, 0, OFFS(offsetof(struct v4l2_event, ts[0]), offsetof(struct v4l2_event, ts[1])) },
/* VIDIOC_OMAP3ISP_STAT_REQ */
{ _IOWR('V', 192+6, char[32]), _IOWR('V', 192+6, char[24]), 22, WR, 0, OFFS(0,4) },