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:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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
@@ -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"]
|
||||
|
||||
@@ -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
@@ -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<()>;
|
||||
}
|
||||
|
||||
@@ -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<()> {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,6 +1,6 @@
|
||||
use super::{
|
||||
super::{types::*, Pal, PalSignal},
|
||||
e, Sys,
|
||||
Sys,
|
||||
};
|
||||
use crate::{
|
||||
error::{Errno, Result},
|
||||
|
||||
+83
-140
@@ -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, ×pec)
|
||||
.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, ×pec)?;
|
||||
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))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user