Skip to content
21 changes: 21 additions & 0 deletions spec/std/system_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,25 @@ describe System do
cpu_count.should eq(shell_cpus)
end
end

pending_win32 describe: "file_descriptor_limit" do
it "returns the current file descriptor limit" do
hard_fd_limit = `ulimit -Hn`.strip
$?.success?.should be_true
soft_fd_limit = `ulimit -Sn`.strip
$?.success?.should be_true

soft_limit, hard_limit = System.file_descriptor_limit
hard_limit.to_s.should eq hard_fd_limit
soft_limit.to_s.should eq soft_fd_limit
end

it "can set the limit" do
System.file_descriptor_limit = 512

soft_fd_limit = `ulimit -Sn`.strip
$?.success?.should be_true
soft_fd_limit.should eq "512"
end
end
end
1 change: 1 addition & 0 deletions src/crystal/system.cr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ end

{% if flag?(:unix) %}
require "./system/unix/hostname"
require "./system/unix/file_descriptor_limit"

{% if flag?(:bsd) %}
require "./system/unix/sysctl_cpucount"
Expand Down
18 changes: 18 additions & 0 deletions src/crystal/system/unix/file_descriptor_limit.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Crystal::System
def self.file_descriptor_limit : Tuple(Int32, Int32)
rlimit = uninitialized LibC::Rlimit
if LibC.getrlimit(LibC::RLIMIT_NOFILE, pointerof(rlimit)) != 0
raise RuntimeError.from_errno("Could not get rlimit")
end
{rlimit.rlim_cur.to_i32, rlimit.rlim_max.to_i32}
end

def self.file_descriptor_limit=(limit : Int) : Nil
rlimit = LibC::Rlimit.new
rlimit.rlim_cur = limit
rlimit.rlim_max = limit
if LibC.setrlimit(LibC::RLIMIT_NOFILE, pointerof(rlimit)) != 0
raise RuntimeError.from_errno("Could not set rlimit")
end
end
end
9 changes: 9 additions & 0 deletions src/crystal/system/win32/file_descriptor_limit.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Crystal::System
def self.file_descriptor_limit : Tuple(Int32, Int32)
raise NotImplementedError.new
end

def self.file_descriptor_limit=(limit : Int) : Nil
raise NotImplementedError.new
end
end
4 changes: 3 additions & 1 deletion src/lib_c/aarch64-darwin/c/sys/resource.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ lib LibC
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/aarch64-linux-gnu/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/aarch64-linux-musl/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/arm-linux-gnueabihf/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/i386-linux-gnu/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/i386-linux-musl/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
4 changes: 3 additions & 1 deletion src/lib_c/x86_64-darwin/c/sys/resource.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ lib LibC
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/x86_64-dragonfly/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 8

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/x86_64-freebsd/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 8

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/x86_64-linux-gnu/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/x86_64-linux-musl/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 7

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/x86_64-netbsd/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 8

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
13 changes: 13 additions & 0 deletions src/lib_c/x86_64-openbsd/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int
fun setrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3
RLIMIT_NOFILE = 8

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
18 changes: 18 additions & 0 deletions src/system.cr
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,22 @@ module System
def self.cpu_count
Crystal::System.cpu_count
end

# Returns the soft and hard file descriptor limits for the current process
#
# ```
# System.file_descriptor_limit # => { 1024, 524288 }
# ```
def self.file_descriptor_limit
Crystal::System.file_descriptor_limit
end

# Sets the soft file descriptor limits for the current process
#
# ```
# System.file_descriptor_limit = 4096
# ```
def self.file_descriptor_limit=(limit : UInt32)
Crystal::System.file_descriptor_limit = limit
end
end