[v2,1/2] v4l2: v4l2_compat: Handle __ioctl_time64
diff mbox series

Message ID 20261023041954.913108-1-ragaprasanth@gmail.com
State New
Headers show
Series
  • [v2,1/2] v4l2: v4l2_compat: Handle __ioctl_time64
Related show

Commit Message

Prasanth Ramesh Oct. 23, 2026, 4:19 a.m. UTC
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
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(+)

Patch
diff mbox series

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();