diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 6952ab7e0e4e..a25989504fa5 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -186,6 +186,73 @@ pub const MAP_FIXED_NOREPLACE = 0x100000; /// For anonymous mmap, memory could be uninitialized pub const MAP_UNINITIALIZED = 0x4000000; +pub const key_t = i32; +pub const IPC_PRIVATE = 0; + +/// create key if key does not exist +pub const IPC_CREAT = 0x200; + +/// fail if key exists +pub const IPC_EXCL = 0x400; + +/// return error on wait +pub const IPC_NOWAIT = 0x800; + +/// segment will be destroyed on last detach +pub const SHM_DEST = 0x200; + +/// segment will not be swapped +pub const SHM_LOCKED = 0x400; + +/// segment will use huge TLB pages +pub const SHM_HUGETLB = 0x800; + +pub const SHM_HUGE_SHIFT = 26; +pub const SHM_HUGE_2MB = 21 << SHM_HUGE_SHIFT; +pub const SHM_HUGE_1GB = 30 << SHM_HUGE_SHIFT; + +/// don't check for reservations +pub const SHM_NORESERVE = 0x1000; + +/// attach read-only else read-write +pub const SHM_RDONLY = 0x1000; + +/// round attach address to SHMLBA +pub const SHM_RND = 0x2000; + +/// take-over region on attach +pub const SHM_REMAP = 0x4000; + +/// execution access +pub const SHM_EXEC = 0x8000; + +/// remove identifier +pub const IPC_RMID = 0; + +/// set 'ipc_perm' options +pub const IPC_SET = 1; + +/// get 'ipc_perm' options +pub const IPC_STAT = 2; + +/// get info about shared memory limits and parameters +pub const IPC_INFO = 3; + +/// lock segment +pub const SHM_LOCK = 11; + +/// unlock segment +pub const SHM_UNLOCK = 12; + +/// get 'ipc_perm' options from kernel index +pub const SHM_STAT = 13; + +/// get info about about system resources consumed by shared memory +pub const SHM_INFO = 14; + +/// get 'ipc_perm' options from kernel index without checking read access +pub const SHM_STAT_ANY = 15; + pub const FD_CLOEXEC = 1; pub const F_OK = 0; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 56e9d45a08e6..5aaa860bb62b 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -274,6 +274,22 @@ pub fn munmap(address: [*]const u8, length: usize) usize { return syscall2(.munmap, @ptrToInt(address), length); } +pub fn shmget(key: key_t, size: usize, shmflg: u32) usize { + return syscall3(.shmget, @bitCast(u32, key), size, shmflg); +} + +pub fn shmat(shmid: i32, shmaddr: ?[*]align(std.mem.page_size) u8, shmflg: u32) usize { + return syscall3(.shmat, @bitCast(u32, shmid), @ptrToInt(shmaddr), shmflg); +} + +pub fn shmctl(shmid: i32, cmd: i32, buf: ?[*]u8) usize { + return syscall3(.shmctl, @bitCast(u32, shmid), @bitCast(u32, cmd), @ptrToInt(buf)); +} + +pub fn shmdt(shmaddr: [*]u8) usize { + return syscall1(.shmdt, @ptrToInt(shmaddr)); +} + pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize { if (@hasField(SYS, "poll")) { return syscall3(.poll, @ptrToInt(fds), n, @bitCast(u32, timeout)); diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig index e34d58880141..126a10e4ea68 100644 --- a/lib/std/os/linux/test.zig +++ b/lib/std/os/linux/test.zig @@ -24,7 +24,7 @@ test "fallocate" { 0 => {}, linux.ENOSYS => return error.SkipZigTest, linux.EOPNOTSUPP => return error.SkipZigTest, - else => |errno| std.debug.panic("unhandled errno: {}", .{ errno }), + else => |errno| std.debug.panic("unhandled errno: {}", .{errno}), } expect((try file.stat()).size == len); @@ -99,3 +99,19 @@ test "statx" { expect(@bitCast(u64, @as(i64, stat_buf.blksize)) == statx_buf.blksize); expect(@bitCast(u64, @as(i64, stat_buf.blocks)) == statx_buf.blocks); } + +test "shm" { + const segment = linux.shmget(linux.IPC_PRIVATE, mem.page_size, linux.IPC_CREAT + 0o666); + expect(linux.getErrno(segment) == 0); + defer { + const r = linux.shmctl(@intCast(i32, segment), linux.IPC_RMID, null); + expect(linux.getErrno(r) == 0); + } + + const addr = std.os.linux.shmat(@intCast(i32, segment), null, 0); + expect(linux.getErrno(addr) == 0); + defer { + const r = std.os.linux.shmdt(@intToPtr([*]u8, addr)); + expect(linux.getErrno(r) == 0); + } +}