mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
Merge pull request #6496 from xackus/rlimit
std: implement {get, set}rlimit for linux
This commit is contained in:
commit
d5d48c6f4e
@ -342,3 +342,6 @@ pub extern "c" fn fsync(fd: c_int) c_int;
|
|||||||
pub extern "c" fn fdatasync(fd: c_int) c_int;
|
pub extern "c" fn fdatasync(fd: c_int) c_int;
|
||||||
|
|
||||||
pub extern "c" fn prctl(option: c_int, ...) c_int;
|
pub extern "c" fn prctl(option: c_int, ...) c_int;
|
||||||
|
|
||||||
|
pub extern "c" fn getrlimit(resource: rlimit_resource, rlim: *rlimit) c_int;
|
||||||
|
pub extern "c" fn setrlimit(resource: rlimit_resource, rlim: *const rlimit) c_int;
|
||||||
|
|||||||
@ -100,6 +100,8 @@ pub extern "c" fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_
|
|||||||
|
|
||||||
pub extern "c" fn signalfd(fd: fd_t, mask: *const sigset_t, flags: c_uint) c_int;
|
pub extern "c" fn signalfd(fd: fd_t, mask: *const sigset_t, flags: c_uint) c_int;
|
||||||
|
|
||||||
|
pub extern "c" fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: *const rlimit, old_limit: *rlimit) c_int;
|
||||||
|
|
||||||
pub const pthread_attr_t = extern struct {
|
pub const pthread_attr_t = extern struct {
|
||||||
__size: [56]u8,
|
__size: [56]u8,
|
||||||
__align: c_long,
|
__align: c_long,
|
||||||
|
|||||||
@ -5410,3 +5410,33 @@ pub fn prctl(option: i32, args: anytype) PrctlError!u31 {
|
|||||||
else => |err| return std.os.unexpectedErrno(err),
|
else => |err| return std.os.unexpectedErrno(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const GetrlimitError = UnexpectedError;
|
||||||
|
|
||||||
|
pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {
|
||||||
|
// TODO implement for systems other than linux and enable test
|
||||||
|
var limits: rlimit = undefined;
|
||||||
|
const rc = system.getrlimit(resource, &limits);
|
||||||
|
switch (errno(rc)) {
|
||||||
|
0 => return limits,
|
||||||
|
EFAULT => unreachable, // bogus pointer
|
||||||
|
EINVAL => unreachable,
|
||||||
|
else => |err| return std.os.unexpectedErrno(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const SetrlimitError = error{
|
||||||
|
PermissionDenied,
|
||||||
|
} || UnexpectedError;
|
||||||
|
|
||||||
|
pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void {
|
||||||
|
// TODO implement for systems other than linux and enable test
|
||||||
|
const rc = system.setrlimit(resource, &limits);
|
||||||
|
switch (errno(rc)) {
|
||||||
|
0 => return,
|
||||||
|
EFAULT => unreachable, // bogus pointer
|
||||||
|
EINVAL => unreachable,
|
||||||
|
EPERM => return error.PermissionDenied,
|
||||||
|
else => |err| return std.os.unexpectedErrno(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1890,3 +1890,79 @@ pub const ifreq = extern struct {
|
|||||||
data: ?[*]u8,
|
data: ?[*]u8,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// doc comments copied from musl
|
||||||
|
pub const rlimit_resource = extern enum(c_int) {
|
||||||
|
/// Per-process CPU limit, in seconds.
|
||||||
|
CPU,
|
||||||
|
|
||||||
|
/// Largest file that can be created, in bytes.
|
||||||
|
FSIZE,
|
||||||
|
|
||||||
|
/// Maximum size of data segment, in bytes.
|
||||||
|
DATA,
|
||||||
|
|
||||||
|
/// Maximum size of stack segment, in bytes.
|
||||||
|
STACK,
|
||||||
|
|
||||||
|
/// Largest core file that can be created, in bytes.
|
||||||
|
CORE,
|
||||||
|
|
||||||
|
/// Largest resident set size, in bytes.
|
||||||
|
/// This affects swapping; processes that are exceeding their
|
||||||
|
/// resident set size will be more likely to have physical memory
|
||||||
|
/// taken from them.
|
||||||
|
RSS,
|
||||||
|
|
||||||
|
/// Number of processes.
|
||||||
|
NPROC,
|
||||||
|
|
||||||
|
/// Number of open files.
|
||||||
|
NOFILE,
|
||||||
|
|
||||||
|
/// Locked-in-memory address space.
|
||||||
|
MEMLOCK,
|
||||||
|
|
||||||
|
/// Address space limit.
|
||||||
|
AS,
|
||||||
|
|
||||||
|
/// Maximum number of file locks.
|
||||||
|
LOCKS,
|
||||||
|
|
||||||
|
/// Maximum number of pending signals.
|
||||||
|
SIGPENDING,
|
||||||
|
|
||||||
|
/// Maximum bytes in POSIX message queues.
|
||||||
|
MSGQUEUE,
|
||||||
|
|
||||||
|
/// Maximum nice priority allowed to raise to.
|
||||||
|
/// Nice levels 19 .. -20 correspond to 0 .. 39
|
||||||
|
/// values of this resource limit.
|
||||||
|
NICE,
|
||||||
|
|
||||||
|
/// Maximum realtime priority allowed for non-priviledged
|
||||||
|
/// processes.
|
||||||
|
RTPRIO,
|
||||||
|
|
||||||
|
/// Maximum CPU time in µs that a process scheduled under a real-time
|
||||||
|
/// scheduling policy may consume without making a blocking system
|
||||||
|
/// call before being forcibly descheduled.
|
||||||
|
RTTIME,
|
||||||
|
|
||||||
|
_,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const rlim_t = u64;
|
||||||
|
|
||||||
|
/// No limit
|
||||||
|
pub const RLIM_INFINITY = ~@as(rlim_t, 0);
|
||||||
|
|
||||||
|
pub const RLIM_SAVED_MAX = RLIM_INFINITY;
|
||||||
|
pub const RLIM_SAVED_CUR = RLIM_INFINITY;
|
||||||
|
|
||||||
|
pub const rlimit = extern struct {
|
||||||
|
/// Soft limit
|
||||||
|
cur: rlim_t,
|
||||||
|
/// Hard limit
|
||||||
|
max: rlim_t,
|
||||||
|
};
|
||||||
|
|||||||
@ -1263,6 +1263,26 @@ pub fn prctl(option: i32, arg2: usize, arg3: usize, arg4: usize, arg5: usize) us
|
|||||||
return syscall5(.prctl, @bitCast(usize, @as(isize, option)), arg2, arg3, arg4, arg5);
|
return syscall5(.prctl, @bitCast(usize, @as(isize, option)), arg2, arg3, arg4, arg5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getrlimit(resource: rlimit_resource, rlim: *rlimit) usize {
|
||||||
|
// use prlimit64 to have 64 bit limits on 32 bit platforms
|
||||||
|
return prlimit(0, resource, null, rlim);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setrlimit(resource: rlimit_resource, rlim: *const rlimit) usize {
|
||||||
|
// use prlimit64 to have 64 bit limits on 32 bit platforms
|
||||||
|
return prlimit(0, resource, rlim, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: ?*const rlimit, old_limit: ?*rlimit) usize {
|
||||||
|
return syscall4(
|
||||||
|
.prlimit64,
|
||||||
|
@bitCast(usize, @as(isize, pid)),
|
||||||
|
@bitCast(usize, @as(isize, @enumToInt(resource))),
|
||||||
|
@ptrToInt(new_limit),
|
||||||
|
@ptrToInt(old_limit)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
test "" {
|
test "" {
|
||||||
if (builtin.os.tag == .linux) {
|
if (builtin.os.tag == .linux) {
|
||||||
_ = @import("linux/test.zig");
|
_ = @import("linux/test.zig");
|
||||||
|
|||||||
@ -591,3 +591,13 @@ test "fsync" {
|
|||||||
try os.fsync(file.handle);
|
try os.fsync(file.handle);
|
||||||
try os.fdatasync(file.handle);
|
try os.fdatasync(file.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "getrlimit and setrlimit" {
|
||||||
|
// TODO enable for other systems when implemented
|
||||||
|
if(builtin.os.tag != .linux){
|
||||||
|
return error.SkipZigTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cpuLimit = try os.getrlimit(.CPU);
|
||||||
|
try os.setrlimit(.CPU, cpuLimit);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user