Merge branch 'pal_errno2' into 'master'

Remove the C-style "-1 or errno" e() function entirely

See merge request redox-os/relibc!516
This commit is contained in:
Jeremy Soller
2024-09-27 16:31:00 +00:00
15 changed files with 287 additions and 313 deletions
+30 -63
View File
@@ -1,9 +1,14 @@
use core::{mem, slice};
use redox_rt::proc::FdGuard;
use syscall;
use crate::{
header::{errno, fcntl, termios},
platform::{self, e, types::*},
error::{Errno, Result, ResultExt},
header::{
errno::{self, EINVAL},
fcntl, termios,
},
platform::{self, types::*, Pal, Sys},
};
use super::winsize;
@@ -49,123 +54,85 @@ fn dup_read<T>(fd: c_int, name: &str, t: &mut T) -> syscall::Result<usize> {
res.map(|bytes| bytes / size)
}
fn dup_write<T>(fd: c_int, name: &str, t: &T) -> syscall::Result<usize> {
let dup = syscall::dup(fd as usize, name.as_bytes())?;
// FIXME: unsound
fn dup_write<T>(fd: c_int, name: &str, t: &T) -> Result<usize> {
let dup = FdGuard::new(syscall::dup(fd as usize, name.as_bytes())?);
let size = mem::size_of::<T>();
let res = syscall::write(dup, unsafe {
let bytes_written = syscall::write(*dup, unsafe {
slice::from_raw_parts(t as *const T as *const u8, size)
});
})?;
let _ = syscall::close(dup);
res.map(|bytes| bytes / size)
Ok(bytes_written / size)
}
#[no_mangle]
pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int {
unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Result<c_int> {
match request {
FIONBIO => {
let mut flags = fcntl::fcntl(fd, fcntl::F_GETFL, 0);
if flags < 0 {
return -1;
}
let mut flags = Sys::fcntl(fd, fcntl::F_GETFL, 0)?;
flags = if *(out as *mut c_int) == 0 {
flags & !fcntl::O_NONBLOCK
} else {
flags | fcntl::O_NONBLOCK
};
if fcntl::fcntl(fd, fcntl::F_SETFL, flags as c_ulonglong) < 0 {
-1
} else {
0
}
Sys::fcntl(fd, fcntl::F_SETFL, flags as c_ulonglong)?;
}
TCGETS => {
let termios = &mut *(out as *mut termios::termios);
if e(dup_read(fd, "termios", termios)) == !0 {
-1
} else {
0
}
dup_read(fd, "termios", termios)?;
}
// TODO: give these different behaviors
TCSETS | TCSETSW | TCSETSF => {
let termios = &*(out as *const termios::termios);
if e(dup_write(fd, "termios", termios)) == !0 {
-1
} else {
0
}
dup_write(fd, "termios", termios)?;
}
TCFLSH => {
let queue = out as c_int;
if e(dup_write(fd, "flush", &queue)) == !0 {
-1
} else {
0
}
dup_write(fd, "flush", &queue)?;
}
TIOCSCTTY => {
eprintln!("TODO: ioctl TIOCSCTTY");
0
}
TIOCGPGRP => {
let pgrp = &mut *(out as *mut pid_t);
if e(dup_read(fd, "pgrp", pgrp)) == !0 {
-1
} else {
0
}
dup_read(fd, "pgrp", pgrp)?;
}
TIOCSPGRP => {
let pgrp = &*(out as *const pid_t);
if e(dup_write(fd, "pgrp", pgrp)) == !0 {
-1
} else {
0
}
dup_write(fd, "pgrp", pgrp)?;
}
TIOCGWINSZ => {
let winsize = &mut *(out as *mut winsize);
if e(dup_read(fd, "winsize", winsize)) == !0 {
-1
} else {
0
}
dup_read(fd, "winsize", winsize)?;
}
TIOCSWINSZ => {
let winsize = &*(out as *const winsize);
if e(dup_write(fd, "winsize", winsize)) == !0 {
-1
} else {
0
}
dup_write(fd, "winsize", winsize)?;
}
TIOCGPTLCK => {
eprintln!("TODO: ioctl TIOCGPTLCK");
0
}
TIOCSPTLCK => {
eprintln!("TODO: ioctl TIOCSPTLCK");
0
}
TCSBRK => {
eprintln!("TODO: ioctl TCSBRK");
0
}
TCXONC => {
eprintln!("TODO: ioctl TCXONC");
0
}
SIOCATMARK => {
eprintln!("TODO: ioctl SIOCATMARK");
0
}
_ => {
platform::ERRNO.set(errno::EINVAL);
-1
return Err(Errno(EINVAL));
}
}
Ok(0)
}
#[no_mangle]
pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int {
ioctl_inner(fd, request, out).or_minus_one_errno()
}
+5 -2
View File
@@ -1,6 +1,9 @@
//! ptrace compatibility layer for Redox OS
use crate::platform::{types::*, PalPtrace, Sys};
use crate::{
error::ResultExt,
platform::{types::*, PalPtrace, Sys},
};
use core::ffi::VaList;
pub const PTRACE_TRACEME: c_int = 0;
@@ -25,5 +28,5 @@ pub const PTRACE_SYSEMU_SINGLESTEP: c_int = 32;
#[no_mangle]
pub unsafe extern "C" fn ptrace(request: c_int, mut __valist: ...) -> c_int {
// Musl also just grabs the arguments from the varargs...
Sys::ptrace(request, __valist.arg(), __valist.arg(), __valist.arg())
Sys::ptrace(request, __valist.arg(), __valist.arg(), __valist.arg()).or_minus_one_errno()
}
+35 -12
View File
@@ -3,6 +3,7 @@
use core::ptr;
use crate::{
error::ResultExt,
header::sys_uio::iovec,
platform::{types::*, PalSocket, Sys},
};
@@ -47,7 +48,7 @@ pub unsafe extern "C" fn accept(
address_len: *mut socklen_t,
) -> c_int {
trace_expr!(
Sys::accept(socket, address, address_len),
Sys::accept(socket, address, address_len).or_minus_one_errno(),
"accept({}, {:p}, {:p})",
socket,
address,
@@ -62,7 +63,9 @@ pub unsafe extern "C" fn bind(
address_len: socklen_t,
) -> c_int {
trace_expr!(
Sys::bind(socket, address, address_len),
Sys::bind(socket, address, address_len)
.map(|()| 0)
.or_minus_one_errno(),
"bind({}, {:p}, {})",
socket,
address,
@@ -77,7 +80,7 @@ pub unsafe extern "C" fn connect(
address_len: socklen_t,
) -> c_int {
trace_expr!(
Sys::connect(socket, address, address_len),
Sys::connect(socket, address, address_len).or_minus_one_errno(),
"connect({}, {:p}, {})",
socket,
address,
@@ -92,7 +95,9 @@ pub unsafe extern "C" fn getpeername(
address_len: *mut socklen_t,
) -> c_int {
trace_expr!(
Sys::getpeername(socket, address, address_len),
Sys::getpeername(socket, address, address_len)
.map(|()| 0)
.or_minus_one_errno(),
"getpeername({}, {:p}, {:p})",
socket,
address,
@@ -107,7 +112,9 @@ pub unsafe extern "C" fn getsockname(
address_len: *mut socklen_t,
) -> c_int {
trace_expr!(
Sys::getsockname(socket, address, address_len),
Sys::getsockname(socket, address, address_len)
.map(|()| 0)
.or_minus_one_errno(),
"getsockname({}, {:p}, {:p})",
socket,
address,
@@ -124,7 +131,9 @@ pub unsafe extern "C" fn getsockopt(
option_len: *mut socklen_t,
) -> c_int {
trace_expr!(
Sys::getsockopt(socket, level, option_name, option_value, option_len),
Sys::getsockopt(socket, level, option_name, option_value, option_len)
.map(|()| 0)
.or_minus_one_errno(),
"getsockopt({}, {}, {}, {:p}, {:p})",
socket,
level,
@@ -137,6 +146,8 @@ pub unsafe extern "C" fn getsockopt(
#[no_mangle]
pub unsafe extern "C" fn listen(socket: c_int, backlog: c_int) -> c_int {
Sys::listen(socket, backlog)
.map(|()| 0)
.or_minus_one_errno()
}
#[no_mangle]
@@ -166,7 +177,9 @@ pub unsafe extern "C" fn recvfrom(
address_len: *mut socklen_t,
) -> ssize_t {
trace_expr!(
Sys::recvfrom(socket, buffer, length, flags, address, address_len),
Sys::recvfrom(socket, buffer, length, flags, address, address_len)
.map(|r| r as ssize_t)
.or_minus_one_errno(),
"recvfrom({}, {:p}, {}, {:#x}, {:p}, {:p})",
socket,
buffer,
@@ -180,6 +193,8 @@ pub unsafe extern "C" fn recvfrom(
#[no_mangle]
pub unsafe extern "C" fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t {
Sys::recvmsg(socket, msg, flags)
.map(|r| r as ssize_t)
.or_minus_one_errno()
}
#[no_mangle]
@@ -195,6 +210,8 @@ pub unsafe extern "C" fn send(
#[no_mangle]
pub unsafe extern "C" fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t {
Sys::sendmsg(socket, msg, flags)
.map(|w| w as ssize_t)
.or_minus_one_errno()
}
#[no_mangle]
@@ -207,7 +224,9 @@ pub unsafe extern "C" fn sendto(
dest_len: socklen_t,
) -> ssize_t {
trace_expr!(
Sys::sendto(socket, message, length, flags, dest_addr, dest_len),
Sys::sendto(socket, message, length, flags, dest_addr, dest_len)
.map(|w| w as ssize_t)
.or_minus_one_errno(),
"sendto({}, {:p}, {}, {:#x}, {:p}, {})",
socket,
message,
@@ -227,7 +246,9 @@ pub unsafe extern "C" fn setsockopt(
option_len: socklen_t,
) -> c_int {
trace_expr!(
Sys::setsockopt(socket, level, option_name, option_value, option_len),
Sys::setsockopt(socket, level, option_name, option_value, option_len)
.map(|()| 0)
.or_minus_one_errno(),
"setsockopt({}, {}, {}, {:p}, {})",
socket,
level,
@@ -239,13 +260,13 @@ pub unsafe extern "C" fn setsockopt(
#[no_mangle]
pub unsafe extern "C" fn shutdown(socket: c_int, how: c_int) -> c_int {
Sys::shutdown(socket, how)
Sys::shutdown(socket, how).map(|()| 0).or_minus_one_errno()
}
#[no_mangle]
pub unsafe extern "C" fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
trace_expr!(
Sys::socket(domain, kind, protocol),
Sys::socket(domain, kind, protocol).or_minus_one_errno(),
"socket({}, {}, {})",
domain,
kind,
@@ -261,7 +282,9 @@ pub unsafe extern "C" fn socketpair(
sv: *mut c_int,
) -> c_int {
trace_expr!(
Sys::socketpair(domain, kind, protocol, &mut *(sv as *mut [c_int; 2])),
Sys::socketpair(domain, kind, protocol, &mut *(sv as *mut [c_int; 2]))
.map(|()| 0)
.or_minus_one_errno(),
"socketpair({}, {}, {}, {:p})",
domain,
kind,
-9
View File
@@ -64,15 +64,6 @@ pub fn e_raw(sys: usize) -> Result<usize> {
Ok(sys)
}
}
pub fn e(sys: usize) -> usize {
match e_raw(sys) {
Ok(value) => value,
Err(Errno(errcode)) => {
ERRNO.set(errcode as c_int);
!0
}
}
}
pub struct Sys;
+9 -3
View File
@@ -1,10 +1,16 @@
use super::{
super::{types::*, PalPtrace},
e, Sys,
e_raw, Sys,
};
use crate::error::Result;
impl PalPtrace for Sys {
fn ptrace(request: c_int, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> c_int {
unsafe { e(syscall!(PTRACE, request, pid, addr, data)) as c_int }
unsafe fn ptrace(
request: c_int,
pid: pid_t,
addr: *mut c_void,
data: *mut c_void,
) -> Result<c_int> {
Ok(unsafe { e_raw(syscall!(PTRACE, request, pid, addr, data))? as c_int })
}
}
+1 -1
View File
@@ -3,7 +3,7 @@ use core::{mem, ptr::addr_of};
use super::{
super::{types::*, PalSignal},
e, e_raw, Sys,
e_raw, Sys,
};
use crate::{
error::{Errno, Result},
+57 -40
View File
@@ -1,46 +1,58 @@
use super::{
super::{types::*, PalSocket},
e, Sys,
use super::{e_raw, Sys};
use crate::{
error::Result,
header::sys_socket::{msghdr, sockaddr, socklen_t},
platform::{types::*, PalSocket},
};
use crate::header::sys_socket::{msghdr, sockaddr, socklen_t};
impl PalSocket for Sys {
unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
e(syscall!(ACCEPT, socket, address, address_len)) as c_int
unsafe fn accept(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> Result<c_int> {
Ok(e_raw(syscall!(ACCEPT, socket, address, address_len))? as c_int)
}
unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
e(syscall!(BIND, socket, address, address_len)) as c_int
unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> Result<()> {
e_raw(syscall!(BIND, socket, address, address_len))?;
Ok(())
}
unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
e(syscall!(CONNECT, socket, address, address_len)) as c_int
unsafe fn connect(
socket: c_int,
address: *const sockaddr,
address_len: socklen_t,
) -> Result<c_int> {
Ok(e_raw(syscall!(CONNECT, socket, address, address_len))? as c_int)
}
unsafe fn getpeername(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> c_int {
e(syscall!(GETPEERNAME, socket, address, address_len)) as c_int
) -> Result<()> {
e_raw(syscall!(GETPEERNAME, socket, address, address_len))?;
Ok(())
}
unsafe fn getsockname(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> c_int {
e(syscall!(GETSOCKNAME, socket, address, address_len)) as c_int
) -> Result<()> {
e_raw(syscall!(GETSOCKNAME, socket, address, address_len))?;
Ok(())
}
fn getsockopt(
unsafe fn getsockopt(
socket: c_int,
level: c_int,
option_name: c_int,
option_value: *mut c_void,
option_len: *mut socklen_t,
) -> c_int {
e(unsafe {
) -> Result<()> {
e_raw(unsafe {
syscall!(
GETSOCKOPT,
socket,
@@ -49,11 +61,13 @@ impl PalSocket for Sys {
option_value,
option_len
)
}) as c_int
})?;
Ok(())
}
fn listen(socket: c_int, backlog: c_int) -> c_int {
e(unsafe { syscall!(LISTEN, socket, backlog) }) as c_int
fn listen(socket: c_int, backlog: c_int) -> Result<()> {
e_raw(unsafe { syscall!(LISTEN, socket, backlog) })?;
Ok(())
}
unsafe fn recvfrom(
@@ -63,8 +77,8 @@ impl PalSocket for Sys {
flags: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> ssize_t {
e(syscall!(
) -> Result<usize> {
e_raw(syscall!(
RECVFROM,
socket,
buf,
@@ -72,15 +86,15 @@ impl PalSocket for Sys {
flags,
address,
address_len
)) as ssize_t
))
}
unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t {
e(syscall!(RECVMSG, socket, msg, flags)) as ssize_t
unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> Result<usize> {
e_raw(syscall!(RECVMSG, socket, msg, flags))
}
unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t {
e(syscall!(SENDMSG, socket, msg, flags)) as ssize_t
unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> Result<usize> {
e_raw(syscall!(SENDMSG, socket, msg, flags))
}
unsafe fn sendto(
@@ -90,20 +104,20 @@ impl PalSocket for Sys {
flags: c_int,
dest_addr: *const sockaddr,
dest_len: socklen_t,
) -> ssize_t {
e(syscall!(
) -> Result<usize> {
e_raw(syscall!(
SENDTO, socket, buf, len, flags, dest_addr, dest_len
)) as ssize_t
))
}
fn setsockopt(
unsafe fn setsockopt(
socket: c_int,
level: c_int,
option_name: c_int,
option_value: *const c_void,
option_len: socklen_t,
) -> c_int {
e(unsafe {
) -> Result<()> {
e_raw(unsafe {
syscall!(
SETSOCKOPT,
socket,
@@ -112,18 +126,21 @@ impl PalSocket for Sys {
option_value,
option_len
)
}) as c_int
})?;
Ok(())
}
fn shutdown(socket: c_int, how: c_int) -> c_int {
e(unsafe { syscall!(SHUTDOWN, socket, how) }) as c_int
fn shutdown(socket: c_int, how: c_int) -> Result<()> {
e_raw(unsafe { syscall!(SHUTDOWN, socket, how) })?;
Ok(())
}
unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
e(syscall!(SOCKET, domain, kind, protocol)) as c_int
unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> Result<c_int> {
Ok(e_raw(syscall!(SOCKET, domain, kind, protocol))? as c_int)
}
fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> c_int {
e(unsafe { syscall!(SOCKETPAIR, domain, kind, protocol, sv.as_mut_ptr()) }) as c_int
fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> Result<()> {
e_raw(unsafe { syscall!(SOCKETPAIR, domain, kind, protocol, sv.as_mut_ptr()) })?;
Ok(())
}
}
+1 -1
View File
@@ -13,7 +13,7 @@ pub use self::pal::{Pal, PalEpoll, PalPtrace, PalSignal, PalSocket};
mod pal;
pub use self::sys::{e, Sys};
pub use self::sys::Sys;
#[cfg(all(not(feature = "no_std"), target_os = "linux"))]
#[path = "linux/mod.rs"]
+10 -2
View File
@@ -1,5 +1,13 @@
use super::super::{types::*, Pal};
use crate::{
error::Result,
platform::{types::*, Pal},
};
pub trait PalPtrace: Pal {
fn ptrace(request: c_int, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> c_int;
unsafe fn ptrace(
request: c_int,
pid: pid_t,
addr: *mut c_void,
data: *mut c_void,
) -> Result<c_int>;
}
+30 -19
View File
@@ -1,34 +1,45 @@
use super::super::{types::*, Pal};
use crate::header::sys_socket::{msghdr, sockaddr, socklen_t};
use crate::{
error::Result,
header::sys_socket::{msghdr, sockaddr, socklen_t},
platform::{types::*, Pal},
};
pub trait PalSocket: Pal {
unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int;
unsafe fn accept(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> Result<c_int>;
unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int;
unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> Result<()>;
unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int;
unsafe fn connect(
socket: c_int,
address: *const sockaddr,
address_len: socklen_t,
) -> Result<c_int>;
unsafe fn getpeername(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> c_int;
) -> Result<()>;
unsafe fn getsockname(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> c_int;
) -> Result<()>;
fn getsockopt(
unsafe fn getsockopt(
socket: c_int,
level: c_int,
option_name: c_int,
option_value: *mut c_void,
option_len: *mut socklen_t,
) -> c_int;
) -> Result<()>;
fn listen(socket: c_int, backlog: c_int) -> c_int;
fn listen(socket: c_int, backlog: c_int) -> Result<()>;
unsafe fn recvfrom(
socket: c_int,
@@ -37,11 +48,11 @@ pub trait PalSocket: Pal {
flags: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> ssize_t;
) -> Result<usize>;
unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t;
unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> Result<usize>;
unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t;
unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> Result<usize>;
unsafe fn sendto(
socket: c_int,
@@ -50,19 +61,19 @@ pub trait PalSocket: Pal {
flags: c_int,
dest_addr: *const sockaddr,
dest_len: socklen_t,
) -> ssize_t;
) -> Result<usize>;
fn setsockopt(
unsafe fn setsockopt(
socket: c_int,
level: c_int,
option_name: c_int,
option_value: *const c_void,
option_len: socklen_t,
) -> c_int;
) -> Result<()>;
fn shutdown(socket: c_int, how: c_int) -> c_int;
fn shutdown(socket: c_int, how: c_int) -> Result<()>;
unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int;
unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> Result<c_int>;
fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> c_int;
fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> Result<()>;
}
+9 -3
View File
@@ -1,16 +1,22 @@
use core::{ptr, slice};
use crate::platform::{sys::e, types::*};
use crate::{
error::{Errno, ResultExt},
platform::types::*,
};
use syscall::{error::*, F_SETFD, F_SETFL};
pub use redox_rt::proc::FdGuard;
#[no_mangle]
pub unsafe extern "C" fn redox_fpath(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t {
e(syscall::fpath(
syscall::fpath(
fd as usize,
slice::from_raw_parts_mut(buf as *mut u8, count),
)) as ssize_t
)
.map_err(Errno::from)
.map(|l| l as ssize_t)
.or_minus_one_errno()
}
pub fn pipe2(fds: &mut [c_int], flags: usize) -> syscall::error::Result<()> {
-11
View File
@@ -74,17 +74,6 @@ macro_rules! path_from_c_str {
use self::{exec::Executable, path::canonicalize};
// TODO: Remove
pub fn e(sys: syscall::error::Result<usize>) -> usize {
match sys {
Ok(ok) => ok,
Err(err) => {
ERRNO.set(err.errno as c_int);
!0
}
}
}
pub struct Sys;
impl Pal for Sys {
+16 -6
View File
@@ -11,8 +11,12 @@ use crate::header::arch_aarch64_user::user_regs_struct;
use crate::header::arch_x64_user::user_regs_struct;
use crate::{
c_str::{CStr, CString},
error::Errno,
fs::File,
header::{errno as errnoh, fcntl, signal, sys_ptrace},
header::{
errno::{self as errnoh, EIO},
fcntl, signal, sys_ptrace,
},
io::{self, prelude::*},
sync::Mutex,
};
@@ -104,7 +108,7 @@ pub fn get_session(
}
#[cfg(target_arch = "aarch64")]
fn inner_ptrace(
unsafe fn inner_ptrace(
request: c_int,
pid: pid_t,
addr: *mut c_void,
@@ -115,7 +119,7 @@ fn inner_ptrace(
}
#[cfg(target_arch = "x86")]
fn inner_ptrace(
unsafe fn inner_ptrace(
request: c_int,
pid: pid_t,
addr: *mut c_void,
@@ -126,7 +130,7 @@ fn inner_ptrace(
}
#[cfg(target_arch = "x86_64")]
fn inner_ptrace(
unsafe fn inner_ptrace(
request: c_int,
pid: pid_t,
addr: *mut c_void,
@@ -253,7 +257,13 @@ fn inner_ptrace(
}
impl PalPtrace for Sys {
fn ptrace(request: c_int, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> c_int {
inner_ptrace(request, pid, addr, data).unwrap_or(-1)
unsafe fn ptrace(
request: c_int,
pid: pid_t,
addr: *mut c_void,
data: *mut c_void,
) -> Result<c_int, Errno> {
inner_ptrace(request, pid, addr, data)
.map_err(|err| Errno(err.raw_os_error().unwrap_or(EIO)))
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
use super::{
super::{types::*, Pal, PalSignal},
e, Sys,
Sys,
};
use crate::{
error::{Errno, Result},
+83 -140
View File
@@ -1,15 +1,17 @@
use alloc::vec::Vec;
use core::{cmp, mem, ptr, slice, str};
use syscall::{self, flag::*, Result};
use redox_rt::proc::FdGuard;
use syscall::{self, flag::*};
use super::{
super::{types::*, Pal, PalSocket, ERRNO},
e, Sys,
Sys,
};
use crate::{
error::ResultExt,
error::{Errno, Result, ResultExt},
header::{
arpa_inet::inet_aton,
errno::{EAFNOSUPPORT, EFAULT, EINVAL, ENOSYS, EOPNOTSUPP, EPROTONOSUPPORT},
netinet_in::{in_addr, in_port_t, sockaddr_in},
string::strnlen,
sys_socket::{constants::*, msghdr, sa_family_t, sockaddr, socklen_t},
@@ -26,26 +28,20 @@ macro_rules! bind_or_connect {
$path
};
($mode:ident into, $socket:expr, $address:expr, $address_len:expr) => {{
let fd = bind_or_connect!($mode copy, $socket, $address, $address_len);
let fd = bind_or_connect!($mode copy, $socket, $address, $address_len)?;
let result = syscall::dup2(fd, $socket as usize, &[]);
let _ = syscall::close(fd);
if (e(result) as c_int) < 0 {
return -1;
}
0
let _ = syscall::dup2(fd, $socket as usize, &[])?;
Result::<c_int, Errno>::Ok(0)
}};
($mode:ident copy, $socket:expr, $address:expr, $address_len:expr) => {{
if ($address_len as usize) < mem::size_of::<sa_family_t>() {
ERRNO.set(syscall::EINVAL);
return -1;
return Err(Errno(EINVAL));
}
let path = match (*$address).sa_family as c_int {
AF_INET => {
if ($address_len as usize) != mem::size_of::<sockaddr_in>() {
ERRNO.set(syscall::EINVAL);
return -1;
return Err(Errno(EINVAL));
}
let data = &*($address as *const sockaddr_in);
let addr = slice::from_raw_parts(
@@ -96,17 +92,12 @@ macro_rules! bind_or_connect {
path
},
_ => {
ERRNO.set(syscall::EAFNOSUPPORT);
return -1;
return Err(Errno(EAFNOSUPPORT));
},
};
// Duplicate the socket, and then duplicate the copy back to the original fd
let fd = e(syscall::dup($socket as usize, path.as_bytes()));
if (fd as c_int) < 0 {
return -1;
}
fd
syscall::dup($socket as usize, path.as_bytes())
}};
}
@@ -175,7 +166,7 @@ unsafe fn inner_get_name(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> Result<usize> {
) -> Result<()> {
// Format: [udp|tcp:]remote/local, chan:path
let mut buf = [0; 256];
let len = syscall::fpath(socket as usize, &mut buf)?;
@@ -197,7 +188,7 @@ unsafe fn inner_get_name(
);
}
Ok(0)
Ok(())
}
fn socket_kind(mut kind: c_int) -> (c_int, usize) {
@@ -214,25 +205,28 @@ fn socket_kind(mut kind: c_int) -> (c_int, usize) {
}
impl PalSocket for Sys {
unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
let stream = e(syscall::dup(socket as usize, b"listen")) as c_int;
if stream < 0 {
return -1;
unsafe fn accept(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> Result<c_int> {
let stream = syscall::dup(socket as usize, b"listen")? as c_int;
if address != ptr::null_mut() && address_len != ptr::null_mut() {
let _ = Self::getpeername(stream, address, address_len)?;
}
if address != ptr::null_mut()
&& address_len != ptr::null_mut()
&& Self::getpeername(stream, address, address_len) < 0
{
return -1;
}
stream
Ok(stream)
}
unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
bind_or_connect!(bind into, socket, address, address_len)
unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> Result<()> {
bind_or_connect!(bind into, socket, address, address_len)?;
Ok(())
}
unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
unsafe fn connect(
socket: c_int,
address: *const sockaddr,
address_len: socklen_t,
) -> Result<c_int> {
bind_or_connect!(connect into, socket, address, address_len)
}
@@ -240,41 +234,41 @@ impl PalSocket for Sys {
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> c_int {
e(inner_get_name(false, socket, address, address_len)) as c_int
) -> Result<()> {
inner_get_name(false, socket, address, address_len)
}
unsafe fn getsockname(
socket: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> c_int {
e(inner_get_name(true, socket, address, address_len)) as c_int
) -> Result<()> {
inner_get_name(true, socket, address, address_len)
}
fn getsockopt(
unsafe fn getsockopt(
socket: c_int,
level: c_int,
option_name: c_int,
option_value: *mut c_void,
option_len: *mut socklen_t,
) -> c_int {
) -> Result<()> {
match level {
SOL_SOCKET => match option_name {
SO_ERROR => {
if option_value.is_null() {
return e(Err(syscall::Error::new(syscall::EFAULT))) as c_int;
return Err(Errno(EFAULT));
}
if (option_len as usize) < mem::size_of::<c_int>() {
return e(Err(syscall::Error::new(syscall::EINVAL))) as c_int;
return Err(Errno(EINVAL));
}
let error = unsafe { &mut *(option_value as *mut c_int) };
//TODO: Socket nonblock connection error
*error = 0;
return 0;
return Ok(());
}
_ => (),
},
@@ -285,12 +279,12 @@ impl PalSocket for Sys {
"getsockopt({}, {}, {}, {:p}, {:p})",
socket, level, option_name, option_value, option_len
);
e(Err(syscall::Error::new(syscall::ENOSYS))) as c_int
Err(Errno(ENOSYS))
}
fn listen(socket: c_int, backlog: c_int) -> c_int {
fn listen(socket: c_int, backlog: c_int) -> Result<()> {
// Redox has no need to listen
0
Ok(())
}
unsafe fn recvfrom(
@@ -300,45 +294,30 @@ impl PalSocket for Sys {
flags: c_int,
address: *mut sockaddr,
address_len: *mut socklen_t,
) -> ssize_t {
) -> Result<usize> {
if flags != 0 {
ERRNO.set(syscall::EOPNOTSUPP);
return -1;
return Err(Errno(EOPNOTSUPP));
}
if address == ptr::null_mut() || address_len == ptr::null_mut() {
Self::read(socket, slice::from_raw_parts_mut(buf as *mut u8, len))
.map(|u| u as ssize_t)
.or_minus_one_errno()
} else {
let fd = e(syscall::dup(socket as usize, b"listen"));
if fd == !0 {
return -1;
}
if Self::getpeername(fd as c_int, address, address_len) < 0 {
let _ = syscall::close(fd);
return -1;
}
let fd = FdGuard::new(syscall::dup(socket as usize, b"listen")?);
Self::getpeername(*fd as c_int, address, address_len)?;
let ret = Self::read(fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len))
.map(|u| u as ssize_t)
.or_minus_one_errno();
let _ = syscall::close(fd);
ret
Self::read(*fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len))
}
}
unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t {
unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> Result<usize> {
//TODO: implement recvfrom with recvmsg
eprintln!("recvmsg not implemented on redox");
ERRNO.set(syscall::ENOSYS);
return -1;
Err(Errno(ENOSYS))
}
unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t {
unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> Result<usize> {
//TODO: implement sendto with sendmsg
eprintln!("sendmsg not implemented on redox");
ERRNO.set(syscall::ENOSYS);
return -1;
Err(Errno(ENOSYS))
}
unsafe fn sendto(
@@ -348,64 +327,45 @@ impl PalSocket for Sys {
flags: c_int,
dest_addr: *const sockaddr,
dest_len: socklen_t,
) -> ssize_t {
) -> Result<usize> {
if flags != 0 {
ERRNO.set(syscall::EOPNOTSUPP);
return -1;
return Err(Errno(EOPNOTSUPP));
}
if dest_addr == ptr::null() || dest_len == 0 {
Self::write(socket, slice::from_raw_parts(buf as *const u8, len))
.map(|u| u as ssize_t)
.or_minus_one_errno()
} else {
let fd = bind_or_connect!(connect copy, socket, dest_addr, dest_len);
let ret = Self::write(fd as c_int, slice::from_raw_parts(buf as *const u8, len))
.map(|u| u as ssize_t)
.or_minus_one_errno();
let _ = syscall::close(fd);
ret
let fd = FdGuard::new(bind_or_connect!(connect copy, socket, dest_addr, dest_len)?);
Self::write(*fd as c_int, slice::from_raw_parts(buf as *const u8, len))
}
}
fn setsockopt(
unsafe fn setsockopt(
socket: c_int,
level: c_int,
option_name: c_int,
option_value: *const c_void,
option_len: socklen_t,
) -> c_int {
let set_timeout = |timeout_name: &[u8]| -> c_int {
) -> Result<()> {
let set_timeout = |timeout_name: &[u8]| -> Result<()> {
if option_value.is_null() {
return e(Err(syscall::Error::new(syscall::EFAULT))) as c_int;
return Err(Errno(EFAULT));
}
if (option_len as usize) < mem::size_of::<timeval>() {
return e(Err(syscall::Error::new(syscall::EINVAL))) as c_int;
return Err(Errno(EINVAL));
}
let timeval = unsafe { &*(option_value as *const timeval) };
let fd = e(syscall::dup(socket as usize, timeout_name));
if fd == !0 {
return -1;
}
let fd = FdGuard::new(syscall::dup(socket as usize, timeout_name)?);
let timespec = syscall::TimeSpec {
tv_sec: timeval.tv_sec as i64,
tv_nsec: timeval.tv_usec * 1000,
};
let ret = Self::write(fd as c_int, &timespec)
.map(|u| u as ssize_t)
.or_minus_one_errno();
let _ = syscall::close(fd);
if ret >= 0 {
0
} else {
-1
}
Self::write(*fd as c_int, &timespec)?;
Ok(())
};
match level {
@@ -421,18 +381,17 @@ impl PalSocket for Sys {
"setsockopt({}, {}, {}, {:p}, {}) - unknown option",
socket, level, option_name, option_value, option_len
);
0
Ok(())
}
fn shutdown(socket: c_int, how: c_int) -> c_int {
fn shutdown(socket: c_int, how: c_int) -> Result<()> {
eprintln!("shutdown({}, {})", socket, how);
e(Err(syscall::Error::new(syscall::ENOSYS))) as c_int
Err(Errno(ENOSYS))
}
unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> Result<c_int> {
if domain != AF_INET && domain != AF_UNIX {
ERRNO.set(syscall::EAFNOSUPPORT);
return -1;
return Err(Errno(EAFNOSUPPORT));
}
// if protocol != 0 {
// ERRNO.set(syscall::EPROTONOSUPPORT);
@@ -443,47 +402,32 @@ impl PalSocket for Sys {
// The tcp: and udp: schemes allow using no path,
// and later specifying one using `dup`.
match (domain, kind) {
(AF_INET, SOCK_STREAM) => e(syscall::open("/scheme/tcp", flags)) as c_int,
(AF_INET, SOCK_DGRAM) => e(syscall::open("/scheme/udp", flags)) as c_int,
(AF_UNIX, SOCK_STREAM) => e(syscall::open("/scheme/chan", flags | O_CREAT)) as c_int,
_ => {
ERRNO.set(syscall::EPROTONOSUPPORT);
-1
}
}
Ok(match (domain, kind) {
(AF_INET, SOCK_STREAM) => syscall::open("/scheme/tcp", flags)? as c_int,
(AF_INET, SOCK_DGRAM) => syscall::open("/scheme/udp", flags)? as c_int,
(AF_UNIX, SOCK_STREAM) => syscall::open("/scheme/chan", flags | O_CREAT)? as c_int,
_ => return Err(Errno(EPROTONOSUPPORT)),
})
}
fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> c_int {
fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> Result<()> {
let (kind, flags) = socket_kind(kind);
match (domain, kind) {
(AF_UNIX, SOCK_STREAM) => {
let listener = e(syscall::open("/scheme/chan", flags | O_CREAT));
if listener == !0 {
return -1;
}
let listener = FdGuard::new(syscall::open("/scheme/chan", flags | O_CREAT)?);
// For now, chan: lets connects be instant, and instead blocks
// on any I/O performed. So we don't need to mark this as
// nonblocking.
let fd0 = e(syscall::dup(listener, b"connect"));
if fd0 == !0 {
let _ = syscall::close(listener);
return -1;
}
let mut fd0 = FdGuard::new(syscall::dup(*listener, b"connect")?);
let fd1 = e(syscall::dup(listener, b"listen"));
if fd1 == !0 {
let _ = syscall::close(fd0);
let _ = syscall::close(listener);
return -1;
}
let mut fd1 = FdGuard::new(syscall::dup(*listener, b"listen")?);
sv[0] = fd0 as c_int;
sv[1] = fd1 as c_int;
0
sv[0] = fd0.take() as c_int;
sv[1] = fd1.take() as c_int;
Ok(())
}
_ => unsafe {
eprintln!(
@@ -493,8 +437,7 @@ impl PalSocket for Sys {
protocol,
sv.as_mut_ptr()
);
ERRNO.set(syscall::EPROTONOSUPPORT);
-1
Err(Errno(EPROTONOSUPPORT))
},
}
}