diff --git a/src/crystal/system.cr b/src/crystal/system.cr new file mode 100644 index 000000000000..212f28140f25 --- /dev/null +++ b/src/crystal/system.cr @@ -0,0 +1,20 @@ +module Crystal + # :nodoc + module System + # Returns the hostname + # def self.hostname + + # Returns the number of logical processors available to the system. + # + # def self.cpu_count + end +end + +require "./system/unix/hostname" + +{% if flag?(:freebsd) || flag?(:openbsd) %} + require "./system/unix/sysctl_cpucount" +{% else %} + # TODO: restrict on flag?(:unix) after crystal > 0.22.0 is released + require "./system/unix/sysconf_cpucount" +{% end %} diff --git a/src/crystal/system/unix/hostname.cr b/src/crystal/system/unix/hostname.cr new file mode 100644 index 000000000000..e803ef514185 --- /dev/null +++ b/src/crystal/system/unix/hostname.cr @@ -0,0 +1,13 @@ +require "c/unistd" + +module Crystal::System + def self.hostname + String.new(255) do |buffer| + unless LibC.gethostname(buffer, LibC::SizeT.new(255)) == 0 + raise Errno.new("Could not get hostname") + end + len = LibC.strlen(buffer) + {len, len} + end + end +end diff --git a/src/crystal/system/unix/sysconf_cpucount.cr b/src/crystal/system/unix/sysconf_cpucount.cr new file mode 100644 index 000000000000..9c0550928092 --- /dev/null +++ b/src/crystal/system/unix/sysconf_cpucount.cr @@ -0,0 +1,9 @@ +{% skip_file if flag?(:openbsd) || flag?(:freebsd) %} + +require "c/unistd" + +module Crystal::System + def self.cpu_count + LibC.sysconf(LibC::SC_NPROCESSORS_ONLN) + end +end diff --git a/src/crystal/system/unix/sysctl_cpucount.cr b/src/crystal/system/unix/sysctl_cpucount.cr new file mode 100644 index 000000000000..ec3a55852fe8 --- /dev/null +++ b/src/crystal/system/unix/sysctl_cpucount.cr @@ -0,0 +1,17 @@ +{% skip_file unless flag?(:openbsd) || flag?(:freebsd) %} + +require "c/sysctl" + +module Crystal::System + def self.cpu_count + mib = Int32[LibC::CTL_HW, LibC::HW_NCPU] + ncpus = 0 + size = sizeof(Int32).to_u64 + + if LibC.sysctl(mib, 2, pointerof(ncpus), pointerof(size), nil, 0) == 0 + ncpus + else + -1 + end + end +end diff --git a/src/lib_c/amd64-unknown-openbsd/c/sysctl.cr b/src/lib_c/amd64-unknown-openbsd/c/sysctl.cr new file mode 100644 index 000000000000..95a9a06fa6cc --- /dev/null +++ b/src/lib_c/amd64-unknown-openbsd/c/sysctl.cr @@ -0,0 +1,6 @@ +lib LibC + CTL_HW = 6 + HW_NCPU = 3 + + fun sysctl(name : Int*, namelen : UInt, oldp : Void*, oldlenp : SizeT*, newp : Void*, newlen : SizeT) : Int +end diff --git a/src/lib_c/amd64-unknown-openbsd/c/unistd.cr b/src/lib_c/amd64-unknown-openbsd/c/unistd.cr index 7ac56b178ccf..b01f56b68ab7 100644 --- a/src/lib_c/amd64-unknown-openbsd/c/unistd.cr +++ b/src/lib_c/amd64-unknown-openbsd/c/unistd.cr @@ -2,12 +2,11 @@ require "./sys/types" require "./stdint" lib LibC - F_OK = 0 - R_OK = 0x04 - W_OK = 0x02 - X_OK = 0x01 - SC_CLK_TCK = 3 - SC_NPROCESSORS_ONLN = 58 + F_OK = 0 + R_OK = 0x04 + W_OK = 0x02 + X_OK = 0x01 + SC_CLK_TCK = 3 fun access(x0 : Char*, x1 : Int) : Int fun chdir(x0 : Char*) : Int diff --git a/src/lib_c/x86_64-portbld-freebsd/c/sysctl.cr b/src/lib_c/x86_64-portbld-freebsd/c/sysctl.cr new file mode 100644 index 000000000000..1fb8d9e2aaf6 --- /dev/null +++ b/src/lib_c/x86_64-portbld-freebsd/c/sysctl.cr @@ -0,0 +1,10 @@ +lib LibC + CTL_HW = 6 + CTL_KERN = 1 + HW_NCPU = 3 + KERN_PROC = 14 + KERN_PROC_PATHNAME = 12 + PATH_MAX = 1024 + + fun sysctl(name : Int*, namelen : UInt, oldp : Void*, oldlenp : SizeT*, newp : Void*, newlen : SizeT) : Int +end diff --git a/src/lib_c/x86_64-portbld-freebsd/c/unistd.cr b/src/lib_c/x86_64-portbld-freebsd/c/unistd.cr index 591a4e6aabd9..def065442a82 100644 --- a/src/lib_c/x86_64-portbld-freebsd/c/unistd.cr +++ b/src/lib_c/x86_64-portbld-freebsd/c/unistd.cr @@ -2,12 +2,11 @@ require "./sys/types" require "./stdint" lib LibC - F_OK = 0 - R_OK = 0x04 - W_OK = 0x02 - X_OK = 0x01 - SC_CLK_TCK = 3 - SC_NPROCESSORS_ONLN = 58 + F_OK = 0 + R_OK = 0x04 + W_OK = 0x02 + X_OK = 0x01 + SC_CLK_TCK = 3 fun access(x0 : Char*, x1 : Int) : Int fun chdir(x0 : Char*) : Int diff --git a/src/process/executable_path.cr b/src/process/executable_path.cr index 9952bc0f569a..5c8d6e140c45 100644 --- a/src/process/executable_path.cr +++ b/src/process/executable_path.cr @@ -72,13 +72,7 @@ end end {% elsif flag?(:freebsd) %} - lib LibC - PATH_MAX = 1024 - CTL_KERN = 1 - KERN_PROC = 14 - KERN_PROC_PATHNAME = 12 - fun sysctl(name : Int*, namelen : UInt, oldp : Void*, oldlenp : SizeT*, newp : Void*, newlen : SizeT) : Int - end + require "c/sysctl" class Process private def self.executable_path_impl diff --git a/src/system.cr b/src/system.cr index f87c6482b5fa..6746651caeb0 100644 --- a/src/system.cr +++ b/src/system.cr @@ -1,22 +1,17 @@ -require "c/unistd" +require "crystal/system" module System # Returns the hostname. # - # NOTE: Maximum of 253 characters are allowed, with 2 bytes reserved for storage. + # NOTE: Maximum of 253 characters are allowed, with 2 bytes reserved for + # storage. # In practice, many platforms will disallow anything longer than 63 characters. # # ``` # System.hostname # => "host.example.org" # ``` def self.hostname - String.new(255) do |buffer| - unless LibC.gethostname(buffer, LibC::SizeT.new(255)) == 0 - raise Errno.new("Could not get hostname") - end - len = LibC.strlen(buffer) - {len, len} - end + Crystal::System.hostname end # Returns the number of logical processors available to the system. @@ -25,6 +20,6 @@ module System # System.cpu_count # => 4 # ``` def self.cpu_count - LibC.sysconf(LibC::SC_NPROCESSORS_ONLN) + Crystal::System.cpu_count end end