authorgravatar for 14938807+xackus@users.noreply.github.comxackus <14938807+xackus@users.noreply.github.com> 2020-10-02 00:20:32+02:00
committergravatar for 14938807+xackus@users.noreply.github.comxackus <14938807+xackus@users.noreply.github.com> 2020-10-04 23:56:10+02:00
log4ec26be424506ed312639405b37bc68d00ccde4e
tree0344ceba5912d4e14c819cf345ae9acd7d7ef37a
parent0e2d858d69ee1595bb58d936f83f0e0248d54d68

implement {get, set}rlimit for linux


5 files changed, 128 insertions(+), 0 deletions(-)

lib/std/c.zig+3
......@@ -342,3 +342,6 @@ pub extern "c" fn fsync(fd: c_int) c_int;
342342pub extern "c" fn fdatasync(fd: c_int) c_int;
343343
344344pub extern "c" fn prctl(option: c_int, ...) c_int;
345
346pub extern "c" fn getrlimit(resource: rlimit_resource, rlim: *rlimit) c_int;
347pub extern "c" fn setrlimit(resource: rlimit_resource, rlim: *const rlimit) c_int;
lib/std/c/linux.zig+2
......@@ -100,6 +100,8 @@ pub extern "c" fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_
100100
101101pub extern "c" fn signalfd(fd: fd_t, mask: *const sigset_t, flags: c_uint) c_int;
102102
103pub extern "c" fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: *const rlimit, old_limit: *rlimit) c_int;
104
103105pub const pthread_attr_t = extern struct {
104106 __size: [56]u8,
105107 __align: c_long,
lib/std/os.zig+27
......@@ -5410,3 +5410,30 @@ pub fn prctl(option: i32, args: anytype) PrctlError!u31 {
54105410 else => |err| return std.os.unexpectedErrno(err),
54115411 }
54125412}
5413
5414pub const GetrlimitError = UnexpectedError;
5415
5416pub fn getrlimit(resource: rlimit_resource, limits: *rlimit) GetrlimitError!void {
5417 const rc = system.getrlimit(resource, limits);
5418 switch (errno(rc)) {
5419 0 => return,
5420 EFAULT => unreachable, // bogus pointer
5421 EINVAL => unreachable,
5422 else => |err| return std.os.unexpectedErrno(err),
5423 }
5424}
5425
5426pub const SetrlimitError = error{
5427 PermissionDenied,
5428} || UnexpectedError;
5429
5430pub fn setrlimit(resource: rlimit_resource, limits: *const rlimit) SetrlimitError!void {
5431 const rc = system.setrlimit(resource, limits);
5432 switch (errno(rc)) {
5433 0 => return,
5434 EFAULT => unreachable, // bogus pointer
5435 EINVAL => unreachable,
5436 EPERM => return error.PermissionDenied,
5437 else => |err| return std.os.unexpectedErrno(err),
5438 }
5439}
lib/std/os/bits/linux.zig+76
......@@ -1890,3 +1890,79 @@ pub const ifreq = extern struct {
18901890 data: ?[*]u8,
18911891 },
18921892};
1893
1894// doc comments copied from musl
1895pub const rlimit_resource = extern enum(c_int) {
1896 /// Per-process CPU limit, in seconds.
1897 CPU,
1898
1899 /// Largest file that can be created, in bytes.
1900 FSIZE,
1901
1902 /// Maximum size of data segment, in bytes.
1903 DATA,
1904
1905 /// Maximum size of stack segment, in bytes.
1906 STACK,
1907
1908 /// Largest core file that can be created, in bytes.
1909 CORE,
1910
1911 /// Largest resident set size, in bytes.
1912 /// This affects swapping; processes that are exceeding their
1913 /// resident set size will be more likely to have physical memory
1914 /// taken from them.
1915 RSS,
1916
1917 /// Number of processes.
1918 NPROC,
1919
1920 /// Number of open files.
1921 NOFILE,
1922
1923 /// Locked-in-memory address space.
1924 MEMLOCK,
1925
1926 /// Address space limit.
1927 AS,
1928
1929 /// Maximum number of file locks.
1930 LOCKS,
1931
1932 /// Maximum number of pending signals.
1933 SIGPENDING,
1934
1935 /// Maximum bytes in POSIX message queues.
1936 MSGQUEUE,
1937
1938 /// Maximum nice priority allowed to raise to.
1939 /// Nice levels 19 .. -20 correspond to 0 .. 39
1940 /// values of this resource limit.
1941 NICE,
1942
1943 /// Maximum realtime priority allowed for non-priviledged
1944 /// processes.
1945 RTPRIO,
1946
1947 /// Maximum CPU time in µs that a process scheduled under a real-time
1948 /// scheduling policy may consume without making a blocking system
1949 /// call before being forcibly descheduled.
1950 RTTIME,
1951
1952 _,
1953};
1954
1955pub const rlim_t = u64;
1956
1957/// No limit
1958pub const RLIM_INFINITY = ~@as(rlim_t, 0);
1959
1960pub const RLIM_SAVED_MAX = RLIM_INFINITY;
1961pub const RLIM_SAVED_CUR = RLIM_INFINITY;
1962
1963pub const rlimit = extern struct {
1964 /// Soft limit
1965 cur: rlim_t,
1966 /// Hard limit
1967 max: rlim_t,
1968};
lib/std/os/linux.zig+20
......@@ -1263,6 +1263,26 @@ pub fn prctl(option: i32, arg2: usize, arg3: usize, arg4: usize, arg5: usize) us
12631263 return syscall5(.prctl, @bitCast(usize, @as(isize, option)), arg2, arg3, arg4, arg5);
12641264}
12651265
1266pub fn getrlimit(resource: rlimit_resource, rlim: *rlimit) usize {
1267 // use prlimit64 to have 64 bit limits on 32 bit platforms
1268 return prlimit(0, resource, null, rlim);
1269}
1270
1271pub fn setrlimit(resource: rlimit_resource, rlim: *const rlimit) usize {
1272 // use prlimit64 to have 64 bit limits on 32 bit platforms
1273 return prlimit(0, resource, rlim, null);
1274}
1275
1276pub fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: ?*const rlimit, old_limit: ?*rlimit) usize {
1277 return syscall4(
1278 .prlimit64,
1279 @bitCast(usize, @as(isize, pid)),
1280 @bitCast(usize, @as(isize, @enumToInt(resource))),
1281 @ptrToInt(new_limit),
1282 @ptrToInt(old_limit)
1283 );
1284}
1285
12661286test "" {
12671287 if (builtin.os.tag == .linux) {
12681288 _ = @import("linux/test.zig");