瀏覽代碼

fix(ioctl): check whether file is /dev/console

greatbridf 2 年之前
父節點
當前提交
5799cd8bfd
共有 3 個文件被更改,包括 34 次插入21 次删除
  1. 1 1
      include/kernel/vfs.hpp
  2. 25 6
      src/kernel/syscall.cpp
  3. 8 14
      src/kernel/vfs.cpp

+ 1 - 1
include/kernel/vfs.hpp

@@ -185,7 +185,7 @@ public:
     virtual int inode_rmfile(dentry* dir, const char* filename);
     virtual int inode_mkdir(dentry* dir, const char* dirname);
     virtual int inode_stat(dentry* dir, stat* stat);
-    virtual uint32_t inode_getnode(inode* file);
+    virtual node_t inode_getnode(inode* file);
 
     // parameter 'length' in callback:
     // if 0, 'name' should be null terminated

+ 25 - 6
src/kernel/syscall.cpp

@@ -388,6 +388,23 @@ int _syscall_setpgid(interrupt_stack* data)
     return 0;
 }
 
+constexpr bool is_tty(fs::file* file)
+{
+    if (file->type != fs::file::types::ind)
+        return false;
+
+    fs::inode* ind = file->ptr.ind;
+
+    if (!ind->flags.in.special_node)
+        return false;
+
+    fs::node_t nd = ind->fs->inode_getnode(ind);
+    if (nd.in.major != 1 || nd.in.minor != 0)
+        return false;
+
+    return true;
+}
+
 int _syscall_ioctl(interrupt_stack* data)
 {
     int fd = data->s_regs.edi;
@@ -396,18 +413,17 @@ int _syscall_ioctl(interrupt_stack* data)
     // TODO: check fd type and get tty* from fd
     //
     //       we use a trick for now, check whether
-    //       the file that fd points to is a pipe or
-    //       not. and we suppose that stdin will be
-    //       either a tty or a pipe.
+    //       the file that fd points to is special
+    //       block 1:0
     auto* file = current_process->files[fd];
     if (!file)
         return -EBADF;
 
-    if (file->type != fs::file::types::ind)
-        return -ENOTTY;
-
     switch (request) {
     case TIOCGPGRP: {
+        if (!is_tty(file))
+            return -ENOTTY;
+
         auto* pgid = (pid_t*)data->s_regs.edx;
         tty* ctrl_tty = procs->get_ctrl_tty(current_process->pid);
         // TODO: copy_to_user
@@ -415,6 +431,9 @@ int _syscall_ioctl(interrupt_stack* data)
         break;
     }
     case TIOCSPGRP: {
+        if (!is_tty(file))
+            return -ENOTTY;
+
         // TODO: copy_from_user
         pid_t pgid = *(const pid_t*)data->s_regs.edx;
         tty* ctrl_tty = procs->get_ctrl_tty(current_process->pid);

+ 8 - 14
src/kernel/vfs.cpp

@@ -217,10 +217,10 @@ int fs::vfs::inode_stat(dentry*, stat*)
     assert(false);
     return GB_FAILED;
 }
-uint32_t fs::vfs::inode_getnode(fs::inode*)
+fs::node_t fs::vfs::inode_getnode(fs::inode*)
 {
     assert(false);
-    return 0xffffffff;
+    return { SN_INVALID };
 }
 
 class tmpfs : public virtual fs::vfs {
@@ -417,9 +417,9 @@ public:
         return GB_OK;
     }
 
-    virtual uint32_t inode_getnode(fs::inode* file) override
+    virtual fs::node_t inode_getnode(fs::inode* file) override
     {
-        return as_val(_getdata(file->ino));
+        return { as_val(_getdata(file->ino)) };
     }
 };
 
@@ -429,14 +429,11 @@ static fs::special_node sns[8][8];
 size_t fs::vfs_read(fs::inode* file, char* buf, size_t buf_size, size_t offset, size_t n)
 {
     if (file->flags.in.special_node) {
-        uint32_t ret = file->fs->inode_getnode(file);
-        if (ret == SN_INVALID) {
+        fs::node_t sn = file->fs->inode_getnode(file);
+        if (sn.v == SN_INVALID) {
             errno = EINVAL;
             return 0xffffffff;
         }
-        fs::node_t sn {
-            .v = ret
-        };
         auto* ptr = &sns[sn.in.major][sn.in.minor];
         auto* ops = &ptr->ops;
         if (ops && ops->read)
@@ -452,14 +449,11 @@ size_t fs::vfs_read(fs::inode* file, char* buf, size_t buf_size, size_t offset,
 size_t fs::vfs_write(fs::inode* file, const char* buf, size_t offset, size_t n)
 {
     if (file->flags.in.special_node) {
-        uint32_t ret = file->fs->inode_getnode(file);
-        if (ret == SN_INVALID) {
+        fs::node_t sn = file->fs->inode_getnode(file);
+        if (sn.v == SN_INVALID) {
             errno = EINVAL;
             return 0xffffffff;
         }
-        fs::node_t sn {
-            .v = ret
-        };
         auto* ptr = &sns[sn.in.major][sn.in.minor];
         auto* ops = &ptr->ops;
         if (ops && ops->write)