Skip to content

Commit

Permalink
net.unix: update the module to make it compatible with windows and co…
Browse files Browse the repository at this point in the history
…routines (#19831)
  • Loading branch information
Casper64 authored Nov 11, 2023
1 parent a176021 commit c0eeb85
Show file tree
Hide file tree
Showing 9 changed files with 576 additions and 357 deletions.
2 changes: 0 additions & 2 deletions cmd/tools/vtest-self.v
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,6 @@ const (
'vlib/v/tests/orm_joined_tables_select_test.v',
'vlib/v/tests/orm_handle_error_for_select_from_not_created_table_test.v',
'vlib/net/websocket/ws_test.v',
'vlib/net/unix/unix_test.v',
'vlib/net/unix/use_net_and_net_unix_together_test.v',
'vlib/net/websocket/websocket_test.v',
'vlib/net/openssl/openssl_compiles_test.c.v',
'vlib/net/http/request_test.v',
Expand Down
6 changes: 4 additions & 2 deletions vlib/net/net_nix.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module net

const is_windows = false

fn error_code() int {
pub fn error_code() int {
return C.errno
}

Expand All @@ -24,7 +24,9 @@ pub const (
msg_nosignal = 0x4000
)

const (
pub const (
error_ewouldblock = C.EWOULDBLOCK
error_einprogress = C.EINPROGRESS
)

fn C.unlink(&char) int
4 changes: 2 additions & 2 deletions vlib/net/net_windows.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ pub fn wsa_error(code int) WsaError {
return unsafe { WsaError(code) }
}

const (
pub const (
error_ewouldblock = WsaError.wsaewouldblock
error_einprogress = WsaError.wsaeinprogress
)
Expand All @@ -757,7 +757,7 @@ const (
)

// Error code returns the last socket error
fn error_code() int {
pub fn error_code() int {
return C.WSAGetLastError()
}

Expand Down
2 changes: 1 addition & 1 deletion vlib/net/socket_options.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub enum SocketOption {
ipv6_only = C.IPV6_V6ONLY
}

const (
pub const (
opts_bool = [SocketOption.broadcast, .debug, .dont_route, .error, .keep_alive, .oob_inline]
opts_int = [
.receive_buf_size,
Expand Down
15 changes: 6 additions & 9 deletions vlib/net/unix/aasocket.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ import net

const use_net = net.no_timeout

// 104 for macos, 108 for linux => use the minimum
const max_sun_path = 104
const max_sun_path = $if windows {
256
} $else {
// 104 for macos, 108 for linux => use the minimum
104
}

// Select represents a select operation
enum Select {
read
write
except
}

// SocketType are the available sockets
// enum SocketType {
// dgram = C.SOCK_DGRAM
// stream = C.SOCK_STREAM
// seqpacket = C.SOCK_SEQPACKET
// }
100 changes: 53 additions & 47 deletions vlib/net/unix/common.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@ module unix
import time
import net

const error_ewouldblock = C.EWOULDBLOCK

fn C.SUN_LEN(ptr &C.sockaddr_un) int
const (
// no_deadline should be given to functions when no deadline is wanted (i.e. all functions
// return instantly)
no_deadline = time.Time{
unix: 0
}
// no_timeout should be given to functions when no timeout is wanted (i.e. all functions
// return instantly)
no_timeout = time.Duration(0)
// infinite_timeout should be given to functions when an infinite_timeout is wanted (i.e. functions
// only ever return with data)
infinite_timeout = time.infinite
)

fn C.strncpy(&char, &char, int)

// close a socket, given its file descriptor `handle`.
pub fn close(handle int) ! {
net.close(handle)!
}

// shutdown shutsdown a socket, given its file descriptor `handle`.
// By default it shuts it down in both directions, both for reading
// and for writing. You can change that using `net.shutdown(handle, how: .read)`
Expand All @@ -17,11 +32,6 @@ pub fn shutdown(handle int, config net.ShutdownConfig) int {
return net.shutdown(handle, config)
}

// close a socket, given its file descriptor `handle`.
pub fn close(handle int) ! {
net.close(handle)!
}

// Select waits for an io operation (specified by parameter `test`) to be available
fn @select(handle int, test Select, timeout time.Duration) !bool {
set := C.fd_set{}
Expand Down Expand Up @@ -60,32 +70,48 @@ fn @select(handle int, test Select, timeout time.Duration) !bool {
return C.FD_ISSET(handle, &set) != 0
}

// wait_for_common wraps the common wait code
fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ! {
if deadline.unix == 0 {
// do not accept negative timeout
if timeout < 0 {
return net.err_timed_out
}
ready := @select(handle, test, timeout)!
if ready {
return
[inline]
fn select_deadline(handle int, test Select, deadline time.Time) !bool {
// if we have a 0 deadline here then the timeout that was passed was infinite...
infinite := deadline.unix_time() == 0
for infinite || time.now() <= deadline {
timeout := if infinite { net.infinite_timeout } else { deadline - time.now() }
ready := @select(handle, test, timeout) or {
if err.code() == 4 {
// Spurious wakeup from signal, keep waiting
continue
}

// NOT a spurious wakeup
return err
}
return net.err_timed_out

return ready
}
// Convert the deadline into a timeout
// and use that
d_timeout := deadline.unix - time.now().unix
if d_timeout < 0 {
// deadline is in the past so this has already
// timed out
return net.err_timed_out

// Deadline elapsed
return net.err_timed_out
}

// wait_for_common wraps the common wait code
fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ! {
// Convert timeouts to deadlines
real_deadline := if timeout == net.infinite_timeout {
time.unix(0)
} else if timeout <= 0 {
// No timeout set, so assume deadline
deadline
} else {
// timeout
time.now().add(timeout)
}

ready := @select(handle, test, d_timeout)!
ready := select_deadline(handle, test, real_deadline)!

if ready {
return
}

return net.err_timed_out
}

Expand All @@ -99,26 +125,6 @@ fn wait_for_read(handle int, deadline time.Time, timeout time.Duration) ! {
return wait_for_common(handle, deadline, timeout, .read)
}

// no_deadline should be given to functions when no deadline is wanted (i.e. all functions
// return instantly)
const (
no_deadline = time.Time{
unix: 0
}
)

// no_timeout should be given to functions when no timeout is wanted (i.e. all functions
// return instantly)
const (
no_timeout = time.Duration(0)
)

// infinite_timeout should be given to functions when an infinite_timeout is wanted (i.e. functions
// only ever return with data)
const (
infinite_timeout = time.infinite
)

[inline]
fn wrap_read_result(result int) !int {
if result != 0 {
Expand Down
Loading

0 comments on commit c0eeb85

Please sign in to comment.