diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-10-24 13:19:36 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-10-24 13:19:36 +0200 |
commit | 5f36a5f22e8bf0e9de9a8059722352d2f8cf9b5f (patch) | |
tree | dcb425849c408c6d2adf9f195ee34d23acd8901d | |
parent | bca4b71bfa1e3db74aaa706a9849e36768282a95 (diff) | |
download | serenity-5f36a5f22e8bf0e9de9a8059722352d2f8cf9b5f.zip |
Add an lstat() syscall and use it to make "ls" nicer.
-rw-r--r-- | Kernel/Syscall.cpp | 2 | ||||
-rw-r--r-- | Kernel/Syscall.h | 1 | ||||
-rw-r--r-- | Kernel/Task.cpp | 11 | ||||
-rw-r--r-- | Kernel/Task.h | 1 | ||||
-rw-r--r-- | Kernel/VGA.cpp | 1 | ||||
-rw-r--r-- | Kernel/_fs_contents | bin | 1024000 -> 1024000 bytes | |||
-rw-r--r-- | LibC/types.h | 23 | ||||
-rw-r--r-- | LibC/unistd.cpp | 5 | ||||
-rw-r--r-- | LibC/unistd.h | 32 | ||||
-rw-r--r-- | 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 Binary files differindex 25f45186bf..7aacb359bb 100644 --- a/Kernel/_fs_contents +++ b/Kernel/_fs_contents 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; } |