From 8b2b52b9f69305004ba7f8883a6d3df11f061604 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Mon, 21 Nov 2011 18:49:55 +0100 Subject: [PATCH] Added unlink(2) and rm(1). --- libmaxsi/c/hsrc/unistd.h | 2 +- libmaxsi/hsrc/error.h | 1 + libmaxsi/io.cpp | 6 ++++++ sortix/filesystem.cpp | 21 +++++++++++++++++++++ sortix/filesystem.h | 2 ++ sortix/fs/initfs.cpp | 6 ++++++ sortix/fs/initfs.h | 1 + sortix/fs/ramfs.cpp | 17 +++++++++++++++++ sortix/fs/ramfs.h | 1 + sortix/syscallnum.h | 3 ++- utils/Makefile | 1 + utils/rm.cpp | 20 ++++++++++++++++++++ 12 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 utils/rm.cpp diff --git a/libmaxsi/c/hsrc/unistd.h b/libmaxsi/c/hsrc/unistd.h index 832927f6..079f7d4b 100644 --- a/libmaxsi/c/hsrc/unistd.h +++ b/libmaxsi/c/hsrc/unistd.h @@ -144,7 +144,6 @@ int tcsetpgrp(int, pid_t); int truncate(const char*, off_t); char* ttyname(int); int ttyname_r(int, char*, size_t); -int unlink(const char*); int unlinkat(int, const char*, int); #if __POSIX_OBSOLETE <= 200801 @@ -169,6 +168,7 @@ unsigned sleep(unsigned); #if __POSIX_OBSOLETE <= 200112 int usleep(useconds_t useconds); #endif +int unlink(const char*); ssize_t write(int, const void*, size_t); __END_DECLS diff --git a/libmaxsi/hsrc/error.h b/libmaxsi/hsrc/error.h index 92101dab..644cd3bb 100644 --- a/libmaxsi/hsrc/error.h +++ b/libmaxsi/hsrc/error.h @@ -57,6 +57,7 @@ namespace Maxsi const int ENOTDIR = 22; const int ENOMEM = 23; const int ERANGE = 24; + const int EISDIR = 25; extern int _errornumber; diff --git a/libmaxsi/io.cpp b/libmaxsi/io.cpp index 4b1c8a1b..1eb06f3f 100644 --- a/libmaxsi/io.cpp +++ b/libmaxsi/io.cpp @@ -40,6 +40,7 @@ namespace Maxsi DEFN_SYSCALL3(int, SysReadDirEnts, 24, int, struct sortix_dirent*, size_t); DEFN_SYSCALL1(int, SysChDir, 25, const char*); DEFN_SYSCALL2(char*, SysGetCWD, 26, char*, size_t); + DEFN_SYSCALL1(int, SysUnlink, 27, const char*); size_t Print(const char* Message) { @@ -114,6 +115,11 @@ namespace Maxsi { return SysGetCWD(buf, size); } + + extern "C" int unlink(const char* pathname) + { + return SysUnlink(pathname); + } #endif } diff --git a/sortix/filesystem.cpp b/sortix/filesystem.cpp index 81feaa8d..9df92937 100644 --- a/sortix/filesystem.cpp +++ b/sortix/filesystem.cpp @@ -53,6 +53,21 @@ namespace Sortix return result; } + bool Unlink(const char* path) + { + Process* process = CurrentProcess(); + const char* wd = process->workingdir; + char* abs = Directory::MakeAbsolute(wd, path); + if ( !abs ) { Error::Set(Error::ENOMEM); return false; } + + size_t pathoffset = 0; + DevFileSystem* fs = Mount::WhichFileSystem(abs, &pathoffset); + if ( !fs ) { delete[] abs; return false; } + bool result = fs->Unlink(abs + pathoffset); + delete[] abs; + return result; + } + int SysOpen(const char* path, int flags, mode_t mode) { Process* process = CurrentProcess(); @@ -63,9 +78,15 @@ namespace Sortix return fd; } + int SysUnlink(const char* path) + { + return Unlink(path) ? 0 : -1; + } + void Init() { Syscall::Register(SYSCALL_OPEN, (void*) SysOpen); + Syscall::Register(SYSCALL_UNLINK, (void*) SysUnlink); } } diff --git a/sortix/filesystem.h b/sortix/filesystem.h index aae0b8b8..84920f7c 100644 --- a/sortix/filesystem.h +++ b/sortix/filesystem.h @@ -55,6 +55,7 @@ namespace Sortix { public: virtual Device* Open(const char* path, int flags, mode_t mode) = 0; + virtual bool Unlink(const char* path) = 0; public: virtual bool IsType(unsigned type) { return type == Device::FILESYSTEM; } @@ -88,6 +89,7 @@ namespace Sortix { void Init(); Device* Open(const char* path, int flags, mode_t mode); + bool Unlink(const char* path); } } diff --git a/sortix/fs/initfs.cpp b/sortix/fs/initfs.cpp index 0b919110..51260c8a 100644 --- a/sortix/fs/initfs.cpp +++ b/sortix/fs/initfs.cpp @@ -228,5 +228,11 @@ namespace Sortix return result; } + + bool DevInitFS::Unlink(const char* path) + { + Error::Set(Error::EROFS); + return false; + } } diff --git a/sortix/fs/initfs.h b/sortix/fs/initfs.h index cc4d701c..65b071f2 100644 --- a/sortix/fs/initfs.h +++ b/sortix/fs/initfs.h @@ -40,6 +40,7 @@ namespace Sortix public: virtual Device* Open(const char* path, int flags, mode_t mode); + virtual bool Unlink(const char* path); }; } diff --git a/sortix/fs/ramfs.cpp b/sortix/fs/ramfs.cpp index 66793233..1db20c1f 100644 --- a/sortix/fs/ramfs.cpp +++ b/sortix/fs/ramfs.cpp @@ -302,6 +302,23 @@ namespace Sortix return file; } + bool DevRAMFS::Unlink(const char* path) + { + if ( *path == '\0' || ( *path++ == '/' && *path == '\0' ) ) + { + Error::Set(Error::EISDIR); + return false; + } + + size_t index = files->Search(LookupFile, path); + if ( index == SIZE_MAX ) { Error::Set(Error::ENOENT); return false; } + + Device* dev = files->Remove(index); + ASSERT(dev); + dev->Unref(); + return true; + } + size_t DevRAMFS::GetNumFiles() { if ( !files ) { return 0; } diff --git a/sortix/fs/ramfs.h b/sortix/fs/ramfs.h index 8179ee24..9bff9972 100644 --- a/sortix/fs/ramfs.h +++ b/sortix/fs/ramfs.h @@ -40,6 +40,7 @@ namespace Sortix public: virtual Device* Open(const char* path, int flags, mode_t mode); + virtual bool Unlink(const char* path); private: Maxsi::SortedList* files; diff --git a/sortix/syscallnum.h b/sortix/syscallnum.h index ee0c8641..bcd0504f 100644 --- a/sortix/syscallnum.h +++ b/sortix/syscallnum.h @@ -52,7 +52,8 @@ #define SYSCALL_READDIRENTS 24 #define SYSCALL_CHDIR 25 #define SYSCALL_GETCWD 26 -#define SYSCALL_MAX_NUM 27 /* index of highest constant + 1 */ +#define SYSCALL_UNLINK 27 +#define SYSCALL_MAX_NUM 28 /* index of highest constant + 1 */ #endif diff --git a/utils/Makefile b/utils/Makefile index 137ac265..cfda47a9 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -7,6 +7,7 @@ LOCALBINARIES:=\ init \ cat \ cp \ +rm \ sh \ mxsh \ clear \ diff --git a/utils/rm.cpp b/utils/rm.cpp new file mode 100644 index 00000000..1203d0b7 --- /dev/null +++ b/utils/rm.cpp @@ -0,0 +1,20 @@ +#include +#include + +int main(int argc, char* argv[]) +{ + if ( argc < 2 ) { printf("usage: %s ...\n"); return 0; } + + int result = 0; + + for ( int i = 1; i < argc; i++ ) + { + if ( unlink(argv[i]) ) + { + printf("%s: unable to unlink: %s\n", argv[0], argv[i]); + result = 1; + } + } + + return result; +}