summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-08-20 13:45:05 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2018-08-20 14:21:41 +0100
commit68e271f35ce71c68e991066754505a29d1f39c5b (patch)
treeceddf5e81d305a819a14d546ca65b2d4ad97bf93
parent50eab8acad0c0d961159b3096e163ceb7b1fb83f (diff)
igt/shell: Simple OS interface
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--shell/include/os-builtin.h7
-rw-r--r--shell/lib/ioctl.c91
-rw-r--r--shell/lib/os.c120
-rw-r--r--shell/meson.build2
4 files changed, 220 insertions, 0 deletions
diff --git a/shell/include/os-builtin.h b/shell/include/os-builtin.h
new file mode 100644
index 00000000..78111bb6
--- /dev/null
+++ b/shell/include/os-builtin.h
@@ -0,0 +1,7 @@
+#ifndef OS_BUILTIN_H
+#define OS_H
+
+__attribute((noreturn))
+void os_throw_errno(duk_context *ctx, int err);
+
+#endif /* OS_BUILTIN_H */
diff --git a/shell/lib/ioctl.c b/shell/lib/ioctl.c
new file mode 100644
index 00000000..6739c9de
--- /dev/null
+++ b/shell/lib/ioctl.c
@@ -0,0 +1,91 @@
+#include <sys/ioctl.h>
+
+#include "duktape.h"
+#include "igt-builtins.h"
+
+static duk_ret_t ioctl_ioctl(duk_context *ctx)
+{
+ duk_size_t sz;
+ unsigned long cmd;
+ int fd;
+ void *ptr;
+
+ fd = duk_get_int(ctx, -3);
+ cmd = duk_get_uint(ctx, -2);
+ ptr = duk_get_buffer_data(ctx, -1, &sz);
+
+ duk_push_int(ctx, ioctl(fd, cmd, ptr));
+ return 1;
+}
+
+static duk_ret_t ioctl_nr(duk_context *ctx)
+{
+ duk_push_uint(ctx, _IOC_NR(duk_require_uint(ctx, -1)));
+ return 1;
+}
+
+static duk_ret_t ioctl_type(duk_context *ctx)
+{
+ duk_push_uint(ctx, _IOC_TYPE(duk_require_uint(ctx, -1)));
+ return 1;
+}
+
+static duk_ret_t ioctl_dir(duk_context *ctx)
+{
+ duk_push_uint(ctx, _IOC_DIR(duk_require_uint(ctx, -1)));
+ return 1;
+}
+
+static duk_ret_t ioctl_size(duk_context *ctx)
+{
+ duk_push_uint(ctx, _IOC_SIZE(duk_require_uint(ctx, -1)));
+ return 1;
+}
+
+static duk_ret_t ioctl_pointer(duk_context *ctx)
+{
+ unsigned long offset = duk_get_uint(ctx, -2);
+ duk_size_t sz;
+ void *user;
+ void *ptr;
+
+ user = duk_get_buffer_data(ctx, -1, &sz);
+ ptr = duk_get_buffer_data(ctx, -3, &sz);
+ if (!ptr)
+ return -1;
+
+ memcpy(ptr + offset, &user, sizeof(void *));
+
+ return 0;
+}
+
+static const duk_function_list_entry funcs[] = {
+ { "ioctl", ioctl_ioctl, 3 },
+
+ { "nr", ioctl_nr, 1 },
+ { "type", ioctl_type, 1 },
+ { "dir", ioctl_dir, 1 },
+ { "size", ioctl_size, 1 },
+
+ { "user_pointer", ioctl_pointer, 3 },
+
+ {}
+};
+
+static duk_ret_t ioctl_builtin_ctor(duk_context *ctx)
+{
+ duk_push_object(ctx);
+ duk_put_function_list(ctx, -1, funcs);
+
+ return 1;
+}
+
+__attribute__((constructor))
+static void __ioctl_register_builtin__(void)
+{
+ static struct igt_builtin builtin = {
+ .name = "ioctl",
+ .ctor = ioctl_builtin_ctor
+ };
+ igt_register_builtin(&builtin);
+}
diff --git a/shell/lib/os.c b/shell/lib/os.c
new file mode 100644
index 00000000..277e41d3
--- /dev/null
+++ b/shell/lib/os.c
@@ -0,0 +1,120 @@
+#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include "duktape.h"
+#include "igt-builtins.h"
+#include "os-builtin.h"
+
+static duk_ret_t os_uid(duk_context *ctx)
+{
+ duk_push_int(ctx, getuid());
+ return 1;
+}
+
+static duk_ret_t os_drop_root(duk_context *ctx)
+{
+ struct passwd *pw;
+ struct group *grp;
+ /* Arbitrary default values for nobody:video */
+ uid_t uid = 65534;
+ gid_t gid = 44;
+
+ if (getuid())
+ return 0; /* already a user */
+
+ pw = getpwnam("nobody");
+ if (pw)
+ uid = pw->pw_uid, gid = pw->pw_gid;
+
+ grp = getgrnam("video");
+ if (grp)
+ gid = grp->gr_gid;
+
+ if (setgid(gid) || setuid(uid))
+ os_throw_errno(ctx, errno);
+
+ return 0;
+}
+
+static const duk_function_list_entry funcs[] = {
+ { "uid", os_uid, 0 },
+ { "drop_root", os_drop_root, 0 },
+
+ {}
+};
+
+static const duk_number_list_entry errnos[] = {
+#define C(x) { #x, x }
+ C(EPERM),
+ C(ENOENT),
+ C(ESRCH),
+ C(EINTR),
+ C(EIO),
+ C(ENXIO),
+ C(E2BIG),
+ C(ENOEXEC),
+ C(EBADF),
+ C(ECHILD),
+ C(EAGAIN),
+ C(ENOMEM),
+ C(EACCES),
+ C(EFAULT),
+ C(ENOTBLK),
+ C(EBUSY),
+ C(EEXIST),
+ C(EXDEV),
+ C(ENODEV),
+ C(ENOTDIR),
+ C(EISDIR),
+ C(EINVAL),
+ C(ENFILE),
+ C(EMFILE),
+ C(ENOTTY),
+ C(ETXTBSY),
+ C(EFBIG),
+ C(ENOSPC),
+ C(ESPIPE),
+ C(EROFS),
+ C(EMLINK),
+ C(EPIPE),
+ C(EDOM),
+ C(ERANGE),
+#undef C
+
+ { },
+};
+
+static duk_ret_t os_builtin_ctor(duk_context *ctx)
+{
+ duk_push_object(ctx);
+ duk_dup_top(ctx);
+ duk_put_global_string(ctx, "os");
+
+ duk_put_function_list(ctx, -1, funcs);
+ duk_put_number_list(ctx, -1, errnos);
+ duk_pop(ctx);
+
+ return 0;
+}
+
+__attribute__((constructor))
+static void __os_register_builtin__(void)
+{
+ static struct igt_builtin builtin = {
+ .name = "os",
+ .ctor = os_builtin_ctor
+ };
+ igt_register_global(&builtin);
+}
+
+__attribute((noreturn))
+void os_throw_errno(duk_context *ctx, int err)
+{
+ duk_push_error_object(ctx, DUK_ERR_ERROR,
+ "%d (%s)", err, strerror(err));
+ duk_push_int(ctx, err);
+ duk_put_prop_string(ctx, -2, "errno");
+ duk_throw_raw(ctx);
+}
diff --git a/shell/meson.build b/shell/meson.build
index 53b0754e..b2450b16 100644
--- a/shell/meson.build
+++ b/shell/meson.build
@@ -3,6 +3,8 @@ executable('igt', [
'igt-builtins.c',
'igt-math.c',
'igt-shell.c',
+ 'lib/ioctl.c',
+ 'lib/os.c',
], dependencies : [ math, libkmod ],
include_directories : include_directories('include', '../include')
)