Add CGroupPtr
This commit is contained in:
parent
3c507ffe08
commit
d4ba5a9a58
@ -1,7 +0,0 @@
|
|||||||
const CGroup = @This();
|
|
||||||
|
|
||||||
gid: u32,
|
|
||||||
name: [:0]const u8,
|
|
||||||
// Should be a sentinel-terminated array.
|
|
||||||
// https://github.com/ziglang/zig/issues/7517
|
|
||||||
members: []align(1) const ?[*:0]const u8,
|
|
@ -46,12 +46,12 @@ pub fn init(
|
|||||||
var getgr_bufsize: usize = 0;
|
var getgr_bufsize: usize = 0;
|
||||||
for (groupsConst) |*group, i| {
|
for (groupsConst) |*group, i| {
|
||||||
groups_arr[i] = try group.clone(allocator);
|
groups_arr[i] = try group.clone(allocator);
|
||||||
getgr_bufsize = math.max(getgr_bufsize, groups_arr[i].strlenZ());
|
getgr_bufsize = math.max(getgr_bufsize, group.strlenZ());
|
||||||
}
|
}
|
||||||
var getpw_bufsize: usize = 0;
|
var getpw_bufsize: usize = 0;
|
||||||
for (usersConst) |*user, i| {
|
for (usersConst) |*user, i| {
|
||||||
users_arr[i] = try user.clone(allocator);
|
users_arr[i] = try user.clone(allocator);
|
||||||
getpw_bufsize = math.max(getpw_bufsize, users_arr[i].strlenZ());
|
getpw_bufsize = math.max(getpw_bufsize, user.strlenZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.sort(User, users_arr, {}, cmpUser);
|
sort.sort(User, users_arr, {}, cmpUser);
|
||||||
|
46
lib/DB.zig
46
lib/DB.zig
@ -16,7 +16,7 @@ const pad = @import("padding.zig");
|
|||||||
const compress = @import("compress.zig");
|
const compress = @import("compress.zig");
|
||||||
const PackedUser = @import("PackedUser.zig");
|
const PackedUser = @import("PackedUser.zig");
|
||||||
const User = @import("User.zig");
|
const User = @import("User.zig");
|
||||||
const CGroup = @import("CGroup.zig");
|
const CGroup = @import("cgroup.zig").CGroup;
|
||||||
const Group = @import("Group.zig");
|
const Group = @import("Group.zig");
|
||||||
const PackedGroup = @import("PackedGroup.zig");
|
const PackedGroup = @import("PackedGroup.zig");
|
||||||
const GroupStored = PackedGroup.GroupStored;
|
const GroupStored = PackedGroup.GroupStored;
|
||||||
@ -267,13 +267,8 @@ fn getGroup(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// getgrtnam returns a Group entry by name. The Group must be
|
// get a CGroup entry by name.
|
||||||
// deinit'ed by caller.
|
fn getgrnam(self: *const DB, name: []const u8, buf: *[]u8) error{OutOfMemory}!?CGroup {
|
||||||
fn getgrnam(
|
|
||||||
self: *const DB,
|
|
||||||
name: []const u8,
|
|
||||||
buf: *[]u8,
|
|
||||||
) error{OutOfMemory}!?CGroup {
|
|
||||||
const idx = bdz.search(self.bdz_groupname, name);
|
const idx = bdz.search(self.bdz_groupname, name);
|
||||||
const offset = self.idx_groupname2group[idx];
|
const offset = self.idx_groupname2group[idx];
|
||||||
const group = PackedGroup.fromBytes(self.groups[offset << 3 ..]).group;
|
const group = PackedGroup.fromBytes(self.groups[offset << 3 ..]).group;
|
||||||
@ -591,26 +586,43 @@ test "read/write via iovec" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "high-level API" {
|
test "high-level API" {
|
||||||
const allocator = testing.allocator;
|
var corpus = try Corpus.testCorpus(testing.allocator);
|
||||||
var corpus = try Corpus.testCorpus(allocator);
|
|
||||||
defer corpus.deinit();
|
defer corpus.deinit();
|
||||||
|
var db = try DB.fromCorpus(testing.allocator, &corpus);
|
||||||
|
defer db.deinit(testing.allocator);
|
||||||
|
var buf = try testing.allocator.alloc(u8, db.header.getgr_bufsize);
|
||||||
|
defer testing.allocator.free(buf);
|
||||||
|
|
||||||
var db = try DB.fromCorpus(allocator, &corpus);
|
|
||||||
defer db.deinit(allocator);
|
|
||||||
|
|
||||||
// TODO: should accept a buffer instead of an allocator instead.
|
|
||||||
var buf = try allocator.alloc(u8, db.header.getgr_bufsize);
|
|
||||||
defer allocator.free(buf);
|
|
||||||
const all = try db.getgrnam("all", &buf);
|
const all = try db.getgrnam("all", &buf);
|
||||||
try testing.expect(all != null);
|
try testing.expect(all != null);
|
||||||
try testing.expectEqual(all.?.gid, 9999);
|
try testing.expectEqual(all.?.gid, 9999);
|
||||||
try testing.expectEqualStrings(all.?.name, "all");
|
try testing.expectEqualStrings(mem.sliceTo(all.?.name, 0), "all");
|
||||||
const members = all.?.members;
|
const members = all.?.members;
|
||||||
try testing.expectEqualStrings(mem.sliceTo(members[0].?, 0), "Name" ** 8);
|
try testing.expectEqualStrings(mem.sliceTo(members[0].?, 0), "Name" ** 8);
|
||||||
try testing.expectEqualStrings(mem.sliceTo(members[1].?, 0), "root");
|
try testing.expectEqualStrings(mem.sliceTo(members[1].?, 0), "root");
|
||||||
try testing.expectEqualStrings(mem.sliceTo(members[2].?, 0), "svc-bar");
|
try testing.expectEqualStrings(mem.sliceTo(members[2].?, 0), "svc-bar");
|
||||||
try testing.expectEqualStrings(mem.sliceTo(members[3].?, 0), "vidmantas");
|
try testing.expectEqualStrings(mem.sliceTo(members[3].?, 0), "vidmantas");
|
||||||
try testing.expectEqual(members[4], null);
|
try testing.expectEqual(members[4], null);
|
||||||
|
|
||||||
|
const cgroup = all.?.ptr();
|
||||||
|
try testing.expectEqual(cgroup.gid, all.?.gid);
|
||||||
|
try testing.expectEqual(cgroup.name[0], 'a');
|
||||||
|
try testing.expectEqual(cgroup.name[1], 'l');
|
||||||
|
try testing.expectEqual(cgroup.name[2], 'l');
|
||||||
|
try testing.expectEqual(cgroup.name[3], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getgr_bufsize" {
|
||||||
|
var corpus = try Corpus.testCorpus(testing.allocator);
|
||||||
|
defer corpus.deinit();
|
||||||
|
var db = try DB.fromCorpus(testing.allocator, &corpus);
|
||||||
|
defer db.deinit(testing.allocator);
|
||||||
|
var buf = try testing.allocator.alloc(u8, db.header.getgr_bufsize);
|
||||||
|
defer testing.allocator.free(buf);
|
||||||
|
|
||||||
|
_ = try db.getgrnam("all", &buf);
|
||||||
|
buf.len -= 1;
|
||||||
|
try testing.expectError(error.OutOfMemory, db.getgrnam("all", &buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "additionalGids" {
|
test "additionalGids" {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const ptr_size = @import("cgroup.zig").ptr_size;
|
||||||
|
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
|
const meta = std.meta;
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
const Group = @This();
|
const Group = @This();
|
||||||
|
|
||||||
@ -56,9 +58,12 @@ pub fn deinit(self: *Group, allocator: Allocator) void {
|
|||||||
|
|
||||||
// buffer size in bytes if all strings were zero-terminated.
|
// buffer size in bytes if all strings were zero-terminated.
|
||||||
pub fn strlenZ(self: *const Group) usize {
|
pub fn strlenZ(self: *const Group) usize {
|
||||||
return self._buf.len +
|
var count: usize = 0;
|
||||||
self.members.len + // each membername sentinel
|
for (self.members) |member|
|
||||||
1; // name sentinel
|
count += member.len + 1;
|
||||||
|
count += ptr_size * (self.members.len + 1);
|
||||||
|
count += self.name.len + 1;
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
32
lib/cgroup.zig
Normal file
32
lib/cgroup.zig
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
const meta = @import("std").meta;
|
||||||
|
|
||||||
|
// All string fields are 0-terminated, but that's not part of the type.
|
||||||
|
// members field is null-terminated, but that's also not part of the type.
|
||||||
|
// Making it part of the type crashes zig compiler in pre-0.10.
|
||||||
|
// https://github.com/ziglang/zig/issues/7517
|
||||||
|
|
||||||
|
pub const CGroup = struct {
|
||||||
|
gid: u32,
|
||||||
|
// should be [*:0]const u8
|
||||||
|
name: []const u8,
|
||||||
|
// Should be [*:null]align(1) const ?[*:0]const u8
|
||||||
|
members: []align(1) const ?[*:0]const u8,
|
||||||
|
|
||||||
|
pub fn ptr(self: *const CGroup) CGroupPtr {
|
||||||
|
return CGroupPtr{
|
||||||
|
.gid = self.gid,
|
||||||
|
.name = self.name.ptr,
|
||||||
|
.members = @intToPtr([*]const u8, @ptrToInt(self.members.ptr)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// size of the pointer to a single member.
|
||||||
|
pub const ptr_size = @sizeOf(meta.Child(meta.fieldInfo(CGroup, .members).field_type));
|
||||||
|
|
||||||
|
// a workaround of not having sentinel-terminated `name` and `members`.
|
||||||
|
pub const CGroupPtr = extern struct {
|
||||||
|
gid: u32,
|
||||||
|
name: [*]const u8,
|
||||||
|
members: [*]const u8,
|
||||||
|
};
|
@ -2,6 +2,7 @@ const std = @import("std");
|
|||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
const native_endian = @import("builtin").target.cpu.arch.endian();
|
const native_endian = @import("builtin").target.cpu.arch.endian();
|
||||||
|
const ptr_size = @import("cgroup.zig").ptr_size;
|
||||||
|
|
||||||
const max_shells = @import("shell.zig").max_shells;
|
const max_shells = @import("shell.zig").max_shells;
|
||||||
const magic = [4]u8{ 0xf0, 0x9f, 0xa4, 0xb7 };
|
const magic = [4]u8{ 0xf0, 0x9f, 0xa4, 0xb7 };
|
||||||
@ -33,7 +34,7 @@ pub const Header = packed struct {
|
|||||||
magic: [4]u8 = magic,
|
magic: [4]u8 = magic,
|
||||||
version: u8 = version,
|
version: u8 = version,
|
||||||
endian: Endian = Endian.native(),
|
endian: Endian = Endian.native(),
|
||||||
ptr_size: u4 = @sizeOf(?[*:0]const u8),
|
ptr_size: u4 = ptr_size,
|
||||||
nblocks_shell_blob: u8,
|
nblocks_shell_blob: u8,
|
||||||
num_shells: u8,
|
num_shells: u8,
|
||||||
num_groups: u32,
|
num_groups: u32,
|
||||||
@ -65,7 +66,7 @@ pub const Header = packed struct {
|
|||||||
// when ptr size is larger than on the host that constructed it the DB,
|
// when ptr size is larger than on the host that constructed it the DB,
|
||||||
// getgr_bufsize/getpw_bufsize may return insufficient values, causing
|
// getgr_bufsize/getpw_bufsize may return insufficient values, causing
|
||||||
// OutOfMemory for getgr* and getpw* calls.
|
// OutOfMemory for getgr* and getpw* calls.
|
||||||
if (self.ptr_size < @sizeOf(?[*:0]const u8))
|
if (self.ptr_size < ptr_size)
|
||||||
return error.InvalidPointerSize;
|
return error.InvalidPointerSize;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
Loading…
Reference in New Issue
Block a user