diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e88f013 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Keenan Nemetz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..afc8705 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Ulimit + +A pure Go library for managing resource limits. + +## Usage + +```go +import "github.com/nasdf/ulimit" +``` + +### Set limits + +```go +err := ulimit.SetRlimit(2048) +``` + +### Get limits + +```go +soft, hard, err := ulimit.GetRlimit() +``` + +## License + +MIT \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a86fb85 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/nasdf/ulimit + +go 1.14 + +require golang.org/x/sys v0.0.0-20210123111255-9b0068b26619 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a92db54 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20210123111255-9b0068b26619 h1:yLLDsUUPDliIQpKl7BjVb1igwngIMH2GBjo1VpwLTE0= +golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/ulimit.go b/ulimit.go new file mode 100644 index 0000000..bc116c3 --- /dev/null +++ b/ulimit.go @@ -0,0 +1,30 @@ +// Package ulimit contains methods for setting resource limits. +package ulimit + +// GetRlimit returns the soft and hard resource limits. +func GetRlimit() (uint64, uint64, error) { + return getRlimit() +} + +// SetRlimit attempts to set the soft and hard resource limits. +// If the hard limit fails to update only the soft limit is set. +func SetRlimit(target uint64) error { + soft, hard, err := getRlimit() + if err != nil { + return err + } + + if target <= soft { + return nil + } + + if err = setRlimit(target, target); err == nil { + return nil + } + + if target > hard { + target = hard + } + + return setRlimit(target, hard) +} diff --git a/ulimit_test.go b/ulimit_test.go new file mode 100644 index 0000000..87adf9d --- /dev/null +++ b/ulimit_test.go @@ -0,0 +1,40 @@ +package ulimit + +import ( + "testing" +) + +func TestSetRlimit(t *testing.T) { + const target = uint64(2048) + if err := SetRlimit(target); err != nil { + t.Fatal("failed to set rlimit") + } + + soft, hard, err := GetRlimit() + if err != nil { + t.Fatal("failed to get rlimit") + } + + if soft != target { + t.Error("unexpected soft target") + } + + if hard != target { + t.Error("unexpected hard target") + } +} + +func TestGetRlimit(t *testing.T) { + soft, hard, err := GetRlimit() + if err != nil { + t.Fatal("failed to get rlimit") + } + + if soft == 0 { + t.Error("unexpected soft limit") + } + + if hard == 0 { + t.Error("unexpected hard limit") + } +} diff --git a/ulimit_unix.go b/ulimit_unix.go new file mode 100644 index 0000000..65f49d5 --- /dev/null +++ b/ulimit_unix.go @@ -0,0 +1,25 @@ +// +build darwin linux netbsd openbsd freebsd + +package ulimit + +import ( + "golang.org/x/sys/unix" +) + +func getRlimit() (uint64, uint64, error) { + var limit unix.Rlimit + if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &limit); err != nil { + return 0, 0, err + } + + return limit.Cur, limit.Max, nil +} + +func setRlimit(soft uint64, max uint64) error { + limit := unix.Rlimit{ + Cur: soft, + Max: max, + } + + return unix.Setrlimit(unix.RLIMIT_NOFILE, &limit) +} diff --git a/ulimit_windows.go b/ulimit_windows.go new file mode 100644 index 0000000..b02ef19 --- /dev/null +++ b/ulimit_windows.go @@ -0,0 +1,11 @@ +// +build windows + +package ulimit + +func getRlimit() (uint64, uint64, error) { + return 0, 0, nil +} + +func setRlimit(soft uint64, max uint64) error { + return nil +}