浏览代码

新增SystemError枚举类型,使得错误处理更清晰 (#205)

login 2 年之前
父节点
当前提交
4454d1a2dd

+ 8 - 5
docs/community/code_contribution/rust-coding-style.md

@@ -29,7 +29,7 @@ fn foo() -> i32 {
 ```
 ### 2.3 错误处理
 
-  DragonOS采用返回Posix错误码作为**模块间错误处理**的方式。为了确保在模块之间,错误处理代码的一致性,我们推荐在发生错误的时候,返回`Err(i32)`,并且posix错误码的值应当是负数。这样做的优点尤其体现在跨模块调用函数时,可以直接返回错误码,从而降低错误处理代码的耦合度。
+  DragonOS采用返回Posix错误码作为**模块间错误处理**的方式。为了确保在模块之间,错误处理代码的一致性,我们推荐在发生错误的时候,返回`SystemError`类型,该类型表示posix错误码。这样做的优点尤其体现在跨模块调用函数时,可以直接返回通用的错误码,从而降低错误处理代码的耦合度。
 
 ```rust
 // 函数跨越模块边界时(由其他模块调用当前函数),不推荐
@@ -42,21 +42,22 @@ fn foo() -> Result<(), CustomErr> {
 }
 
 // 函数跨越模块边界时(由其他模块调用当前函数),推荐
-fn foo() -> Result<(), i32> {
+fn foo() -> Result<(), SystemError> {
     if 1 + 2 == 3 {
         return Ok(());
     } else {
-        return Err(-(EINVAL as i32));
+        return Err(SystemError::EINVAL);
     }
 }
 ```
 
-&emsp;&emsp;在**模块内部**,您既可以采用返回自定义错误enum的方式,也可以采用返回Posix错误码的方式。但是,我们推荐您在模块内部,采用返回自定义错误enum的方式,这样可以使错误处理代码更加清晰。
+&emsp;&emsp;在**模块内部**,您既可以采用返回自定义错误enum的方式,也可以采用返回`SystemError`的方式。但是,我们推荐您在模块内部,采用返回自定义错误enum的方式,这样可以使错误处理代码更加清晰。
 
+&emsp;&emsp;**TODO**: 将原有的使用i32作为错误码的代码,改为使用`SystemError`。
 
 ## 3. 注释
 
-&emsp;&emsp;DragonOS的注释风格与Rust官方的不太一样。但是,我们仍然推荐您在代码中加入尽可能多的有效注释,以便于其他人理解您的代码。并且,变量、函数等声明,遵守第一节中提到的命名规范,使其能够“自注释”。
+&emsp;&emsp;DragonOS的注释风格与Rust官方的不太一样,我们部分结合了Linux的注释风格。同时,我们推荐您在代码中加入尽可能多的有效注释,以便于其他人理解您的代码。并且,变量、函数等声明,遵守第一节中提到的命名规范,使其能够“自注释”。
 
 ### 3.1 函数注释
 
@@ -76,6 +77,7 @@ fn foo() -> Result<(), i32> {
 /// 函数的详细描述
 /// 
 /// @param 参数1 参数1的说明
+/// 
 /// @param 参数2 参数2的说明
 /// 
 /// @return 返回值的说明
@@ -85,5 +87,6 @@ fn foo() -> Result<(), i32> {
 
 ```rust
 /// @return Ok(返回值类型) 返回值的说明
+/// 
 /// @return Err(错误值类型) 错误的说明
 ```

+ 6 - 0
kernel/Cargo.toml

@@ -15,6 +15,12 @@ bitflags = "1.3.2"
 virtio-drivers = "0.2.0"
 # 一个无锁MPSC队列
 thingbuf = { version = "0.1.3", default-features = false, features = ["alloc"] }
+# smoltcp 0.9.1
+smoltcp = { git = "https://github.com/DragonOS-Community/smoltcp.git", rev = "9027825", default-features = false, features = ["log", "alloc",  "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]}
+# num-traits 0.2.15
+num-traits = { git = "https://github.com/DragonOS-Community/num-traits.git", rev="1597c1c", default-features = false }
+num = { version = "0.4.0", default-features = false }
+num-derive = "0.3"
 
 # 构建时依赖项
 [build-dependencies]

+ 7 - 1
kernel/src/lib.rs

@@ -26,18 +26,24 @@ mod filesystem;
 mod io;
 mod ipc;
 mod mm;
+mod net;
 mod process;
 mod sched;
 mod smp;
+mod syscall;
 mod time;
 
 #[macro_use]
 extern crate alloc;
 #[macro_use]
+extern crate bitflags;
+#[macro_use]
 extern crate lazy_static;
 
+extern crate num;
 #[macro_use]
-extern crate bitflags;
+extern crate num_derive;
+extern crate smoltcp;
 extern crate thingbuf;
 
 use mm::allocator::KernelAllocator;

+ 7 - 7
kernel/src/libs/mod.rs

@@ -1,15 +1,15 @@
-pub mod ffi_convert;
-pub mod printk;
-pub mod spinlock;
-#[macro_use]
-pub mod refcount;
 pub mod atomic;
+pub mod ffi_convert;
 pub mod list;
 pub mod lockref;
 pub mod mutex;
-pub mod vec_cursor;
+pub mod printk;
 #[macro_use]
-pub mod volatile_io;
+pub mod refcount;
 pub mod rwlock;
 pub mod semaphore;
+pub mod spinlock;
+pub mod vec_cursor;
+#[macro_use]
+pub mod volatile_io;
 pub mod wait_queue;

+ 9 - 0
kernel/src/net/mod.rs

@@ -0,0 +1,9 @@
+use core::fmt::Debug;
+
+use crate::syscall::SystemError;
+
+pub trait Socket: Sync + Send + Debug {
+    fn read(&self, buf: &mut [u8]) -> Result<usize, SystemError>;
+
+    fn write(&self, buf: &[u8]) -> Result<usize, SystemError>;
+}

+ 167 - 0
kernel/src/syscall/mod.rs

@@ -0,0 +1,167 @@
+#[repr(i32)]
+#[derive(Debug, FromPrimitive)]
+#[allow(dead_code)]
+pub enum SystemError {
+    /// 参数列表过长,或者在输出buffer中缺少空间 或者参数比系统内建的最大值要大 Argument list too long.
+    E2BIG = 1,
+    /// 访问被拒绝 Permission denied
+    EACCES = 2,
+    /// 地址正在被使用 Address in use.
+    EADDRINUSE = 3,
+    /// 地址不可用 Address  not available.
+    EADDRNOTAVAIL = 4,
+    /// 地址family不支持 Address family not supported.
+    EAFNOSUPPORT = 5,
+    /// 资源不可用,请重试。 Resource unavailable, try again (may be the same value as [EWOULDBLOCK])
+    EAGAIN = 6,
+    /// 连接已经在处理 Connection already in progress.
+    EALREADY = 7,
+    /// 错误的文件描述符 Bad file descriptor.
+    EBADF = 8,
+    /// 错误的消息 Bad message.
+    EBADMSG = 9,
+    /// 设备或资源忙 Device or resource busy.
+    EBUSY = 10,
+    /// 操作被取消 Operation canceled.
+    ECANCELED = 11,
+    /// 没有子进程 No child processes.
+    ECHILD = 12,
+    /// 连接已断开 Connection aborted.
+    ECONNABORTED = 13,
+    /// 连接被拒绝 Connection refused.
+    ECONNREFUSED = 14,
+    /// 连接被重置 Connection reset.
+    ECONNRESET = 15,
+    /// 资源死锁将要发生 Resource deadlock would occur.
+    EDEADLK = 16,
+    /// 需要目标地址 Destination address required.
+    EDESTADDRREQ = 17,
+    /// 数学参数超出作用域 Mathematics argument out of domain of function.
+    EDOM = 18,
+    /// 保留使用 Reserved
+    EDQUOT = 19,
+    /// 文件已存在 File exists.
+    EEXIST = 20,
+    /// 错误的地址 Bad address
+    EFAULT = 21,
+    /// 文件太大 File too large.
+    EFBIG = 22,
+    /// 主机不可达 Host is unreachable.
+    EHOSTUNREACH = 23,
+    /// 标志符被移除 Identifier removed.
+    EIDRM = 24,
+    /// 不合法的字符序列 Illegal byte sequence.
+    EILSEQ = 25,
+    /// 操作正在处理 Operation in progress.
+    EINPROGRESS = 26,
+    /// 被中断的函数 Interrupted function.
+    EINTR = 27,
+    /// 不可用的参数 Invalid argument.
+    EINVAL = 28,
+    /// I/O错误 I/O error.
+    EIO = 29,
+    /// 套接字已连接 Socket is connected.
+    EISCONN = 30,
+    /// 是一个目录 Is a directory
+    EISDIR = 31,
+    /// 符号链接级别过多 Too many levels of symbolic links.
+    ELOOP = 32,
+    /// 文件描述符的值过大 File descriptor value too large.
+    EMFILE = 33,
+    /// 链接数过多 Too many links.
+    EMLINK = 34,
+    /// 消息过大 Message too large.
+    EMSGSIZE = 35,
+    /// 保留使用 Reserved.
+    EMULTIHOP = 36,
+    /// 文件名过长 Filename too long.
+    ENAMETOOLONG = 37,
+    /// 网络已关闭 Network is down.
+    ENETDOWN = 38,
+    /// 网络连接已断开 Connection aborted by network.
+    ENETRESET = 39,
+    /// 网络不可达 Network unreachable.
+    ENETUNREACH = 40,
+    /// 系统中打开的文件过多 Too many files open in system.
+    ENFILE = 41,
+    /// 缓冲区空间不足 No buffer space available.
+    ENOBUFS = 42,
+    /// 队列头没有可读取的消息 No message is available on the STREAM head read queue.
+    ENODATA = 43,
+    /// 没有指定的设备 No such device.
+    ENODEV = 44,
+    /// 没有指定的文件或目录 No such file or directory.
+    ENOENT = 45,
+    /// 可执行文件格式错误 Executable file format error
+    ENOEXEC = 46,
+    /// 没有可用的锁 No locks available.
+    ENOLCK = 47,
+    /// 保留 Reserved.
+    ENOLINK = 48,
+    /// 没有足够的空间 Not enough space.
+    ENOMEM = 49,
+    /// 没有期待类型的消息 No message of the desired type.
+    ENOMSG = 50,
+    /// 协议不可用 Protocol not available.
+    ENOPROTOOPT = 51,
+    /// 设备上没有空间 No space left on device.
+    ENOSPC = 52,
+    /// 没有STREAM资源  No STREAM resources.
+    ENOSR = 53,
+    /// 不是STREAM Not a STREAM
+    ENOSTR = 54,
+    /// 功能不支持 Function not supported.
+    ENOSYS = 55,
+    /// 套接字未连接 The socket is not connected.
+    ENOTCONN = 56,
+    /// 不是目录 Not a directory.
+    ENOTDIR = 57,
+    /// 目录非空 Directory not empty.
+    ENOTEMPTY = 58,
+    /// 状态不可恢复 State not recoverable.
+    ENOTRECOVERABLE = 59,
+    /// 不是一个套接字 Not a socket.
+    ENOTSOCK = 60,
+    /// 不被支持 Not supported (may be the same value as [EOPNOTSUPP]).
+    ENOTSUP = 61,
+    /// 不正确的I/O控制操作 Inappropriate I/O control operation.
+    ENOTTY = 62,
+    /// 没有这样的设备或地址 No such device or address.
+    ENXIO = 63,
+    /// 套接字不支持该操作 Operation not supported on socket (may be the same value as [ENOTSUP]).
+    EOPNOTSUPP = 64,
+    /// 数值过大,产生溢出 Value too large to be stored in data type.
+    EOVERFLOW = 65,
+    /// 之前的拥有者挂了 Previous owner died.
+    EOWNERDEAD = 66,
+    /// 操作不被允许 Operation not permitted.
+    EPERM = 67,
+    /// 断开的管道 Broken pipe.
+    EPIPE = 68,
+    /// 协议错误 Protocol error.
+    EPROTO = 69,
+    /// 协议不被支持 Protocol not supported.
+    EPROTONOSUPPORT = 70,
+    /// 对于套接字而言,错误的协议 Protocol wrong type for socket.
+    EPROTOTYPE = 71,
+    /// 结果过大 Result too large.
+    ERANGE = 72,
+    /// 只读的文件系统 Read-only file system.
+    EROFS = 73,
+    /// 错误的寻道.当前文件是pipe,不允许seek请求  Invalid seek.
+    ESPIPE = 74,
+    /// 没有这样的进程 No such process.
+    ESRCH = 75,
+    /// 保留 Reserved.
+    ESTALE = 76,
+    /// 流式ioctl()超时 Stream ioctl() timeout
+    ETIME = 77,
+    /// 连接超时 Connection timed out.
+    ETIMEDOUT = 78,
+    /// 文本文件忙 Text file busy.
+    ETXTBSY = 79,
+    /// 操作将被禁止 Operation would block (may be the same value as [EAGAIN]).
+    EWOULDBLOCK = 80,
+    /// 跨设备连接 Cross-device link.
+    EXDEV = 81,
+}