Procházet zdrojové kódy

add os module

fix color for GC DUMP

add os module and test

support ESP32
pikastech před 3 roky
rodič
revize
a3b402ae36

+ 24 - 0
examples/os/os_test1.py

@@ -0,0 +1,24 @@
+import os
+origin = os.getcwd()
+os.chdir("test/out")
+os.getcwd()
+
+try:
+    # cleanup
+    os.remove("_testdir/testfile")
+    os.rmdir("_testdir")
+except:
+    pass
+
+os.mkdir("_testdir")
+os.chdir("_testdir")
+
+
+f = os.open("testfile", os.O_CREAT | os.O_RDWR)
+assert os.write(f, b"Hello World!") == 12
+assert os.lseek(f, 0, 0) == 0
+print(os.read(f, 100))
+os.close(f)
+os.chdir("..")
+os.chdir(origin)
+print("PASS")

+ 105 - 0
package/os/os.c

@@ -0,0 +1,105 @@
+#include "os.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "PikaObj.h"
+#include "PikaStdData_List.h"
+#include "TinyObj.h"
+#include "os_fileStat.h"
+#include "os_platform.h"
+
+void os___init__(PikaObj* self) {
+    // obj_newDirectObj(self,"os",New_TinyObj);
+
+    obj_setInt(self, "O_RDONLY", FILE_RDONLY);
+    obj_setInt(self, "O_WRONLY", FILE_WRONLY);
+    obj_setInt(self, "O_RDWR", FILE_RDWR);
+    obj_setInt(self, "O_APPEND", FILE_APPEND);
+    obj_setInt(self, "O_CREAT", FILE_CREAT);
+}
+//#undef _WIN32
+
+int os_fileStat_st_size(PikaObj* self) {
+    int size = obj_getInt(self, "st_size");
+    return size;
+}
+
+PikaObj* os_fstat(PikaObj* self, PikaObj* fd) {
+    int size = 0;
+    size = os_getFileSize(fd);
+
+    PikaObj* stat_obj = newNormalObj(New_os_fileStat);
+
+    obj_setInt(stat_obj, "st_size", size);
+    return stat_obj;
+}
+
+PikaObj* os_open(PikaObj* self, char* filename, int flags) {
+    return os_open_platform(filename, flags);
+}
+
+char* os_read(PikaObj* self, PikaObj* fd, int len) {
+    return os_read_platform(self, fd, len);
+}
+
+int os_write(PikaObj* self, PikaObj* fd, Arg* buf) {
+    if (arg_getType(buf) != ARG_TYPE_BYTES) {
+        obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
+        pika_platform_printf(
+            "TypeError: a bytes-like object is required, not 'str'\r\n");
+        return -1;
+    }
+    return os_write_platform(arg_getBytes(buf), arg_getBytesSize(buf), fd);
+}
+
+int os_lseek(PikaObj* self, PikaObj* fd, int how, int pos) {
+    return os_lseek_platform(fd, how, pos);
+}
+
+void os_close(PikaObj* self, PikaObj* fd) {
+    if (os_close_platform(fd) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("close file error\r\n");
+    }
+}
+
+char* os_getcwd(PikaObj* self) {
+    return os_getcwd_platform(self);
+}
+
+PikaObj* os_listdir(PikaObj* self, char* path) {
+    return os_listdir_platform(path);
+}
+
+void os_mkdir(PikaObj* self, char* path, PikaTuple* mode) {
+    int iMode = 0;
+    if (pikaTuple_getSize(mode) == 0) {
+        iMode = 0777;
+    } else {
+        iMode = pikaTuple_getInt(mode, 0);
+    }
+    if (os_mkdir_platform(iMode, path) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("mkdir error\r\n");
+    }
+}
+
+void os_chdir(PikaObj* self, char* path) {
+    if (os_chdir_platform(path) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("chdir error\r\n");
+    }
+}
+
+void os_rmdir(PikaObj* self, char* path) {
+    if (os_rmdir_platform(path) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("rmdir error\r\n");
+    }
+}
+
+void os_remove(PikaObj* self, char* filename) {
+    if (os_remove_platform(filename) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("remove error\r\n");
+    }
+}

+ 62 - 0
package/os/os.pyi

@@ -0,0 +1,62 @@
+O_RDONLY: int
+O_WRONLY: int
+O_RDWR: int
+O_APPEND: int
+O_CREAT: int
+
+
+class fileStat:
+    def st_size(self) -> int:
+        pass
+
+
+def __init__(self):
+    pass
+
+
+def mkdir(self, path: str, *mode):
+    pass
+
+
+def rmdir(self, path: str):
+    pass
+
+
+def chdir(self, path: str):
+    pass
+
+
+def listdir(self, path: str) -> list:
+    pass
+
+
+def getcwd(self) -> str:
+    pass
+
+
+def open(self, filename: str, flags: int) -> FILE:
+    pass
+
+
+def read(self, fd: FILE, len: int) -> str:
+    pass
+
+
+def write(self, fd: FILE, buf: any) -> int:
+    pass
+
+
+def lseek(self, fd: FILE, pos: int, how: int) -> int:
+    pass
+
+
+def close(self, fd: FILE):
+    pass
+
+
+def fstat(self, fd: FILE) -> fileStat:
+    pass
+
+
+def remove(self, filename: str):
+    pass

+ 206 - 0
package/os/os_platform.c

@@ -0,0 +1,206 @@
+#include "os_platform.h"
+
+int os_getFileSize(PikaObj* fd) {
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        int ret = fseek(fp, 0, SEEK_END);
+        if (ret == 0) {
+            ret = ftell(fp);
+            return ret;
+        }
+    }
+    return -2;
+}
+
+PikaObj* os_open_platform(char* filename, int flags) {
+    char file_flag[4] = {0};
+    int index = 0;
+    char dirpath[256] = {0};
+    memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
+
+    if (FILE_RDONLY == (flags & FILE_RDONLY)) {
+        file_flag[0] = 'r';
+        if (FILE_CREAT == (flags & FILE_CREAT)) {
+            file_flag[1] = 'w';
+        }
+    }
+
+    if (FILE_RDWR == (flags & FILE_RDWR)) {
+        memcpy(file_flag, "r+", 2);
+        if (FILE_CREAT == (flags & FILE_CREAT)) {
+            memcpy(file_flag, "w+", 2);
+        }
+    }
+
+    if (FILE_WRONLY == (flags & FILE_WRONLY))
+        file_flag[index] = 'w';
+
+    if (FILE_APPEND == (flags & FILE_APPEND))
+        memcpy(file_flag, "a+", 2);
+
+    FILE* fp = fopen(dirpath, file_flag);
+    if (fp != NULL) {
+        PikaObj* file_obj = newNormalObj(New_TinyObj);
+        obj_setPtr(file_obj, "fd", fp);
+        return file_obj;
+    } else {
+        return NULL;
+    }
+}
+
+char* os_read_platform(PikaObj* self, PikaObj* fd, int len) {
+    char* buf = NULL;
+    int size = 0;
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        buf = malloc(len);
+        memset(buf, 0x00, len);
+        size = fread(buf, 1, len, fp);
+
+        if (size > 0) {
+            //转换成
+            obj_setStr(self, "os_file_read", buf);
+            free(buf);
+            return obj_getStr(self, "os_file_read");
+        }
+    }
+
+    return "";
+}
+
+int os_write_platform(uint8_t* buf, size_t len, PikaObj* fd) {
+    int size = 0;
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        size = fwrite(buf, 1, len, fp);
+        return size;
+    }
+    return 0;
+}
+
+int os_lseek_platform(PikaObj* fd, int how, int pos) {
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        int ret = fseek(fp, pos, how);
+        return ret;
+
+    } else
+        return -2;
+}
+
+int os_close_platform(PikaObj* fd) {
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        int ret = fclose(fp);
+        return ret;
+
+    } else
+        return -2;
+}
+
+char* os_getcwd_platform(PikaObj* self) {
+    char dirpath[256] = {0};
+    if (getcwd(dirpath, sizeof(dirpath)) == NULL) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        obj_setStr(self, "os_current_path", "");
+        return NULL;
+    }
+    obj_setStr(self, "os_current_path", dirpath);
+    return obj_getStr(self, "os_current_path");
+}
+
+PikaObj* os_listdir_platform(char* path) {
+#ifdef _WIN32
+    struct _finddata_t fb;
+    long handle = 0;
+    char dirpath[256] = {0};
+    char* currentPath = getcwd(dirpath, 256);
+    memcpy(dirpath + strlen(dirpath), path, strlen(path));
+    strcat(dirpath, "/*");
+
+    PikaObj* list = newNormalObj(New_PikaStdData_List);
+    PikaStdData_List___init__(list);
+
+    handle = _findfirst(dirpath, &fb);
+    //找到第一个匹配的文件
+    if (handle != -1L) {
+        if (memcmp(fb.name, ".", 1) != 0) {
+            Arg* arg = arg_setStr(NULL, "", fb.name);
+
+            PikaStdData_List_append(list, arg);
+
+            arg_deinit(arg);
+        }
+
+        while (0 == _findnext(handle, &fb)) {
+            if (memcmp(fb.name, "..", 2) != 0) {
+                Arg* arg = arg_setStr(NULL, "", fb.name);
+                PikaStdData_List_append(list, arg);
+                arg_deinit(arg);
+            }
+        }
+        _findclose(handle);
+    }
+
+    return list;
+#elif defined(__linux)
+    struct dirent* dp;
+    DIR* dir = opendir(path);
+
+    PikaObj* list = newNormalObj(New_PikaStdData_List);
+    PikaStdData_List___init__(list);
+
+    if (dir != NULL) {
+        while ((dp = readdir(dir)) != NULL) {
+            if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
+                Arg* arg = arg_setStr(NULL, "", dp->d_name);
+                PikaStdData_List_append(list, arg);
+                arg_deinit(arg);
+            }
+        }
+
+        closedir(dir);
+    }
+
+    return list;
+#endif
+}
+
+int os_mkdir_platform(int mode, char* path) {
+    char dirpath[256] = {0};
+    int ret = 0;
+    memcpy(dirpath + strlen(dirpath), path, strlen(path));
+
+    ret = mkdir(dirpath, mode);
+    if (ret != 0)
+        printf("create file error\n");
+    return ret;
+}
+
+int os_chdir_platform(char* path) {
+    int ret = 0;
+    ret = chdir(path);
+    if (ret == 0)
+        ret = PIKA_TRUE;
+    else
+        ret = PIKA_FALSE;
+
+    return ret;
+}
+
+int os_rmdir_platform(char* path) {
+    int ret = 0;
+    char dirpath[256] = {0};
+    memcpy(dirpath + strlen(dirpath), path, strlen(path));
+
+    ret = rmdir(dirpath);
+    return ret;
+}
+
+int os_remove_platform(char* filename) {
+    int ret = 0;
+    char dirpath[256] = {0};
+    memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
+    ret = remove(dirpath);
+    return ret;
+}

+ 38 - 0
package/os/os_platform.h

@@ -0,0 +1,38 @@
+#ifndef _OS_INTERFACE_H
+#define _OS_INTERFACE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "PikaObj.h"
+#include "PikaStdData_List.h"
+#include "TinyObj.h"
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#elif defined(__linux) || defined(ESP32)
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#endif
+enum {
+    FILE_RDONLY = 0x00,
+    FILE_WRONLY = 0x01,
+    FILE_RDWR = 0x02,
+    FILE_CREAT = 0x0100,
+    FILE_APPEND = 0x02000,
+};
+
+PikaObj* os_open_platform(char* filename, int flags);
+char* os_read_platform(PikaObj* self, PikaObj* fd, int len);
+int os_write_platform(uint8_t* buf, size_t len, PikaObj* fd);
+int os_lseek_platform(PikaObj* fd, int how, int pos);
+int os_close_platform(PikaObj* fd);
+char* os_getcwd_platform(PikaObj* self);
+PikaObj* os_listdir_platform(char* path);
+int os_mkdir_platform(int mode, char* path);
+int os_chdir_platform(char* path);
+int os_rmdir_platform(char* path);
+int os_remove_platform(char* filename);
+int os_getFileSize(PikaObj* fd);
+
+#endif

+ 1 - 1
port/linux/package/pikascript/main.py

@@ -5,7 +5,7 @@ import GTestTask, TempDevTest
 import cb_test
 import configparser, network
 import test_module1, test_cmodule, test_module4, import_test
-import hashlib, hmac, aes, base64, time
+import hashlib, hmac, aes, base64, time, os
 import _thread, weakref
 
 mem = PikaStdLib.MemChecker()

+ 62 - 0
port/linux/package/pikascript/os.pyi

@@ -0,0 +1,62 @@
+O_RDONLY: int
+O_WRONLY: int
+O_RDWR: int
+O_APPEND: int
+O_CREAT: int
+
+
+class fileStat:
+    def st_size(self) -> int:
+        pass
+
+
+def __init__(self):
+    pass
+
+
+def mkdir(self, path: str, *mode):
+    pass
+
+
+def rmdir(self, path: str):
+    pass
+
+
+def chdir(self, path: str):
+    pass
+
+
+def listdir(self, path: str) -> list:
+    pass
+
+
+def getcwd(self) -> str:
+    pass
+
+
+def open(self, filename: str, flags: int) -> FILE:
+    pass
+
+
+def read(self, fd: FILE, len: int) -> str:
+    pass
+
+
+def write(self, fd: FILE, buf: any) -> int:
+    pass
+
+
+def lseek(self, fd: FILE, pos: int, how: int) -> int:
+    pass
+
+
+def close(self, fd: FILE):
+    pass
+
+
+def fstat(self, fd: FILE) -> fileStat:
+    pass
+
+
+def remove(self, filename: str):
+    pass

+ 105 - 0
port/linux/package/pikascript/pikascript-lib/os/os.c

@@ -0,0 +1,105 @@
+#include "os.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "PikaObj.h"
+#include "PikaStdData_List.h"
+#include "TinyObj.h"
+#include "os_fileStat.h"
+#include "os_platform.h"
+
+void os___init__(PikaObj* self) {
+    // obj_newDirectObj(self,"os",New_TinyObj);
+
+    obj_setInt(self, "O_RDONLY", FILE_RDONLY);
+    obj_setInt(self, "O_WRONLY", FILE_WRONLY);
+    obj_setInt(self, "O_RDWR", FILE_RDWR);
+    obj_setInt(self, "O_APPEND", FILE_APPEND);
+    obj_setInt(self, "O_CREAT", FILE_CREAT);
+}
+//#undef _WIN32
+
+int os_fileStat_st_size(PikaObj* self) {
+    int size = obj_getInt(self, "st_size");
+    return size;
+}
+
+PikaObj* os_fstat(PikaObj* self, PikaObj* fd) {
+    int size = 0;
+    size = os_getFileSize(fd);
+
+    PikaObj* stat_obj = newNormalObj(New_os_fileStat);
+
+    obj_setInt(stat_obj, "st_size", size);
+    return stat_obj;
+}
+
+PikaObj* os_open(PikaObj* self, char* filename, int flags) {
+    return os_open_platform(filename, flags);
+}
+
+char* os_read(PikaObj* self, PikaObj* fd, int len) {
+    return os_read_platform(self, fd, len);
+}
+
+int os_write(PikaObj* self, PikaObj* fd, Arg* buf) {
+    if (arg_getType(buf) != ARG_TYPE_BYTES) {
+        obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
+        pika_platform_printf(
+            "TypeError: a bytes-like object is required, not 'str'\r\n");
+        return -1;
+    }
+    return os_write_platform(arg_getBytes(buf), arg_getBytesSize(buf), fd);
+}
+
+int os_lseek(PikaObj* self, PikaObj* fd, int how, int pos) {
+    return os_lseek_platform(fd, how, pos);
+}
+
+void os_close(PikaObj* self, PikaObj* fd) {
+    if (os_close_platform(fd) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("close file error\r\n");
+    }
+}
+
+char* os_getcwd(PikaObj* self) {
+    return os_getcwd_platform(self);
+}
+
+PikaObj* os_listdir(PikaObj* self, char* path) {
+    return os_listdir_platform(path);
+}
+
+void os_mkdir(PikaObj* self, char* path, PikaTuple* mode) {
+    int iMode = 0;
+    if (pikaTuple_getSize(mode) == 0) {
+        iMode = 0777;
+    } else {
+        iMode = pikaTuple_getInt(mode, 0);
+    }
+    if (os_mkdir_platform(iMode, path) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("mkdir error\r\n");
+    }
+}
+
+void os_chdir(PikaObj* self, char* path) {
+    if (os_chdir_platform(path) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("chdir error\r\n");
+    }
+}
+
+void os_rmdir(PikaObj* self, char* path) {
+    if (os_rmdir_platform(path) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("rmdir error\r\n");
+    }
+}
+
+void os_remove(PikaObj* self, char* filename) {
+    if (os_remove_platform(filename) < 0) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        pika_platform_printf("remove error\r\n");
+    }
+}

+ 206 - 0
port/linux/package/pikascript/pikascript-lib/os/os_platform.c

@@ -0,0 +1,206 @@
+#include "os_platform.h"
+
+int os_getFileSize(PikaObj* fd) {
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        int ret = fseek(fp, 0, SEEK_END);
+        if (ret == 0) {
+            ret = ftell(fp);
+            return ret;
+        }
+    }
+    return -2;
+}
+
+PikaObj* os_open_platform(char* filename, int flags) {
+    char file_flag[4] = {0};
+    int index = 0;
+    char dirpath[256] = {0};
+    memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
+
+    if (FILE_RDONLY == (flags & FILE_RDONLY)) {
+        file_flag[0] = 'r';
+        if (FILE_CREAT == (flags & FILE_CREAT)) {
+            file_flag[1] = 'w';
+        }
+    }
+
+    if (FILE_RDWR == (flags & FILE_RDWR)) {
+        memcpy(file_flag, "r+", 2);
+        if (FILE_CREAT == (flags & FILE_CREAT)) {
+            memcpy(file_flag, "w+", 2);
+        }
+    }
+
+    if (FILE_WRONLY == (flags & FILE_WRONLY))
+        file_flag[index] = 'w';
+
+    if (FILE_APPEND == (flags & FILE_APPEND))
+        memcpy(file_flag, "a+", 2);
+
+    FILE* fp = fopen(dirpath, file_flag);
+    if (fp != NULL) {
+        PikaObj* file_obj = newNormalObj(New_TinyObj);
+        obj_setPtr(file_obj, "fd", fp);
+        return file_obj;
+    } else {
+        return NULL;
+    }
+}
+
+char* os_read_platform(PikaObj* self, PikaObj* fd, int len) {
+    char* buf = NULL;
+    int size = 0;
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        buf = malloc(len);
+        memset(buf, 0x00, len);
+        size = fread(buf, 1, len, fp);
+
+        if (size > 0) {
+            //转换成
+            obj_setStr(self, "os_file_read", buf);
+            free(buf);
+            return obj_getStr(self, "os_file_read");
+        }
+    }
+
+    return "";
+}
+
+int os_write_platform(uint8_t* buf, size_t len, PikaObj* fd) {
+    int size = 0;
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        size = fwrite(buf, 1, len, fp);
+        return size;
+    }
+    return 0;
+}
+
+int os_lseek_platform(PikaObj* fd, int how, int pos) {
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        int ret = fseek(fp, pos, how);
+        return ret;
+
+    } else
+        return -2;
+}
+
+int os_close_platform(PikaObj* fd) {
+    FILE* fp = obj_getPtr(fd, "fd");
+    if (fp != NULL) {
+        int ret = fclose(fp);
+        return ret;
+
+    } else
+        return -2;
+}
+
+char* os_getcwd_platform(PikaObj* self) {
+    char dirpath[256] = {0};
+    if (getcwd(dirpath, sizeof(dirpath)) == NULL) {
+        obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
+        obj_setStr(self, "os_current_path", "");
+        return NULL;
+    }
+    obj_setStr(self, "os_current_path", dirpath);
+    return obj_getStr(self, "os_current_path");
+}
+
+PikaObj* os_listdir_platform(char* path) {
+#ifdef _WIN32
+    struct _finddata_t fb;
+    long handle = 0;
+    char dirpath[256] = {0};
+    char* currentPath = getcwd(dirpath, 256);
+    memcpy(dirpath + strlen(dirpath), path, strlen(path));
+    strcat(dirpath, "/*");
+
+    PikaObj* list = newNormalObj(New_PikaStdData_List);
+    PikaStdData_List___init__(list);
+
+    handle = _findfirst(dirpath, &fb);
+    //找到第一个匹配的文件
+    if (handle != -1L) {
+        if (memcmp(fb.name, ".", 1) != 0) {
+            Arg* arg = arg_setStr(NULL, "", fb.name);
+
+            PikaStdData_List_append(list, arg);
+
+            arg_deinit(arg);
+        }
+
+        while (0 == _findnext(handle, &fb)) {
+            if (memcmp(fb.name, "..", 2) != 0) {
+                Arg* arg = arg_setStr(NULL, "", fb.name);
+                PikaStdData_List_append(list, arg);
+                arg_deinit(arg);
+            }
+        }
+        _findclose(handle);
+    }
+
+    return list;
+#elif defined(__linux) || defined(ESP32)
+    struct dirent* dp;
+    DIR* dir = opendir(path);
+
+    PikaObj* list = newNormalObj(New_PikaStdData_List);
+    PikaStdData_List___init__(list);
+
+    if (dir != NULL) {
+        while ((dp = readdir(dir)) != NULL) {
+            if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
+                Arg* arg = arg_setStr(NULL, "", dp->d_name);
+                PikaStdData_List_append(list, arg);
+                arg_deinit(arg);
+            }
+        }
+
+        closedir(dir);
+    }
+
+    return list;
+#endif
+}
+
+int os_mkdir_platform(int mode, char* path) {
+    char dirpath[256] = {0};
+    int ret = 0;
+    memcpy(dirpath + strlen(dirpath), path, strlen(path));
+
+    ret = mkdir(dirpath, mode);
+    if (ret != 0)
+        printf("create file error\n");
+    return ret;
+}
+
+int os_chdir_platform(char* path) {
+    int ret = 0;
+    ret = chdir(path);
+    if (ret == 0)
+        ret = PIKA_TRUE;
+    else
+        ret = PIKA_FALSE;
+
+    return ret;
+}
+
+int os_rmdir_platform(char* path) {
+    int ret = 0;
+    char dirpath[256] = {0};
+    memcpy(dirpath + strlen(dirpath), path, strlen(path));
+
+    ret = rmdir(dirpath);
+    return ret;
+}
+
+int os_remove_platform(char* filename) {
+    int ret = 0;
+    char dirpath[256] = {0};
+    memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
+    ret = remove(dirpath);
+    return ret;
+}

+ 38 - 0
port/linux/package/pikascript/pikascript-lib/os/os_platform.h

@@ -0,0 +1,38 @@
+#ifndef _OS_INTERFACE_H
+#define _OS_INTERFACE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "PikaObj.h"
+#include "PikaStdData_List.h"
+#include "TinyObj.h"
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#elif defined(__linux) || defined(ESP32)
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#endif
+enum {
+    FILE_RDONLY = 0x00,
+    FILE_WRONLY = 0x01,
+    FILE_RDWR = 0x02,
+    FILE_CREAT = 0x0100,
+    FILE_APPEND = 0x02000,
+};
+
+PikaObj* os_open_platform(char* filename, int flags);
+char* os_read_platform(PikaObj* self, PikaObj* fd, int len);
+int os_write_platform(uint8_t* buf, size_t len, PikaObj* fd);
+int os_lseek_platform(PikaObj* fd, int how, int pos);
+int os_close_platform(PikaObj* fd);
+char* os_getcwd_platform(PikaObj* self);
+PikaObj* os_listdir_platform(char* path);
+int os_mkdir_platform(int mode, char* path);
+int os_chdir_platform(char* path);
+int os_rmdir_platform(char* path);
+int os_remove_platform(char* filename);
+int os_getFileSize(PikaObj* fd);
+
+#endif

+ 1 - 1
src/PikaObj.c

@@ -1975,7 +1975,7 @@ void pikaGC_markDump(void) {
 #else
     PikaGC gc = {0};
     pika_platform_printf(
-        "\033[31m"
+        "\033[32m"
         "========= PIKA GC DUMP =========\r\n"
         "\033[0m");
     gc.onMarkObj = _pikaGC_markDumpHandler;

+ 4 - 0
src/pika_config_valid.h

@@ -403,6 +403,10 @@
         #define PIKA_FREERTOS_ENABLE 0
     #endif
 
+    #ifndef PIKA_RTTHREAD_ENABLE
+        #define PIKA_RTTHREAD_ENABLE 0
+    #endif
+
     #ifndef PIKA_LWIP_ENABLE
         #define PIKA_LWIP_ENABLE 0
     #endif

+ 22 - 0
test/os-test.cpp

@@ -0,0 +1,22 @@
+#include "test_common.h"
+TEST_START
+#if !PIKA_NANO_ENABLE
+
+TEST(os, test1) {
+    g_PikaMemInfo.heapUsedMax = 0;
+    PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
+    extern unsigned char pikaModules_py_a[];
+    obj_linkLibrary(pikaMain, pikaModules_py_a);
+    /* run */
+    __platform_printf("BEGIN\r\n");
+    pikaVM_runSingleFile(pikaMain, "test/python/os/os_test1.py");
+    /* assert */
+    EXPECT_STREQ(log_buff[0], "PASS\r\n");
+    EXPECT_STREQ(log_buff[1], "Hello World!\r\n");
+    /* deinit */
+    obj_deinit(pikaMain);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
+#endif
+TEST_END

+ 24 - 0
test/python/os/os_test1.py

@@ -0,0 +1,24 @@
+import os
+origin = os.getcwd()
+os.chdir("test/out")
+os.getcwd()
+
+try:
+    # cleanup
+    os.remove("_testdir/testfile")
+    os.rmdir("_testdir")
+except:
+    pass
+
+os.mkdir("_testdir")
+os.chdir("_testdir")
+
+
+f = os.open("testfile", os.O_CREAT | os.O_RDWR)
+assert os.write(f, b"Hello World!") == 12
+assert os.lseek(f, 0, 0) == 0
+print(os.read(f, 100))
+os.close(f)
+os.chdir("..")
+os.chdir(origin)
+print("PASS")