fix VIDIOC_DQEVENT (v4l2) ioctl fallback for pre-5.6 kernels

commit 2412638bb3 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.
This commit is contained in:
Rich Felker 2020-12-14 11:10:30 -05:00
parent 30f55067a6
commit 3953aecbef

View File

@ -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) },