| Message ID | 20261023041954.913108-1-ragaprasanth@gmail.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
On Fri, Oct 23, 2026 at 01:19:53PM +0900, Prasanth R wrote: > From: Paul Elder <paul.elder@ideasonboard.com> > > 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. > > Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/290 I think we need patch 2/2 to close the issue. Let's move the tag to the next patch, and update the commit message to indicate this isn't a full solution. On 32-bit systems with 64-bit time_t (except x32), ioctl is redirected to __ioctl_time64. The v4l2-compat layer only intercepts the former, we need to intercept and handle the latter as well. In order to correctly support those systems, translation between 32-bit and 64-bit ioctl structures also need to be implemented. This will be done in a subsequent patch. > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > Tested-by: Prasanth R <ragaprasanth@gmail.com> > Signed-off-by: Prasanth R <ragaprasanth@gmail.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 ff833f57..10421cef 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. Extraneous space before __USE_TIME64_REDIRECTS. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > + */ > +#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 b07f865f..65cce7e1 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"); > } > @@ -243,3 +244,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 13673d60..1093505a 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();
diff --git a/src/v4l2/v4l2_compat.cpp b/src/v4l2/v4l2_compat.cpp index ff833f57..10421cef 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 b07f865f..65cce7e1 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"); } @@ -243,3 +244,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 13673d60..1093505a 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();