diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2018-08-22 12:59:30 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2018-08-22 13:44:40 +0100 |
commit | a27d7e7d3a3e790d7325f69e4ac40a2a3922b5d2 (patch) | |
tree | ee208fb2a17b22395b8121994a6452cf2299ceeb | |
parent | a745d0cb810146352f02edd463ec338e75605f89 (diff) |
igt/shell: Wrap ioctls on our fd
-rw-r--r-- | shell/lib/os-file.cc | 83 |
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); } |