diff --git a/CMakeLists.txt b/CMakeLists.txt index 31f65d0a..e6533eba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ add_subdirectory(LibELF) add_subdirectory(userspace) add_custom_target(sysroot - COMMAND mkdir -p ${BANAN_SYSROOT} + COMMAND ${CMAKE_COMMAND} -E make_directory ${BANAN_SYSROOT} COMMAND cd ${BANAN_SYSROOT} && sudo tar xf ${BANAN_BASE_SYSROOT} USES_TERMINAL ) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 9fbe4aad..54884377 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -96,6 +96,8 @@ namespace Kernel BAN::ErrorOr sys_close(int fd); BAN::ErrorOr sys_read(int fd, void* buffer, size_t count); BAN::ErrorOr sys_write(int fd, const void* buffer, size_t count); + BAN::ErrorOr sys_create(const char*, mode_t); + BAN::ErrorOr sys_create_dir(const char*, mode_t); BAN::ErrorOr sys_chmod(const char*, mode_t); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 46083aff..b6edb963 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -746,6 +746,22 @@ namespace Kernel return TRY(m_open_file_descriptors.write(fd, BAN::ByteSpan((uint8_t*)buffer, count))); } + BAN::ErrorOr Process::sys_create(const char* path, mode_t mode) + { + LockGuard _(m_lock); + validate_string_access(path); + TRY(create_file_or_dir(path, mode)); + return 0; + } + + BAN::ErrorOr Process::sys_create_dir(const char* path, mode_t mode) + { + LockGuard _(m_lock); + validate_string_access(path); + TRY(create_file_or_dir(path, Inode::Mode::IFDIR | mode)); + return 0; + } + BAN::ErrorOr Process::sys_chmod(const char* path, mode_t mode) { if (mode & S_IFMASK) diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index ccc9e894..6b0a4249 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -202,6 +202,12 @@ namespace Kernel case SYS_CHMOD: ret = Process::current().sys_chmod((const char*)arg1, (mode_t)arg2); break; + case SYS_CREATE: + ret = Process::current().sys_create((const char*)arg1, (mode_t)arg2); + break; + case SYS_CREATE_DIR: + ret = Process::current().sys_create_dir((const char*)arg1, (mode_t)arg2); + break; default: dwarnln("Unknown syscall {}", syscall); break; diff --git a/libc/fcntl.cpp b/libc/fcntl.cpp index 4a796461..4c6e7fd7 100644 --- a/libc/fcntl.cpp +++ b/libc/fcntl.cpp @@ -4,6 +4,11 @@ #include #include +int creat(const char* path, mode_t mode) +{ + return syscall(SYS_CREATE, path, S_IFREG | mode); +} + int open(const char* path, int oflag, ...) { va_list args; diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h index c5a51817..0daa6d7a 100644 --- a/libc/include/sys/syscall.h +++ b/libc/include/sys/syscall.h @@ -56,6 +56,8 @@ __BEGIN_DECLS #define SYS_TTY_CTRL 53 #define SYS_POWEROFF 54 #define SYS_CHMOD 55 +#define SYS_CREATE 56 // creat, mkfifo +#define SYS_CREATE_DIR 57 // mkdir __END_DECLS diff --git a/libc/sys/stat.cpp b/libc/sys/stat.cpp index 09b6140d..923e6dec 100644 --- a/libc/sys/stat.cpp +++ b/libc/sys/stat.cpp @@ -28,3 +28,8 @@ int stat(const char* __restrict path, struct stat* __restrict buf) { return syscall(SYS_STAT, path, buf, 0); } + +int mkdir(const char* path, mode_t mode) +{ + return syscall(SYS_CREATE_DIR, path, mode); +} diff --git a/userspace/CMakeLists.txt b/userspace/CMakeLists.txt index cb9bf28c..a1b64e04 100644 --- a/userspace/CMakeLists.txt +++ b/userspace/CMakeLists.txt @@ -13,6 +13,7 @@ set(USERSPACE_PROJECTS init ls meminfo + mkdir mmap-shared-test poweroff Shell diff --git a/userspace/mkdir/CMakeLists.txt b/userspace/mkdir/CMakeLists.txt new file mode 100644 index 00000000..9568f08f --- /dev/null +++ b/userspace/mkdir/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.26) + +project(mkdir CXX) + +set(SOURCES + main.cpp +) + +add_executable(mkdir ${SOURCES}) +target_compile_options(mkdir PUBLIC -O2 -g) +target_link_libraries(mkdir PUBLIC libc) + +add_custom_target(mkdir-install + COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/mkdir ${BANAN_BIN}/ + DEPENDS mkdir + USES_TERMINAL +) diff --git a/userspace/mkdir/main.cpp b/userspace/mkdir/main.cpp new file mode 100644 index 00000000..07afcd8c --- /dev/null +++ b/userspace/mkdir/main.cpp @@ -0,0 +1,23 @@ +#include +#include + +int main(int argc, char** argv) +{ + if (argc <= 1) + { + fprintf(stderr, "Missing operand\n"); + return 1; + } + + int ret = 0; + for (int i = 1; i < argc; i++) + { + if (mkdir(argv[i], 0755) == -1) + { + perror("mkdir"); + ret = 1; + } + } + + return ret; +} diff --git a/userspace/touch/main.cpp b/userspace/touch/main.cpp index 23ddd8ac..2f74dcde 100644 --- a/userspace/touch/main.cpp +++ b/userspace/touch/main.cpp @@ -4,18 +4,14 @@ int main(int argc, char** argv) { + int ret = 0; for (int i = 1; i < argc; i++) { - int fd = open(argv[i], O_WRONLY | O_CREAT, 0644); - if (fd == -1) + if (creat(argv[i], 0644) == -1 && errno != EEXIST) { - if (errno != EEXISTS) - perror(argv[i]); - } - else - { - close(fd); + perror(argv[i]); + ret = 1; } } - return 0; + return ret; }