[igt-dev] [PATCH i-g-t 3/6] igt/shell: Simple OS interface

Chris Wilson chris at chris-wilson.co.uk
Mon Aug 20 13:01:46 UTC 2018


Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 shell/include/os-builtin.h |   7 +++
 shell/lib/ioctl.c          |  91 ++++++++++++++++++++++++++++
 shell/lib/os.c             | 120 +++++++++++++++++++++++++++++++++++++
 shell/meson.build          |   2 +
 4 files changed, 220 insertions(+)
 create mode 100644 shell/include/os-builtin.h
 create mode 100644 shell/lib/ioctl.c
 create mode 100644 shell/lib/os.c

diff --git a/shell/include/os-builtin.h b/shell/include/os-builtin.h
new file mode 100644
index 000000000..78111bb61
--- /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 000000000..6739c9de0
--- /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 000000000..f3b07e961
--- /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 53b0754e9..b2450b162 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')
 )
-- 
2.18.0



More information about the igt-dev mailing list