From 5f36a5f22e8bf0e9de9a8059722352d2f8cf9b5f Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 24 Oct 2018 13:19:36 +0200 Subject: [PATCH] Add an lstat() syscall and use it to make "ls" nicer. --- Kernel/Syscall.cpp | 2 ++ Kernel/Syscall.h | 1 + Kernel/Task.cpp | 11 ++++++++++- Kernel/Task.h | 1 + Kernel/VGA.cpp | 1 + Kernel/_fs_contents | Bin 1024000 -> 1024000 bytes LibC/types.h | 23 +++++++++++++++++++++++ LibC/unistd.cpp | 5 +++++ LibC/unistd.h | 32 ++++++++++++++++++++++++++++++++ Userland/ls.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- 10 files changed, 118 insertions(+), 2 deletions(-) diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 4be04cbfac..846c1b99ea 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -68,6 +68,8 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3) return current->sys$spawn((const char*)arg1); case Syscall::GetDirEntries: return current->sys$get_dir_entries((int)arg1, (void*)arg2, (size_t)arg3); + case Syscall::PosixLstat: + return current->sys$lstat((const char*)arg1, (void*)arg2); case Syscall::PosixOpen: //kprintf("syscall: open('%s', %u)\n", arg1, arg2); return current->sys$open((const char*)arg1, (size_t)arg2); diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 70b3f12983..ff0b8af69e 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -27,6 +27,7 @@ enum Function { PosixMmap = 0x1995, PosixMunmap = 0x1996, GetDirEntries = 0x1997, + PosixLstat = 0x1998, }; void initialize(); diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index fe185cc154..7005394ee5 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -700,13 +700,22 @@ int Task::sys$close(int fd) return 0; } +int Task::sys$lstat(const char* path, void* statbuf) +{ + auto handle = VirtualFileSystem::the().open(move(path)); + if (!handle) + return -1; + handle->stat((Unix::stat*)statbuf); + return 0; +} + int Task::sys$open(const char* path, size_t pathLength) { Task::checkSanity("sys$open"); #ifdef DEBUG_IO kprintf("Task::sys$open(): PID=%u, path=%s {%u}\n", m_pid, path, pathLength); #endif - auto* handle = current->openFile(String(path, pathLength)); + auto* handle = openFile(String(path, pathLength)); if (handle) return handle->fd(); return -1; diff --git a/Kernel/Task.h b/Kernel/Task.h index 8ff28a00ed..c7ca13eeb4 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -92,6 +92,7 @@ public: int sys$open(const char* path, size_t pathLength); int sys$close(int fd); int sys$read(int fd, void* outbuf, size_t nread); + int sys$lstat(const char*, void* statbuf); int sys$seek(int fd, int offset); int sys$kill(pid_t pid, int sig); int sys$geterror() { return m_error; } diff --git a/Kernel/VGA.cpp b/Kernel/VGA.cpp index 458a3c967c..59e3c73267 100644 --- a/Kernel/VGA.cpp +++ b/Kernel/VGA.cpp @@ -10,6 +10,7 @@ PRIVATE BYTE current_attr = 0x07; void vga_scroll_up() { + InterruptDisabler disabler; memcpy(vga_mem, vga_mem + 160, 160 * 24); memset(vga_mem + (160 * 24), 0, 160); } diff --git a/Kernel/_fs_contents b/Kernel/_fs_contents index 25f45186bf0759cb69e983cecd678b2f6563db67..7aacb359bb12fc7d45c55342defaaa38d7d02b0e 100644 GIT binary patch delta 21052 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 diff --git a/LibC/types.h b/LibC/types.h index cedc52280c..d28920f7f2 100644 --- a/LibC/types.h +++ b/LibC/types.h @@ -20,5 +20,28 @@ typedef signed_dword ssize_t; typedef dword ino_t; typedef signed_dword off_t; +typedef dword dev_t; +typedef dword mode_t; +typedef dword nlink_t; +typedef dword blksize_t; +typedef dword blkcnt_t; +typedef dword time_t; + +struct stat { + dev_t st_dev; /* ID of device containing file */ + ino_t st_ino; /* inode number */ + mode_t st_mode; /* protection */ + nlink_t st_nlink; /* number of hard links */ + uid_t st_uid; /* user ID of owner */ + gid_t st_gid; /* group ID of owner */ + dev_t st_rdev; /* device ID (if special file) */ + off_t st_size; /* total size, in bytes */ + blksize_t st_blksize; /* blocksize for file system I/O */ + blkcnt_t st_blocks; /* number of 512B blocks allocated */ + time_t st_atime; /* time of last access */ + time_t st_mtime; /* time of last modification */ + time_t st_ctime; /* time of last status change */ +}; + } diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index 81570ece70..42e3f49c32 100644 --- a/LibC/unistd.cpp +++ b/LibC/unistd.cpp @@ -40,5 +40,10 @@ pid_t waitpid(pid_t waitee) return Syscall::invoke(Syscall::PosixWaitpid, waitee); } +int lstat(const char* path, stat* statbuf) +{ + return Syscall::invoke(Syscall::PosixLstat, (dword)path, (dword)statbuf); +} + } diff --git a/LibC/unistd.h b/LibC/unistd.h index 078a90fe0e..7dcbe0b51f 100644 --- a/LibC/unistd.h +++ b/LibC/unistd.h @@ -12,5 +12,37 @@ ssize_t read(int fd, void* buf, size_t count); int close(int fd); pid_t waitpid(pid_t); +int lstat(const char* path, stat* statbuf); + +#define S_IFMT 0170000 +#define S_IFDIR 0040000 +#define S_IFCHR 0020000 +#define S_IFBLK 0060000 +#define S_IFREG 0100000 +#define S_IFIFO 0010000 +#define S_IFLNK 0120000 +#define S_IFSOCK 0140000 + +#define S_ISUID 04000 +#define S_ISGID 02000 +#define S_ISVTX 01000 +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#define S_IXUSR 0100 +#define S_IRGRP 0040 +#define S_IWGRP 0020 +#define S_IXGRP 0010 +#define S_IROTH 0004 +#define S_IWOTH 0002 +#define S_IXOTH 0001 + + +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) + } diff --git a/Userland/ls.cpp b/Userland/ls.cpp index dfaa0d4eb2..eab5de08c6 100644 --- a/Userland/ls.cpp +++ b/Userland/ls.cpp @@ -9,9 +9,51 @@ int main(int c, char** v) printf("opendir failed :(\n"); return 1; } + char pathbuf[256]; while (auto* de = readdir(dirp)) { - printf("%s\n", de->d_name); + sprintf(pathbuf, "/%s", de->d_name); + stat st; + int rc = lstat(pathbuf, &st); + if (rc == -1) { + printf("Failed to stat '%s'\n", pathbuf); + return 2; + } + if (S_ISDIR(st.st_mode)) + printf("d"); + else if (S_ISLNK(st.st_mode)) + printf("l"); + else if (S_ISBLK(st.st_mode)) + printf("b"); + else if (S_ISCHR(st.st_mode)) + printf("c"); + else if (S_ISFIFO(st.st_mode)) + printf("f"); + else if (S_ISREG(st.st_mode)) + printf("-"); + else + printf("?"); + + printf("%c%c%c%c%c%c%c%c", + st.st_mode & S_IRUSR ? 'r' : '-', + st.st_mode & S_IWUSR ? 'w' : '-', + st.st_mode & S_IXUSR ? 'x' : '-', + st.st_mode & S_IRGRP ? 'r' : '-', + st.st_mode & S_IWGRP ? 'w' : '-', + st.st_mode & S_IXGRP ? 'x' : '-', + st.st_mode & S_IROTH ? 'r' : '-', + st.st_mode & S_IWOTH ? 'w' : '-' + ); + + if (st.st_mode & S_ISVTX) + printf("t"); + else + printf("%c", st.st_mode & S_IXOTH ? 'x' : '-'); + + printf(" i:%x ", de->d_ino); + printf(" %x ", st.st_size); + printf("%s%c", de->d_name, S_ISDIR(st.st_mode) ? '/' : ' '); + printf("\n"); } return 0; }