Kaynağa Gözat

Add an lstat() syscall and use it to make "ls" nicer.

Andreas Kling 6 yıl önce
ebeveyn
işleme
5f36a5f22e
10 değiştirilmiş dosya ile 118 ekleme ve 2 silme
  1. 2 0
      Kernel/Syscall.cpp
  2. 1 0
      Kernel/Syscall.h
  3. 10 1
      Kernel/Task.cpp
  4. 1 0
      Kernel/Task.h
  5. 1 0
      Kernel/VGA.cpp
  6. BIN
      Kernel/_fs_contents
  7. 23 0
      LibC/types.h
  8. 5 0
      LibC/unistd.cpp
  9. 32 0
      LibC/unistd.h
  10. 43 1
      Userland/ls.cpp

+ 2 - 0
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);

+ 1 - 0
Kernel/Syscall.h

@@ -27,6 +27,7 @@ enum Function {
     PosixMmap = 0x1995,
     PosixMunmap = 0x1996,
     GetDirEntries = 0x1997,
+    PosixLstat = 0x1998,
 };
 
 void initialize();

+ 10 - 1
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;

+ 1 - 0
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; }

+ 1 - 0
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);
 }

BIN
Kernel/_fs_contents


+ 23 - 0
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 */
+};
+
 }
 

+ 5 - 0
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);
+}
+
 }
 

+ 32 - 0
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)
+
 }
 

+ 43 - 1
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;
 }