diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2018-08-20 13:45:05 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2018-08-20 14:21:41 +0100 |
commit | 68e271f35ce71c68e991066754505a29d1f39c5b (patch) | |
tree | ceddf5e81d305a819a14d546ca65b2d4ad97bf93 | |
parent | 50eab8acad0c0d961159b3096e163ceb7b1fb83f (diff) |
igt/shell: Simple OS interface
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | shell/include/os-builtin.h | 7 | ||||
-rw-r--r-- | shell/lib/ioctl.c | 91 | ||||
-rw-r--r-- | shell/lib/os.c | 120 | ||||
-rw-r--r-- | shell/meson.build | 2 |
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') ) |