| Message ID | 20260122121015.3842322-1-paul.elder@ideasonboard.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
Quoting Paul Elder (2026-01-22 12:10:15) > On 32-bit systems, ioctl is redirected to __ioctl_time64, so the latter > needs to be intercepted and handled as well. Add support for this. > > Bug: https://gitlab.freedesktop.org/camera/libcamera/-/issues/290 I think we've switched to Closes: now ? But best I can tell this all looks reasonable and fixes and issue so: Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> > --- > src/v4l2/v4l2_compat.cpp | 21 +++++++++++++++++++++ > src/v4l2/v4l2_compat_manager.cpp | 10 ++++++++++ > src/v4l2/v4l2_compat_manager.h | 2 ++ > 3 files changed, 33 insertions(+) > > diff --git a/src/v4l2/v4l2_compat.cpp b/src/v4l2/v4l2_compat.cpp > index ff833f571bde..10421cef76f4 100644 > --- a/src/v4l2/v4l2_compat.cpp > +++ b/src/v4l2/v4l2_compat.cpp > @@ -165,4 +165,25 @@ LIBCAMERA_PUBLIC int ioctl(int fd, unsigned long request, ...) > return V4L2CompatManager::instance()->ioctl(fd, request, arg); > } > > +/* > + * __USE_TIME64_REDIRECTS redirects ioctl to __ioctl_time64. Disable the > + * -Wmissing-declarations warnings, as the functions won't be declared if > + * __USE_TIME64_REDIRECTS is not in use. > + */ > +#pragma GCC diagnostic push > +#pragma GCC diagnostic ignored "-Wmissing-declarations" > + > +#if HAVE_POSIX_IOCTL > +LIBCAMERA_PUBLIC int __ioctl_time64(int fd, int request, ...) > +#else > +LIBCAMERA_PUBLIC int __ioctl_time64(int fd, unsigned long request, ...) > +#endif > +{ > + void *arg; > + extract_va_arg(void *, arg, request); > + > + return V4L2CompatManager::instance()->ioctl_time64(fd, request, arg); > +} > + > +#pragma GCC diagnostic pop > } > diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp > index f53fb300dde8..4303883712d6 100644 > --- a/src/v4l2/v4l2_compat_manager.cpp > +++ b/src/v4l2/v4l2_compat_manager.cpp > @@ -46,6 +46,7 @@ V4L2CompatManager::V4L2CompatManager() > get_symbol(fops_.dup, "dup"); > get_symbol(fops_.close, "close"); > get_symbol(fops_.ioctl, "ioctl"); > + get_symbol(fops_.ioctl_time64, "__ioctl_time64"); > get_symbol(fops_.mmap, "mmap64"); > get_symbol(fops_.munmap, "munmap"); > } > @@ -249,3 +250,12 @@ int V4L2CompatManager::ioctl(int fd, unsigned long request, void *arg) > > return file->proxy()->ioctl(file.get(), request, arg); > } > + > +int V4L2CompatManager::ioctl_time64(int fd, unsigned long request, void *arg) > +{ > + std::shared_ptr<V4L2CameraFile> file = cameraFile(fd); > + if (!file) > + return fops_.ioctl_time64(fd, request, arg); > + > + return file->proxy()->ioctl(file.get(), request, arg); > +} > diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h > index f7c6f1228282..f713f2333500 100644 > --- a/src/v4l2/v4l2_compat_manager.h > +++ b/src/v4l2/v4l2_compat_manager.h > @@ -34,6 +34,7 @@ public: > dup_func_t dup; > close_func_t close; > ioctl_func_t ioctl; > + ioctl_func_t ioctl_time64; > mmap_func_t mmap; > munmap_func_t munmap; > }; > @@ -50,6 +51,7 @@ public: > int fd, off64_t offset); > int munmap(void *addr, size_t length); > int ioctl(int fd, unsigned long request, void *arg); > + int ioctl_time64(int fd, unsigned long request, void *arg); > > private: > V4L2CompatManager(); > -- > 2.47.2 >
diff --git a/src/v4l2/v4l2_compat.cpp b/src/v4l2/v4l2_compat.cpp index ff833f571bde..10421cef76f4 100644 --- a/src/v4l2/v4l2_compat.cpp +++ b/src/v4l2/v4l2_compat.cpp @@ -165,4 +165,25 @@ LIBCAMERA_PUBLIC int ioctl(int fd, unsigned long request, ...) return V4L2CompatManager::instance()->ioctl(fd, request, arg); } +/* + * __USE_TIME64_REDIRECTS redirects ioctl to __ioctl_time64. Disable the + * -Wmissing-declarations warnings, as the functions won't be declared if + * __USE_TIME64_REDIRECTS is not in use. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-declarations" + +#if HAVE_POSIX_IOCTL +LIBCAMERA_PUBLIC int __ioctl_time64(int fd, int request, ...) +#else +LIBCAMERA_PUBLIC int __ioctl_time64(int fd, unsigned long request, ...) +#endif +{ + void *arg; + extract_va_arg(void *, arg, request); + + return V4L2CompatManager::instance()->ioctl_time64(fd, request, arg); +} + +#pragma GCC diagnostic pop } diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp index f53fb300dde8..4303883712d6 100644 --- a/src/v4l2/v4l2_compat_manager.cpp +++ b/src/v4l2/v4l2_compat_manager.cpp @@ -46,6 +46,7 @@ V4L2CompatManager::V4L2CompatManager() get_symbol(fops_.dup, "dup"); get_symbol(fops_.close, "close"); get_symbol(fops_.ioctl, "ioctl"); + get_symbol(fops_.ioctl_time64, "__ioctl_time64"); get_symbol(fops_.mmap, "mmap64"); get_symbol(fops_.munmap, "munmap"); } @@ -249,3 +250,12 @@ int V4L2CompatManager::ioctl(int fd, unsigned long request, void *arg) return file->proxy()->ioctl(file.get(), request, arg); } + +int V4L2CompatManager::ioctl_time64(int fd, unsigned long request, void *arg) +{ + std::shared_ptr<V4L2CameraFile> file = cameraFile(fd); + if (!file) + return fops_.ioctl_time64(fd, request, arg); + + return file->proxy()->ioctl(file.get(), request, arg); +} diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h index f7c6f1228282..f713f2333500 100644 --- a/src/v4l2/v4l2_compat_manager.h +++ b/src/v4l2/v4l2_compat_manager.h @@ -34,6 +34,7 @@ public: dup_func_t dup; close_func_t close; ioctl_func_t ioctl; + ioctl_func_t ioctl_time64; mmap_func_t mmap; munmap_func_t munmap; }; @@ -50,6 +51,7 @@ public: int fd, off64_t offset); int munmap(void *addr, size_t length); int ioctl(int fd, unsigned long request, void *arg); + int ioctl_time64(int fd, unsigned long request, void *arg); private: V4L2CompatManager();
On 32-bit systems, ioctl is redirected to __ioctl_time64, so the latter needs to be intercepted and handled as well. Add support for this. Bug: https://gitlab.freedesktop.org/camera/libcamera/-/issues/290 Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> --- src/v4l2/v4l2_compat.cpp | 21 +++++++++++++++++++++ src/v4l2/v4l2_compat_manager.cpp | 10 ++++++++++ src/v4l2/v4l2_compat_manager.h | 2 ++ 3 files changed, 33 insertions(+)