diff --git a/docs/architecture.md b/docs/architecture.md index 8789a39..2e7a715 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -132,10 +132,11 @@ caller does not receive `ENOMEM`. Primitive types --------------- -`User` and `Group` entries are sorted by the order they were received in the input -file. All entries are aligned to 8 bytes. All `User` and `Group` entries are -referred by their byte offset in the `Users` and `Groups` section relative to -the beginning of the section. +`User` and `Group` entries are sorted by the order they were received in the +input file. All entries are aligned to 8 bytes. All `User` and `Group` entries +are referred by their byte offset (shifted by 3 bits due to the 8-byte +alignment) in the `Users` and `Groups` section relative to the beginning of the +section. ``` const PackedGroup = packed struct { @@ -146,7 +147,8 @@ const PackedGroup = packed struct { ``` PackedGroup is followed by the group name (of length `groupname_len`), followed -by a varint-compressed offset to the groupmembers section, followed by 8b padding. +by a varint-compressed offset to the groupmembers section, followed by padding +upto 8 bytes. PackedUser is a bit more involved: @@ -177,9 +179,9 @@ them. PackedUser employs two data-oriented compression techniques: - shells are often shared across different users, see the "Shells" section. -- `name` is frequently a suffix of `home`. For example, `/home/vidmantas` and - `vidmantas`. In this case storing both name and home is wasteful. Therefore - name has two options: +- `name` is frequently a suffix of `home`. For example, `home=/home/vidmantas` + and `name=vidmantas`. In this case storing both name and home is wasteful. + Therefore name has two options: 1. `name_is_a_suffix=true`: name is a suffix of the home dir. Then `name` starts at the `home_len - name_len`'th byte of `home`, and ends at the same place as `home`. diff --git a/src/DB.zig b/src/DB.zig index 7508def..796265a 100644 --- a/src/DB.zig +++ b/src/DB.zig @@ -702,10 +702,10 @@ fn bdzIdx( keys: []const T, idx2offset: []const u32, ) error{OutOfMemory}![]align(8) const u32 { - const search_fn = switch (T) { + const search_fn = comptime switch (T) { u32 => bdz.search_u32, []const u8 => bdz.search, - else => unreachable, + else => @compileError("unexpected type " ++ @typeName(T)), }; assert(keys.len <= math.maxInt(u32)); var result = try allocator.alignedAlloc(u32, 8, keys.len); diff --git a/src/Group.zig b/src/Group.zig index a74e4fb..ded49d3 100644 --- a/src/Group.zig +++ b/src/Group.zig @@ -74,7 +74,6 @@ pub fn fromReader(allocator: Allocator, reader: anytype) FromReaderError![]Group var i: usize = 0; while (true) : (i += 1) { - // TODO: catch and interpret different errors const max = std.math.maxInt(u32); reader.readUntilDelimiterArrayList(&line, '\n', max) catch |err| switch (err) { error.EndOfStream => break, diff --git a/src/libnss.zig b/src/libnss.zig index e1011a3..af7d048 100644 --- a/src/libnss.zig +++ b/src/libnss.zig @@ -220,7 +220,7 @@ fn getgrgid_r( const omit_members = state.omit_members; var buf = buffer[0..buflen]; - var cgroup = db.getgrgid(gid, buf, omit_members) catch |err| switch (err) { + const cgroup = db.getgrgid(gid, buf, omit_members) catch |err| switch (err) { error.BufferTooSmall => { errnop.* = @enumToInt(os.E.RANGE); return c.NSS_STATUS_TRYAGAIN; @@ -262,17 +262,16 @@ fn getgrnam_r( const omit_members = state.omit_members; const nameSlice = mem.sliceTo(name, 0); var buf = buffer[0..buflen]; - var cgroup = db.getgrnam(nameSlice, buf, omit_members) catch |err| switch (err) { + const cgroup = db.getgrnam(nameSlice, buf, omit_members) catch |err| switch (err) { error.BufferTooSmall => { errnop.* = @enumToInt(os.E.RANGE); return c.NSS_STATUS_TRYAGAIN; }, }; - const got_cgroup = cgroup orelse { + group.* = cgroup orelse { errnop.* = @enumToInt(os.E.NOENT); return c.NSS_STATUS_NOTFOUND; }; - group.* = got_cgroup; return c.NSS_STATUS_SUCCESS; } @@ -286,11 +285,10 @@ fn setpwent(state: *State) c.enum_nss_status { state.getpwent_iterator_mu.lock(); defer state.getpwent_iterator_mu.unlock(); - const db = state.file.db; state.getpwent_iterator = PackedUser.iterator( - db.users, - db.header.num_users, - db.shellReader(), + state.file.db.users, + state.file.db.header.num_users, + state.file.db.shellReader(), ); return c.NSS_STATUS_SUCCESS; }