Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/crystal/event_loop/iocp.cr
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ class Crystal::EventLoop::IOCP < Crystal::EventLoop
# AcceptEx does not automatically set the socket options on the accepted
# socket to match those of the listening socket, we need to ask for that
# explicitly with SO_UPDATE_ACCEPT_CONTEXT
socket.system_setsockopt client_handle, LibC::SO_UPDATE_ACCEPT_CONTEXT, socket.fd
System::Socket.setsockopt client_handle, LibC::SO_UPDATE_ACCEPT_CONTEXT, socket.fd

true
else
Expand Down
8 changes: 5 additions & 3 deletions src/crystal/system/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ module Crystal::System::Socket

# private def system_linger=(val)

# private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET, &)
# private def system_getsockopt(optname, optval, level = LibC::SOL_SOCKET, &)

# private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
# private def system_getsockopt(optname, optval, level = LibC::SOL_SOCKET)

# private def system_setsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
# private def system_setsockopt(optname, optval, level = LibC::SOL_SOCKET)

# private def system_blocking?

Expand All @@ -70,6 +70,8 @@ module Crystal::System::Socket

# private def system_close_on_exec=(arg : Bool)

# private def system_fcntl(cmd, arg = 0)

# def self.fcntl(fd, cmd, arg = 0)

# def self.socketpair(type : ::Socket::Type, protocol : ::Socket::Protocol, blocking : Bool) : {Handle, Handle}
Expand Down
26 changes: 15 additions & 11 deletions src/crystal/system/unix/file_descriptor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module Crystal::System::FileDescriptor
STDERR_HANDLE = 2

private def system_blocking?
flags = fcntl(LibC::F_GETFL)
flags = system_fcntl(LibC::F_GETFL)
!flags.bits_set? LibC::O_NONBLOCK
end

Expand Down Expand Up @@ -56,12 +56,12 @@ module Crystal::System::FileDescriptor
end

private def system_close_on_exec?
flags = fcntl(LibC::F_GETFD)
flags = system_fcntl(LibC::F_GETFD)
flags.bits_set? LibC::FD_CLOEXEC
end

private def system_close_on_exec=(arg : Bool)
fcntl(LibC::F_SETFD, arg ? LibC::FD_CLOEXEC : 0)
system_fcntl(LibC::F_SETFD, arg ? LibC::FD_CLOEXEC : 0)
arg
end

Expand All @@ -75,6 +75,10 @@ module Crystal::System::FileDescriptor
r
end

private def system_fcntl(cmd, arg = 0)
FileDescriptor.fcntl(fd, cmd, arg)
end

def self.system_info(fd)
stat = uninitialized LibC::Stat
ret = File.fstat(fd, pointerof(stat))
Expand Down Expand Up @@ -284,10 +288,10 @@ module Crystal::System::FileDescriptor
end

private def system_echo(enable : Bool, mode = nil)
new_mode = mode || FileDescriptor.tcgetattr(fd)
new_mode = mode || system_tcgetattr
flags = LibC::ECHO | LibC::ECHOE | LibC::ECHOK | LibC::ECHONL
new_mode.c_lflag = enable ? (new_mode.c_lflag | flags) : (new_mode.c_lflag & ~flags)
if FileDescriptor.tcsetattr(fd, LibC::TCSANOW, pointerof(new_mode)) != 0
if system_tcsetattr(LibC::TCSANOW, pointerof(new_mode)) != 0
raise IO::Error.from_errno("tcsetattr")
end
end
Expand All @@ -300,15 +304,15 @@ module Crystal::System::FileDescriptor
end

private def system_raw(enable : Bool, mode = nil)
new_mode = mode || FileDescriptor.tcgetattr(fd)
new_mode = mode || system_tcgetattr
if enable
new_mode = FileDescriptor.cfmakeraw(new_mode)
else
new_mode.c_iflag |= LibC::BRKINT | LibC::ISTRIP | LibC::ICRNL | LibC::IXON
new_mode.c_oflag |= LibC::OPOST
new_mode.c_lflag |= LibC::ECHO | LibC::ECHOE | LibC::ECHOK | LibC::ECHONL | LibC::ICANON | LibC::ISIG | LibC::IEXTEN
end
if FileDescriptor.tcsetattr(fd, LibC::TCSANOW, pointerof(new_mode)) != 0
if system_tcsetattr(LibC::TCSANOW, pointerof(new_mode)) != 0
raise IO::Error.from_errno("tcsetattr")
end
end
Expand All @@ -322,16 +326,16 @@ module Crystal::System::FileDescriptor

@[AlwaysInline]
private def system_console_mode(&)
before = FileDescriptor.tcgetattr(fd)
before = system_tcgetattr
begin
yield before
ensure
FileDescriptor.tcsetattr(fd, LibC::TCSANOW, pointerof(before))
system_tcsetattr(LibC::TCSANOW, pointerof(before))
end
end

@[AlwaysInline]
def self.tcgetattr(fd)
private def system_tcgetattr
termios = uninitialized LibC::Termios
{% if LibC.has_method?(:tcgetattr) %}
ret = LibC.tcgetattr(fd, pointerof(termios))
Expand All @@ -344,7 +348,7 @@ module Crystal::System::FileDescriptor
end

@[AlwaysInline]
def self.tcsetattr(fd, optional_actions, termios_p)
private def system_tcsetattr(optional_actions, termios_p)
{% if LibC.has_method?(:tcsetattr) %}
LibC.tcsetattr(fd, optional_actions, termios_p)
{% else %}
Expand Down
48 changes: 22 additions & 26 deletions src/crystal/system/unix/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ module Crystal::System::Socket
Process.lock_read do
fd = LibC.socket(family, type, protocol)
raise ::Socket::Error.from_errno("Failed to create socket") if fd == -1
Socket.fcntl(fd, LibC::F_SETFD, LibC::FD_CLOEXEC)
Socket.fcntl(fd, LibC::F_SETFL, Socket.fcntl(fd, LibC::F_GETFL) | LibC::O_NONBLOCK) unless blocking
FileDescriptor.fcntl(fd, LibC::F_SETFD, LibC::FD_CLOEXEC)
FileDescriptor.fcntl(fd, LibC::F_SETFL, FileDescriptor.fcntl(fd, LibC::F_GETFL) | LibC::O_NONBLOCK) unless blocking
fd
end
{% end %}
Expand Down Expand Up @@ -84,7 +84,7 @@ module Crystal::System::Socket
end

private def system_reuse_port? : Bool
system_getsockopt(fd, LibC::SO_REUSEPORT, 0) do |value|
system_getsockopt(LibC::SO_REUSEPORT, 0) do |value|
return value != 0
end

Expand Down Expand Up @@ -135,19 +135,19 @@ module Crystal::System::Socket
val
end

private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET, &)
private def system_getsockopt(optname, optval, level = LibC::SOL_SOCKET, &)
optsize = LibC::SocklenT.new(sizeof(typeof(optval)))
ret = LibC.getsockopt(fd, level, optname, pointerof(optval), pointerof(optsize))
yield optval if ret == 0
ret
end

private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
system_getsockopt(fd, optname, optval, level) { |value| return value }
private def system_getsockopt(optname, optval, level = LibC::SOL_SOCKET)
system_getsockopt(optname, optval, level) { |value| return value }
raise ::Socket::Error.from_errno("getsockopt #{optname}")
end

private def system_setsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
private def system_setsockopt(optname, optval, level = LibC::SOL_SOCKET)
optsize = LibC::SocklenT.new(sizeof(typeof(optval)))

ret = LibC.setsockopt(fd, level, optname, pointerof(optval), optsize)
Expand All @@ -156,41 +156,37 @@ module Crystal::System::Socket
end

private def system_blocking?
Socket.get_blocking(fd)
FileDescriptor.get_blocking(fd)
end

private def system_blocking=(value)
Socket.set_blocking(fd, value)
FileDescriptor.set_blocking(fd, value)
end

def self.get_blocking(fd : Handle)
fcntl(fd, LibC::F_GETFL) & LibC::O_NONBLOCK == 0
FileDescriptor.get_blocking(fd)
end

def self.set_blocking(fd : Handle, value : Bool)
flags = fcntl(fd, LibC::F_GETFL)
if value
flags &= ~LibC::O_NONBLOCK
else
flags |= LibC::O_NONBLOCK
end
fcntl(fd, LibC::F_SETFL, flags)
FileDescriptor.set_blocking(fd, value)
end

private def system_close_on_exec?
flags = fcntl(LibC::F_GETFD)
flags = system_fcntl(LibC::F_GETFD)
(flags & LibC::FD_CLOEXEC) == LibC::FD_CLOEXEC
end

private def system_close_on_exec=(arg : Bool)
fcntl(LibC::F_SETFD, arg ? LibC::FD_CLOEXEC : 0)
system_fcntl(LibC::F_SETFD, arg ? LibC::FD_CLOEXEC : 0)
arg
end

def self.fcntl(fd, cmd, arg = 0)
r = LibC.fcntl fd, cmd, arg
raise ::Socket::Error.from_errno("fcntl() failed") if r == -1
r
FileDescriptor.fcntl(fd, cmd, arg)
end

private def system_fcntl(cmd, arg = 0)
FileDescriptor.fcntl(fd, cmd, arg)
end

def self.socketpair(type : ::Socket::Type, protocol : ::Socket::Protocol, blocking : Bool) : {Handle, Handle}
Expand All @@ -207,11 +203,11 @@ module Crystal::System::Socket
if LibC.socketpair(::Socket::Family::UNIX, type, protocol, fds) == -1
raise ::Socket::Error.new("socketpair() failed")
end
fcntl(fds[0], LibC::F_SETFD, LibC::FD_CLOEXEC)
fcntl(fds[1], LibC::F_SETFD, LibC::FD_CLOEXEC)
FileDescriptor.fcntl(fds[0], LibC::F_SETFD, LibC::FD_CLOEXEC)
FileDescriptor.fcntl(fds[1], LibC::F_SETFD, LibC::FD_CLOEXEC)
unless blocking
fcntl(fds[0], LibC::F_SETFL, fcntl(fds[0], LibC::F_GETFL) | LibC::O_NONBLOCK)
fcntl(fds[1], LibC::F_SETFL, fcntl(fds[1], LibC::F_GETFL) | LibC::O_NONBLOCK)
FileDescriptor.fcntl(fds[0], LibC::F_SETFL, FileDescriptor.fcntl(fds[0], LibC::F_GETFL) | LibC::O_NONBLOCK)
FileDescriptor.fcntl(fds[1], LibC::F_SETFL, FileDescriptor.fcntl(fds[1], LibC::F_GETFL) | LibC::O_NONBLOCK)
end
end
{% end %}
Expand Down
8 changes: 5 additions & 3 deletions src/crystal/system/wasi/file_descriptor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ module Crystal::System::FileDescriptor
end

def self.fcntl(fd, cmd, arg = 0)
r = LibC.fcntl(fd, cmd, arg)
raise IO::Error.from_errno("fcntl() failed") if r == -1
r
FileDescriptor.fcntl(fd, cmd, arg)
end

private def system_fcntl(cmd, arg = 0)
FileDescriptor.fcntl(fd, cmd, arg)
end

def self.get_blocking(fd : Handle)
Expand Down
10 changes: 7 additions & 3 deletions src/crystal/system/wasi/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ module Crystal::System::Socket
raise NotImplementedError.new "Crystal::System::Socket#system_linge="
end

private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET, &)
private def system_getsockopt(optname, optval, level = LibC::SOL_SOCKET, &)
raise NotImplementedError.new "Crystal::System::Socket#system_getsockopt"
end

private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
private def system_getsockopt(optname, optval, level = LibC::SOL_SOCKET)
raise NotImplementedError.new "Crystal::System::Socket#system_getsockopt"
end

private def system_setsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
private def system_setsockopt(optname, optval, level = LibC::SOL_SOCKET)
raise NotImplementedError.new "Crystal::System::Socket#system_setsockopt"
end

Expand Down Expand Up @@ -139,6 +139,10 @@ module Crystal::System::Socket
r
end

private def system_fcntl(cmd, arg = 0)
FileDescriptor.system_fcntl(fd, cmd, arg)
end

private def system_tty?
LibC.isatty(fd) == 1
end
Expand Down
4 changes: 4 additions & 0 deletions src/crystal/system/win32/file_descriptor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ module Crystal::System::FileDescriptor
raise NotImplementedError.new "Crystal::System::FileDescriptor.fcntl"
end

private def system_fcntl(cmd, arg = 0)
raise NotImplementedError.new "Crystal::System::FileDescriptor#system_fcntl"
end

protected def windows_handle
LibC::HANDLE.new(fd)
end
Expand Down
30 changes: 21 additions & 9 deletions src/crystal/system/win32/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ module Crystal::System::Socket
@blocking = blocking unless blocking.nil?

unless @family.unix?
system_getsockopt(handle, LibC::SO_REUSEADDR, 0) do |value|
Socket.getsockopt(handle, LibC::SO_REUSEADDR, 0) do |value|
if value == 0
system_setsockopt(handle, LibC::SO_EXCLUSIVEADDRUSE, 1)
Socket.setsockopt(handle, LibC::SO_EXCLUSIVEADDRUSE, 1)
end
end
end
Expand Down Expand Up @@ -310,20 +310,28 @@ module Crystal::System::Socket
val
end

private def system_getsockopt(handle, optname, optval, level = LibC::SOL_SOCKET, &)
private def system_getsockopt(optname, optval, level = LibC::SOL_SOCKET, &)
Socket.getsockopt(fd, optname, optval, level) { |value| yield value }
end

private def system_getsockopt(optname, optval, level = LibC::SOL_SOCKET)
Socket.getsockopt(fd, optname, optval, level) { |value| return value }
raise ::Socket::Error.from_wsa_error("getsockopt #{optname}")
end

private def system_setsockopt(optname, optval, level = LibC::SOL_SOCKET)
Socket.setsockopt(fd, optname, optval, level)
end

protected def self.getsockopt(handle, optname, optval, level = LibC::SOL_SOCKET, &)
optsize = sizeof(typeof(optval))
ret = LibC.getsockopt(handle, level, optname, pointerof(optval).as(UInt8*), pointerof(optsize))
yield optval if ret == 0
ret
end

private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
system_getsockopt(fd, optname, optval, level) { |value| return value }
raise ::Socket::Error.from_wsa_error("getsockopt #{optname}")
end

# :nodoc:
def system_setsockopt(handle, optname, optval, level = LibC::SOL_SOCKET)
protected def self.setsockopt(handle, optname, optval, level = LibC::SOL_SOCKET)
optsize = sizeof(typeof(optval))

ret = LibC.setsockopt(handle, level, optname, pointerof(optval).as(UInt8*), optsize)
Expand Down Expand Up @@ -369,6 +377,10 @@ module Crystal::System::Socket
raise NotImplementedError.new "Crystal::System::Socket.fcntl"
end

private def system_fcntl(cmd, arg = 0)
raise NotImplementedError.new "Crystal::System::Socket#system_fcntl"
end

private def system_tty?
LibC.GetConsoleMode(LibC::HANDLE.new(fd), out _) != 0
end
Expand Down
6 changes: 3 additions & 3 deletions src/io/console.cr
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class IO::FileDescriptor < IO
@[Deprecated]
macro noecho_from_tc_mode!
mode.c_lflag &= ~(Termios::LocalMode.flags(ECHO, ECHOE, ECHOK, ECHONL).value)
Crystal::System::FileDescriptor.tcsetattr(fd, Termios::LineControl::TCSANOW, pointerof(mode))
system_tcsetattr(Termios::LineControl::TCSANOW, pointerof(mode))
end

@[Deprecated]
Expand All @@ -109,12 +109,12 @@ class IO::FileDescriptor < IO
Termios::LocalMode::ICANON |
Termios::LocalMode::ISIG |
Termios::LocalMode::IEXTEN).value
Crystal::System::FileDescriptor.tcsetattr(fd, Termios::LineControl::TCSANOW, pointerof(mode))
system_tcsetattr(Termios::LineControl::TCSANOW, pointerof(mode))
end

@[Deprecated]
macro raw_from_tc_mode!
Crystal::System::FileDescriptor.cfmakeraw(pointerof(mode))
Crystal::System::FileDescriptor.tcsetattr(fd, Termios::LineControl::TCSANOW, pointerof(mode))
system_tcsetattr(Termios::LineControl::TCSANOW, pointerof(mode))
end
end
2 changes: 1 addition & 1 deletion src/io/file_descriptor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class IO::FileDescriptor < IO
end

def fcntl(cmd : Int, arg : Int = 0) : Int
Crystal::System::FileDescriptor.fcntl(fd, cmd, arg)
system_fcntl(cmd, arg)
end

# Returns a `File::Info` object for this file descriptor, or raises
Expand Down
Loading