]> granicus.if.org Git - strace/blobdiff - v4l2.c
tests: use fixed socket address in net-yy-unix.test
[strace] / v4l2.c
diff --git a/v4l2.c b/v4l2.c
index bbf94366870dd066697276d5fb49130ce9b0a116..637e8788a6b55fea133a9f95f5877bd572ddbb6b 100644 (file)
--- a/v4l2.c
+++ b/v4l2.c
 
 #include "defs.h"
 
+#include DEF_MPERS_TYPE(struct_v4l2_buffer)
+#include DEF_MPERS_TYPE(struct_v4l2_create_buffers)
+#include DEF_MPERS_TYPE(struct_v4l2_ext_control)
+#include DEF_MPERS_TYPE(struct_v4l2_ext_controls)
+#include DEF_MPERS_TYPE(struct_v4l2_format)
+#include DEF_MPERS_TYPE(struct_v4l2_framebuffer)
+#include DEF_MPERS_TYPE(struct_v4l2_input)
+#include DEF_MPERS_TYPE(struct_v4l2_standard)
+
 #include <stdint.h>
-#include <sys/ioctl.h>
+#include <linux/ioctl.h>
 #include <linux/types.h>
 #include <linux/videodev2.h>
 
+typedef struct v4l2_buffer struct_v4l2_buffer;
+typedef struct v4l2_create_buffers struct_v4l2_create_buffers;
+typedef struct v4l2_ext_control struct_v4l2_ext_control;
+typedef struct v4l2_ext_controls struct_v4l2_ext_controls;
+typedef struct v4l2_format struct_v4l2_format;
+typedef struct v4l2_framebuffer struct_v4l2_framebuffer;
+typedef struct v4l2_input struct_v4l2_input;
+typedef struct v4l2_standard struct_v4l2_standard;
+
+#include MPERS_DEFS
+
 /* some historical constants */
 #ifndef V4L2_CID_HCENTER
 #define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
@@ -57,7 +77,18 @@ print_pixelformat(uint32_t fourcc)
        const union {
                uint32_t pixelformat;
                unsigned char cc[sizeof(uint32_t)];
-       } u = { .pixelformat = htole32(fourcc) };
+       } u = {
+#if WORDS_BIGENDIAN
+               .cc = {
+                       (unsigned char) (fourcc >> 24),
+                       (unsigned char) (fourcc >> 16),
+                       (unsigned char) (fourcc >> 8),
+                       (unsigned char) fourcc
+               }
+#else
+               .pixelformat = fourcc
+#endif
+       };
        unsigned int i;
 
        tprints("v4l2_fourcc(");
@@ -102,7 +133,7 @@ print_pixelformat(uint32_t fourcc)
 #include "xlat/v4l2_device_capabilities_flags.h"
 
 static int
-print_v4l2_capability(struct tcb *tcp, const long arg)
+print_v4l2_capability(struct tcb *const tcp, const kernel_ulong_t arg)
 {
        struct v4l2_capability caps;
 
@@ -139,7 +170,7 @@ print_v4l2_capability(struct tcb *tcp, const long arg)
 #include "xlat/v4l2_format_description_flags.h"
 
 static int
-print_v4l2_fmtdesc(struct tcb *tcp, const long arg)
+print_v4l2_fmtdesc(struct tcb *const tcp, const kernel_ulong_t arg)
 {
        struct v4l2_fmtdesc f;
 
@@ -171,7 +202,7 @@ print_v4l2_fmtdesc(struct tcb *tcp, const long arg)
 #include "xlat/v4l2_colorspaces.h"
 
 static void
-print_v4l2_format_fmt(const char *prefix, const struct v4l2_format *f)
+print_v4l2_format_fmt(const char *prefix, const struct_v4l2_format *f)
 {
        switch (f->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -252,9 +283,10 @@ print_v4l2_format_fmt(const char *prefix, const struct v4l2_format *f)
 }
 
 static int
-print_v4l2_format(struct tcb *tcp, const long arg, const bool is_get)
+print_v4l2_format(struct tcb *const tcp, const kernel_ulong_t arg,
+                 const bool is_get)
 {
-       struct v4l2_format f;
+       struct_v4l2_format f;
 
        if (entering(tcp)) {
                tprints(", ");
@@ -278,7 +310,7 @@ print_v4l2_format(struct tcb *tcp, const long arg, const bool is_get)
 #include "xlat/v4l2_memories.h"
 
 static int
-print_v4l2_requestbuffers(struct tcb *tcp, const long arg)
+print_v4l2_requestbuffers(struct tcb *const tcp, const kernel_ulong_t arg)
 {
        struct v4l2_requestbuffers reqbufs;
 
@@ -306,9 +338,10 @@ print_v4l2_requestbuffers(struct tcb *tcp, const long arg)
 #include "xlat/v4l2_buf_flags.h"
 
 static int
-print_v4l2_buffer(struct tcb *tcp, const unsigned int code, const long arg)
+print_v4l2_buffer(struct tcb *const tcp, const unsigned int code,
+                 const kernel_ulong_t arg)
 {
-       struct v4l2_buffer b;
+       struct_v4l2_buffer b;
 
        if (entering(tcp)) {
                tprints(", ");
@@ -328,17 +361,17 @@ print_v4l2_buffer(struct tcb *tcp, const unsigned int code, const long arg)
                        if (b.memory == V4L2_MEMORY_MMAP) {
                                tprintf(", m.offset=%#x", b.m.offset);
                        } else if (b.memory == V4L2_MEMORY_USERPTR) {
-                               tprintf(", m.userptr=%#lx",
-                                       (unsigned long) b.m.userptr);
+                               tprints(", m.userptr=");
+                               printaddr(b.m.userptr);
                        }
 
                        tprintf(", length=%u, bytesused=%u, flags=",
                                b.length, b.bytesused);
                        printflags(v4l2_buf_flags, b.flags, "V4L2_BUF_FLAG_???");
-                       if (code == VIDIOC_DQBUF)
-                               tprintf(", timestamp = {%ju.%06ju}",
-                                       (uintmax_t)b.timestamp.tv_sec,
-                                       (uintmax_t)b.timestamp.tv_usec);
+                       if (code == VIDIOC_DQBUF) {
+                               tprints(", timestamp = ");
+                               MPERS_FUNC_NAME(print_struct_timeval)(&b.timestamp);
+                       }
                        tprints(", ...");
                }
                tprints("}");
@@ -347,21 +380,23 @@ print_v4l2_buffer(struct tcb *tcp, const unsigned int code, const long arg)
 }
 
 static int
-print_v4l2_framebuffer(struct tcb *tcp, const long arg)
+print_v4l2_framebuffer(struct tcb *const tcp, const kernel_ulong_t arg)
 {
-       struct v4l2_framebuffer b;
+       struct_v4l2_framebuffer b;
 
        tprints(", ");
        if (!umove_or_printaddr(tcp, arg, &b)) {
-               tprintf("{capability=%#x, flags=%#x, base=%#lx}",
-                       b.capability, b.flags, (unsigned long) b.base);
+               tprintf("{capability=%#x, flags=%#x, base=",
+                       b.capability, b.flags);
+               printaddr(ptr_to_kulong(b.base));
+               tprints("}");
        }
 
        return RVAL_DECODED | 1;
 }
 
 static int
-print_v4l2_buf_type(struct tcb *tcp, const long arg)
+print_v4l2_buf_type(struct tcb *const tcp, const kernel_ulong_t arg)
 {
        int type;
 
@@ -378,7 +413,8 @@ print_v4l2_buf_type(struct tcb *tcp, const long arg)
 #include "xlat/v4l2_capture_modes.h"
 
 static int
-print_v4l2_streamparm(struct tcb *tcp, const long arg, const bool is_get)
+print_v4l2_streamparm(struct tcb *const tcp, const kernel_ulong_t arg,
+                     const bool is_get)
 {
        struct v4l2_streamparm s;
 
@@ -442,9 +478,9 @@ print_v4l2_streamparm(struct tcb *tcp, const long arg, const bool is_get)
 }
 
 static int
-print_v4l2_standard(struct tcb *tcp, const long arg)
+print_v4l2_standard(struct tcb *const tcp, const kernel_ulong_t arg)
 {
-       struct v4l2_standard s;
+       struct_v4l2_standard s;
 
        if (entering(tcp)) {
                tprints(", ");
@@ -469,9 +505,9 @@ print_v4l2_standard(struct tcb *tcp, const long arg)
 #include "xlat/v4l2_input_types.h"
 
 static int
-print_v4l2_input(struct tcb *tcp, const long arg)
+print_v4l2_input(struct tcb *const tcp, const kernel_ulong_t arg)
 {
-       struct v4l2_input i;
+       struct_v4l2_input i;
 
        if (entering(tcp)) {
                tprints(", ");
@@ -496,7 +532,8 @@ print_v4l2_input(struct tcb *tcp, const long arg)
 #include "xlat/v4l2_control_ids.h"
 
 static int
-print_v4l2_control(struct tcb *tcp, const long arg, const bool is_get)
+print_v4l2_control(struct tcb *const tcp, const kernel_ulong_t arg,
+                  const bool is_get)
 {
        struct v4l2_control c;
 
@@ -524,7 +561,7 @@ print_v4l2_control(struct tcb *tcp, const long arg, const bool is_get)
 #include "xlat/v4l2_control_flags.h"
 
 static int
-print_v4l2_queryctrl(struct tcb *tcp, const long arg)
+print_v4l2_queryctrl(struct tcb *const tcp, const kernel_ulong_t arg)
 {
        struct v4l2_queryctrl c;
 
@@ -538,14 +575,15 @@ print_v4l2_queryctrl(struct tcb *tcp, const long arg)
                        tprints("}");
                        return 1;
                }
-               if (tcp->auxstr)
+               if (get_tcb_priv_ulong(tcp))
                        tprints(" => ");
        }
 
-       if (entering(tcp) || tcp->auxstr) {
+       if (entering(tcp) || get_tcb_priv_ulong(tcp)) {
 #ifdef V4L2_CTRL_FLAG_NEXT_CTRL
-               tcp->auxstr = (c.id & V4L2_CTRL_FLAG_NEXT_CTRL) ? "" : NULL;
-               if (tcp->auxstr) {
+               const unsigned long next = c.id & V4L2_CTRL_FLAG_NEXT_CTRL;
+               set_tcb_priv_ulong(tcp, next);
+               if (next) {
                        tprints("V4L2_CTRL_FLAG_NEXT_CTRL|");
                        c.id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
                }
@@ -570,7 +608,7 @@ print_v4l2_queryctrl(struct tcb *tcp, const long arg)
 }
 
 static int
-print_v4l2_cropcap(struct tcb *tcp, const long arg)
+print_v4l2_cropcap(struct tcb *const tcp, const kernel_ulong_t arg)
 {
        struct v4l2_cropcap c;
 
@@ -595,7 +633,8 @@ print_v4l2_cropcap(struct tcb *tcp, const long arg)
 }
 
 static int
-print_v4l2_crop(struct tcb *tcp, const long arg, const bool is_get)
+print_v4l2_crop(struct tcb *const tcp, const kernel_ulong_t arg,
+               const bool is_get)
 {
        struct v4l2_crop c;
 
@@ -618,66 +657,33 @@ print_v4l2_crop(struct tcb *tcp, const long arg, const bool is_get)
 }
 
 #ifdef VIDIOC_S_EXT_CTRLS
-static int
-print_v4l2_ext_control_array(struct tcb *tcp, const unsigned long addr,
-                            const unsigned count)
+static bool
+print_v4l2_ext_control(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
 {
-       struct v4l2_ext_control ctrl;
-       const unsigned long size = count * sizeof(ctrl);
-       const unsigned long end = addr + size;
-       int rc = 0;
-
-       if (!addr || end <= addr || size / sizeof(ctrl) != count) {
-               printaddr(addr);
-               return -1;
-       }
-       const unsigned long abbrev_end =
-               (abbrev(tcp) && max_strlen < count) ?
-                       addr + max_strlen * sizeof(ctrl) : end;
-       unsigned long cur;
-       for (cur = addr; cur < end; cur += sizeof(ctrl)) {
-               if (cur != addr)
-                       tprints(", ");
-
-               if (umove(tcp, cur, &ctrl)) {
-                       printaddr(cur);
-                       rc = -1;
-                       break;
-               }
-
-               if (cur == addr)
-                       tprints("[");
-
-               if (cur >= abbrev_end) {
-                       tprints("...");
-                       cur = end;
-                       break;
-               }
+       const struct_v4l2_ext_control *p = elem_buf;
 
-               tprints("{id=");
-               printxval(v4l2_control_ids, ctrl.id, "V4L2_CID_???");
+       tprints("{id=");
+       printxval(v4l2_control_ids, p->id, "V4L2_CID_???");
 # if HAVE_DECL_V4L2_CTRL_TYPE_STRING
-               tprintf(", size=%u", ctrl.size);
-               if (ctrl.size > 0) {
-                       tprints(", string=");
-                       printstr(tcp, (long) ctrl.string, ctrl.size);
-               } else
+       tprintf(", size=%u", p->size);
+       if (p->size > 0) {
+               tprints(", string=");
+               printstrn(tcp, ptr_to_kulong(p->string), p->size);
+       } else
 # endif
-               tprintf(", value=%d, value64=%lld", ctrl.value,
-                       (long long) ctrl.value64);
-               tprints("}");
-       }
-       if (cur != addr)
-               tprints("]");
-       return rc;
+       tprintf(", value=%d, value64=%" PRId64, p->value, (int64_t) p->value64);
+       tprints("}");
+
+       return true;
 }
 
 #include "xlat/v4l2_control_classes.h"
 
 static int
-print_v4l2_ext_controls(struct tcb *tcp, const long arg, const bool is_get)
+print_v4l2_ext_controls(struct tcb *const tcp, const kernel_ulong_t arg,
+                       const bool is_get)
 {
-       struct v4l2_ext_controls c;
+       struct_v4l2_ext_controls c;
 
        if (entering(tcp)) {
                tprints(", ");
@@ -703,9 +709,11 @@ print_v4l2_ext_controls(struct tcb *tcp, const long arg, const bool is_get)
        }
 
        tprints("controls=");
-       int fail = print_v4l2_ext_control_array(tcp,
-                                               (unsigned long) c.controls,
-                                               c.count);
+       struct_v4l2_ext_control ctrl;
+       bool fail = !print_array(tcp, ptr_to_kulong(c.controls), c.count,
+                                &ctrl, sizeof(ctrl),
+                                umoven_or_printaddr_ignore_syserror,
+                                print_v4l2_ext_control, 0);
 
        if (exiting(tcp) && syserror(tcp))
                tprintf(", error_idx=%u", c.error_idx);
@@ -722,7 +730,7 @@ print_v4l2_ext_controls(struct tcb *tcp, const long arg, const bool is_get)
 # include "xlat/v4l2_framesize_types.h"
 
 static int
-print_v4l2_frmsizeenum(struct tcb *tcp, const long arg)
+print_v4l2_frmsizeenum(struct tcb *const tcp, const kernel_ulong_t arg)
 {
        struct v4l2_frmsizeenum s;
 
@@ -762,7 +770,7 @@ print_v4l2_frmsizeenum(struct tcb *tcp, const long arg)
 # include "xlat/v4l2_frameinterval_types.h"
 
 static int
-print_v4l2_frmivalenum(struct tcb *tcp, const long arg)
+print_v4l2_frmivalenum(struct tcb *const tcp, const kernel_ulong_t arg)
 {
        struct v4l2_frmivalenum f;
 
@@ -801,9 +809,9 @@ print_v4l2_frmivalenum(struct tcb *tcp, const long arg)
 
 #ifdef VIDIOC_CREATE_BUFS
 static int
-print_v4l2_create_buffers(struct tcb *tcp, const long arg)
+print_v4l2_create_buffers(struct tcb *const tcp, const kernel_ulong_t arg)
 {
-       struct v4l2_create_buffers b;
+       struct_v4l2_create_buffers b;
 
        if (entering(tcp)) {
                tprints(", ");
@@ -815,7 +823,7 @@ print_v4l2_create_buffers(struct tcb *tcp, const long arg)
                printxval(v4l2_buf_types, b.format.type,
                          "V4L2_BUF_TYPE_???");
                print_v4l2_format_fmt(", ",
-                                     (struct v4l2_format *) &b.format);
+                                     (struct_v4l2_format *) &b.format);
                tprints("}}");
                return 0;
        } else {
@@ -831,8 +839,8 @@ print_v4l2_create_buffers(struct tcb *tcp, const long arg)
 }
 #endif /* VIDIOC_CREATE_BUFS */
 
-int
-v4l2_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
+MPERS_PRINTER_DECL(int, v4l2_ioctl, struct tcb *const tcp,
+                  const unsigned int code, const kernel_ulong_t arg)
 {
        if (!verbose(tcp))
                return RVAL_DECODED;