From 88409854cc8c0657d23223a3c7508b538ae758c6 Mon Sep 17 00:00:00 2001
From: Rahix <rahix@rahix.de>
Date: Mon, 12 Aug 2019 14:45:26 +0200
Subject: [PATCH] feat(pycardium): Add a barebones "os" module

Signed-off-by: Rahix <rahix@rahix.de>
---
 pycardium/meson.build        |  1 +
 pycardium/modules/os.c       | 65 ++++++++++++++++++++++++++++++++++++
 pycardium/modules/qstrdefs.h |  4 +++
 pycardium/mpconfigport.h     |  1 +
 4 files changed, 71 insertions(+)
 create mode 100644 pycardium/modules/os.c

diff --git a/pycardium/meson.build b/pycardium/meson.build
index 8dafd3e0..b43d0fc5 100644
--- a/pycardium/meson.build
+++ b/pycardium/meson.build
@@ -6,6 +6,7 @@ modsrc = files(
   'modules/interrupt.c',
   'modules/sys_leds.c',
   'modules/light_sensor.c',
+  'modules/os.c',
   'modules/sys_display.c',
   'modules/utime.c',
   'modules/vibra.c',
diff --git a/pycardium/modules/os.c b/pycardium/modules/os.c
new file mode 100644
index 00000000..3f84c26e
--- /dev/null
+++ b/pycardium/modules/os.c
@@ -0,0 +1,65 @@
+#include "epicardium.h"
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include <string.h>
+
+static mp_obj_t mp_os_exit(size_t n_args, const mp_obj_t *args)
+{
+	int ret = 0;
+	if (n_args == 1) {
+		ret = mp_obj_get_int(args[0]);
+	}
+
+	epic_exit(ret);
+
+	/* unreachable */
+	return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(exit_obj, 0, 1, mp_os_exit);
+
+static mp_obj_t mp_os_exec(mp_obj_t name_in)
+{
+	const char *name_ptr;
+	char name_str[256];
+	size_t len, maxlen;
+
+	name_ptr = mp_obj_str_get_data(name_in, &len);
+
+	/*
+	 * The string retrieved from MicroPython is not NULL-terminated so we
+	 * first need to copy it and add a NULL-byte.
+	 */
+	maxlen = len < (sizeof(name_str) - 1) ? len : (sizeof(name_str) - 1);
+	memcpy(name_str, name_ptr, maxlen);
+	name_str[maxlen] = '\0';
+
+	int ret = epic_exec(name_str);
+
+	/*
+	 * If epic_exec() returns, something went wrong.  We can raise an
+	 * exception in all cases.
+	 */
+	mp_raise_OSError(-ret);
+
+	/* unreachable */
+	return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_1(exec_obj, mp_os_exec);
+
+static const mp_rom_map_elem_t os_module_gobals_table[] = {
+	{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) },
+	{ MP_ROM_QSTR(MP_QSTR_exit), MP_ROM_PTR(&exit_obj) },
+	{ MP_ROM_QSTR(MP_QSTR_exec), MP_ROM_PTR(&exec_obj) },
+};
+static MP_DEFINE_CONST_DICT(os_module_globals, os_module_gobals_table);
+
+const mp_obj_module_t os_module = {
+	.base    = { &mp_type_module },
+	.globals = (mp_obj_dict_t *)&os_module_globals,
+};
+
+/* This is a special macro that will make MicroPython aware of this module */
+/* clang-format off */
+MP_REGISTER_MODULE(MP_QSTR_os, os_module, MODULE_OS_ENABLED);
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index 1c399060..f25307d5 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -85,3 +85,7 @@ Q(tell)
 Q(TextIOWrapper)
 Q(write)
 
+/* os */
+Q(os)
+Q(exit)
+Q(exec)
diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h
index 38934682..5e4d09e9 100644
--- a/pycardium/mpconfigport.h
+++ b/pycardium/mpconfigport.h
@@ -43,6 +43,7 @@
 #define MODULE_INTERRUPT_ENABLED            (1)
 #define MODULE_LEDS_ENABLED                 (1)
 #define MODULE_LIGHT_SENSOR_ENABLED         (1)
+#define MODULE_OS_ENABLED                   (1)
 #define MODULE_UTIME_ENABLED                (1)
 #define MODULE_VIBRA_ENABLED                (1)
 
-- 
GitLab