summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-08-22 12:59:30 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2018-08-22 13:44:40 +0100
commita27d7e7d3a3e790d7325f69e4ac40a2a3922b5d2 (patch)
treeee208fb2a17b22395b8121994a6452cf2299ceeb
parenta745d0cb810146352f02edd463ec338e75605f89 (diff)
igt/shell: Wrap ioctls on our fd
-rw-r--r--shell/lib/os-file.cc83
1 files changed, 83 insertions, 0 deletions
diff --git a/shell/lib/os-file.cc b/shell/lib/os-file.cc
index c10f02df..1f2b6450 100644
--- a/shell/lib/os-file.cc
+++ b/shell/lib/os-file.cc
@@ -1,5 +1,6 @@
#include <errno.h>
#include <fcntl.h>
+#include <sys/ioctl.h>
#include <unistd.h>
#include "igt-shell.h"
@@ -73,6 +74,77 @@ static void os_close(const FunctionCallbackInfo<Value>& args)
}
}
+static void os_ioctl(const FunctionCallbackInfo<Value>& args)
+{
+ auto iso = args.GetIsolate();
+ HandleScope scope(iso);
+
+ Local<Value> v_fd, v_cmd, v_arg = Null(iso);
+
+ if (args.Length() == 1) {
+ Local<Object> obj = args[0]->ToObject();
+ v_fd = obj->Get(AsString(iso, "fd").ToLocalChecked());
+ v_cmd = obj->Get(AsString(iso, "cmd").ToLocalChecked());
+ if (obj->Has(AsString(iso, "arg").ToLocalChecked()))
+ v_arg = obj->Get(AsString(iso, "arg").ToLocalChecked());
+ } else if (args.Length() < 3) {
+ v_fd = args[0];
+ v_cmd = args[1];
+ if (args.Length() > 2)
+ v_arg = args[2];
+ } else{
+ iso->ThrowException(Exception::SyntaxError(AsString(iso, "bad args").ToLocalChecked()));
+ return ;
+ }
+
+ int fd = v_fd->Int32Value();
+ unsigned long cmd = v_cmd->Uint32Value();
+ void *ptr = NULL;
+ if (v_arg->IsArrayBuffer()) {
+ Local<ArrayBuffer> buf = Local<ArrayBuffer>::Cast(v_arg->ToObject());
+ ptr = buf->GetContents().Data();
+ } else if (v_arg->IsTypedArray()) {
+ Local<TypedArray> t = Local<TypedArray>::Cast(v_arg->ToObject());
+ ptr = t->Buffer()->GetContents().Data();
+ } else if (!v_arg->IsNull()) {
+ iso->ThrowException(Exception::TypeError(AsString(iso, "bad arg[2], expecting an ArrayBuffer or a TypedArray").ToLocalChecked()));
+ return;
+ }
+
+ long ret = ioctl(fd, cmd, ptr);
+ if (ret == -1) {
+ os_throw_errno(iso, errno);
+ return;
+ }
+
+ args.GetReturnValue().Set(static_cast<int32_t>(ret));
+}
+
+static void os_ioctl_size(const FunctionCallbackInfo<Value>& args)
+{
+ unsigned long cmd = args[1]->Uint32Value();
+ args.GetReturnValue().Set(static_cast<uint32_t>(_IOC_SIZE(cmd)));
+}
+
+static void os_ioctl_nr(const FunctionCallbackInfo<Value>& args)
+{
+ unsigned long cmd = args[1]->Uint32Value();
+ args.GetReturnValue().Set(static_cast<uint32_t>(_IOC_NR(cmd)));
+}
+
+static void os_ioctl_type(const FunctionCallbackInfo<Value>& args)
+{
+ unsigned long cmd = args[1]->Uint32Value();
+ args.GetReturnValue().Set(static_cast<uint32_t>(_IOC_TYPE(cmd)));
+}
+
+static void os_ioctl_dir(const FunctionCallbackInfo<Value>& args)
+{
+ unsigned long cmd = args[1]->Uint32Value();
+ args.GetReturnValue().Set(static_cast<uint32_t>(_IOC_DIR(cmd)));
+}
+
+
void os_file_ctor(Isolate *iso, Handle<ObjectTemplate> os)
{
HandleScope handle_scope(iso);
@@ -85,4 +157,15 @@ void os_file_ctor(Isolate *iso, Handle<ObjectTemplate> os)
{}
};
v8_helper_funcs(iso, os, funcs);
+
+ auto ioctl_tmpl = FunctionTemplate::New(iso, os_ioctl);
+ static const struct v8_helper_fn ioctl_funcs[] = {
+ { "size", os_ioctl_size },
+ { "nr", os_ioctl_nr },
+ { "type", os_ioctl_type },
+ { "dir", os_ioctl_dir },
+ {}
+ };
+ v8_helper_funcs(iso, ioctl_tmpl, ioctl_funcs);
+ os->Set(AsString(iso, "ioctl").ToLocalChecked(), ioctl_tmpl);
}