diff --git a/docs/community/code_contribution/rust-coding-style.md b/docs/community/code_contribution/rust-coding-style.md index 7de75cf4..0f8aad2a 100644 --- a/docs/community/code_contribution/rust-coding-style.md +++ b/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); } } ``` -  在**模块内部**,您既可以采用返回自定义错误enum的方式,也可以采用返回Posix错误码的方式。但是,我们推荐您在模块内部,采用返回自定义错误enum的方式,这样可以使错误处理代码更加清晰。 +  在**模块内部**,您既可以采用返回自定义错误enum的方式,也可以采用返回`SystemError`的方式。但是,我们推荐您在模块内部,采用返回自定义错误enum的方式,这样可以使错误处理代码更加清晰。 +  **TODO**: 将原有的使用i32作为错误码的代码,改为使用`SystemError`。 ## 3. 注释 -  DragonOS的注释风格与Rust官方的不太一样。但是,我们仍然推荐您在代码中加入尽可能多的有效注释,以便于其他人理解您的代码。并且,变量、函数等声明,遵守第一节中提到的命名规范,使其能够“自注释”。 +  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(错误值类型) 错误的说明 ``` diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 1f893dab..e54e01cd 100644 --- a/kernel/Cargo.toml +++ b/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] diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index c269d80d..0e897bb4 100644 --- a/kernel/src/lib.rs +++ b/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; diff --git a/kernel/src/libs/mod.rs b/kernel/src/libs/mod.rs index 3098f653..8569e0b5 100644 --- a/kernel/src/libs/mod.rs +++ b/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 printk; +#[macro_use] +pub mod refcount; +pub mod rwlock; +pub mod semaphore; +pub mod spinlock; pub mod vec_cursor; #[macro_use] pub mod volatile_io; -pub mod rwlock; -pub mod semaphore; pub mod wait_queue; diff --git a/kernel/src/net/mod.rs b/kernel/src/net/mod.rs new file mode 100644 index 00000000..1b714cf0 --- /dev/null +++ b/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; + + fn write(&self, buf: &[u8]) -> Result; +} diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs new file mode 100644 index 00000000..9efaa7df --- /dev/null +++ b/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, +}