libnss: pass state explicitly
This commit is contained in:
parent
f327fb24ba
commit
78ac541e49
10
src/File.zig
10
src/File.zig
@ -39,9 +39,10 @@ pub fn close(self: *File) void {
|
|||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
|
||||||
pub const TestDB = struct {
|
pub const TestDB = struct {
|
||||||
allocator: Allocator,
|
file: File,
|
||||||
dir: testing.TmpDir,
|
dir: testing.TmpDir,
|
||||||
path: [:0]const u8,
|
path: [:0]const u8,
|
||||||
|
allocator: Allocator,
|
||||||
|
|
||||||
pub fn init(allocator: Allocator) !TestDB {
|
pub fn init(allocator: Allocator) !TestDB {
|
||||||
var errc = ErrCtx{};
|
var errc = ErrCtx{};
|
||||||
@ -65,9 +66,9 @@ pub const TestDB = struct {
|
|||||||
break :blk real_path;
|
break :blk real_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
const full_path = try fs.path.join(allocator, &[_][]const u8{
|
const full_path = try fs.path.joinZ(allocator, &[_][]const u8{
|
||||||
base_path,
|
base_path,
|
||||||
"db.turbo\x00",
|
"db.turbo",
|
||||||
});
|
});
|
||||||
allocator.free(base_path);
|
allocator.free(base_path);
|
||||||
|
|
||||||
@ -78,8 +79,9 @@ pub const TestDB = struct {
|
|||||||
_ = try os.writev(fd, db.iov().constSlice());
|
_ = try os.writev(fd, db.iov().constSlice());
|
||||||
|
|
||||||
return TestDB{
|
return TestDB{
|
||||||
|
.file = try open(full_path),
|
||||||
.dir = tmp,
|
.dir = tmp,
|
||||||
.path = full_path[0 .. full_path.len - 1 :0],
|
.path = full_path,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
141
src/libnss.zig
141
src/libnss.zig
@ -115,7 +115,17 @@ export fn _nss_turbo_getpwuid_r(
|
|||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
return getpwuid_r(&db, uid, passwd, buffer, buflen, errnop);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getpwuid_r(
|
||||||
|
db: *const DB,
|
||||||
|
uid: c_uint,
|
||||||
|
passwd: *CUser,
|
||||||
|
buffer: [*]u8,
|
||||||
|
buflen: usize,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
var cuser = db.getpwuid(uid, buffer[0..buflen]) catch |err| switch (err) {
|
var cuser = db.getpwuid(uid, buffer[0..buflen]) catch |err| switch (err) {
|
||||||
error.BufferTooSmall => {
|
error.BufferTooSmall => {
|
||||||
errnop.* = @enumToInt(os.E.RANGE);
|
errnop.* = @enumToInt(os.E.RANGE);
|
||||||
@ -140,6 +150,17 @@ export fn _nss_turbo_getpwnam_r(
|
|||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
return getpwnam_r(&db, name, passwd, buffer, buflen, errnop);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getpwnam_r(
|
||||||
|
db: *const DB,
|
||||||
|
name: [*:0]const u8,
|
||||||
|
passwd: *CUser,
|
||||||
|
buffer: [*]u8,
|
||||||
|
buflen: usize,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
const nameSlice = mem.sliceTo(name, 0);
|
const nameSlice = mem.sliceTo(name, 0);
|
||||||
|
|
||||||
var buf = buffer[0..buflen];
|
var buf = buffer[0..buflen];
|
||||||
@ -167,6 +188,17 @@ export fn _nss_turbo_getgrgid_r(
|
|||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
return getgrgid_r(&state, gid, gr, buffer, buflen, errnop);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getgrgid_r(
|
||||||
|
state: *const State,
|
||||||
|
gid: c_uint,
|
||||||
|
gr: *CGroup,
|
||||||
|
buffer: [*]u8,
|
||||||
|
buflen: usize,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
const db = state.file.db;
|
const db = state.file.db;
|
||||||
const omit_members = state.omit_members;
|
const omit_members = state.omit_members;
|
||||||
|
|
||||||
@ -195,9 +227,19 @@ export fn _nss_turbo_getgrnam_r(
|
|||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
return getgrnam_r(&state, name, group, buffer, buflen, errnop);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getgrnam_r(
|
||||||
|
state: *const State,
|
||||||
|
name: [*:0]const u8,
|
||||||
|
group: *CGroup,
|
||||||
|
buffer: [*]u8,
|
||||||
|
buflen: usize,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
const db = state.file.db;
|
const db = state.file.db;
|
||||||
const omit_members = state.omit_members;
|
const omit_members = state.omit_members;
|
||||||
|
|
||||||
const nameSlice = mem.sliceTo(name, 0);
|
const nameSlice = mem.sliceTo(name, 0);
|
||||||
var buf = buffer[0..buflen];
|
var buf = buffer[0..buflen];
|
||||||
var cgroup = db.getgrnam(nameSlice, buf, omit_members) catch |err| switch (err) {
|
var cgroup = db.getgrnam(nameSlice, buf, omit_members) catch |err| switch (err) {
|
||||||
@ -206,12 +248,10 @@ export fn _nss_turbo_getgrnam_r(
|
|||||||
return c.NSS_STATUS_TRYAGAIN;
|
return c.NSS_STATUS_TRYAGAIN;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const got_cgroup = cgroup orelse {
|
const got_cgroup = cgroup orelse {
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
};
|
};
|
||||||
|
|
||||||
group.* = got_cgroup;
|
group.* = got_cgroup;
|
||||||
return c.NSS_STATUS_SUCCESS;
|
return c.NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -219,7 +259,10 @@ export fn _nss_turbo_getgrnam_r(
|
|||||||
export fn _nss_turbo_setpwent(_: c_int) void {
|
export fn _nss_turbo_setpwent(_: c_int) void {
|
||||||
global_init.call();
|
global_init.call();
|
||||||
var state = global_state orelse return;
|
var state = global_state orelse return;
|
||||||
|
setpwent(&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setpwent(state: *State) void {
|
||||||
state.getpwent_iterator_mu.lock();
|
state.getpwent_iterator_mu.lock();
|
||||||
defer state.getpwent_iterator_mu.unlock();
|
defer state.getpwent_iterator_mu.unlock();
|
||||||
|
|
||||||
@ -235,7 +278,10 @@ export fn _nss_turbo_setpwent(_: c_int) void {
|
|||||||
export fn _nss_turbo_endpwent() void {
|
export fn _nss_turbo_endpwent() void {
|
||||||
global_init.call();
|
global_init.call();
|
||||||
var state = global_state orelse return;
|
var state = global_state orelse return;
|
||||||
|
endpwent(&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endpwent(state: *State) void {
|
||||||
state.getpwent_iterator_mu.lock();
|
state.getpwent_iterator_mu.lock();
|
||||||
state.getpwent_iterator = null;
|
state.getpwent_iterator = null;
|
||||||
state.getpwent_iterator_mu.unlock();
|
state.getpwent_iterator_mu.unlock();
|
||||||
@ -243,6 +289,10 @@ export fn _nss_turbo_endpwent() void {
|
|||||||
|
|
||||||
export fn _nss_turbo_setgrent(_: c_int) void {
|
export fn _nss_turbo_setgrent(_: c_int) void {
|
||||||
var state = getState() orelse return;
|
var state = getState() orelse return;
|
||||||
|
setgrent(&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setgrent(state: *State) void {
|
||||||
state.getgrent_iterator_mu.lock();
|
state.getgrent_iterator_mu.lock();
|
||||||
defer state.getgrent_iterator_mu.unlock();
|
defer state.getgrent_iterator_mu.unlock();
|
||||||
state.getgrent_iterator = PackedGroup.iterator(
|
state.getgrent_iterator = PackedGroup.iterator(
|
||||||
@ -252,7 +302,10 @@ export fn _nss_turbo_setgrent(_: c_int) void {
|
|||||||
|
|
||||||
export fn _nss_turbo_endgrent() void {
|
export fn _nss_turbo_endgrent() void {
|
||||||
var state = getState() orelse return;
|
var state = getState() orelse return;
|
||||||
|
endgrent(&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endgrent(state: *State) void {
|
||||||
state.getgrent_iterator_mu.lock();
|
state.getgrent_iterator_mu.lock();
|
||||||
state.getgrent_iterator = null;
|
state.getgrent_iterator = null;
|
||||||
state.getgrent_iterator_mu.unlock();
|
state.getgrent_iterator_mu.unlock();
|
||||||
@ -265,7 +318,16 @@ export fn _nss_turbo_getgrent_r(
|
|||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
var state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
var state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
return getgrent_r(&state, result, buffer, buflen, errnop);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getgrent_r(
|
||||||
|
state: *State,
|
||||||
|
result: *CGroup,
|
||||||
|
buffer: [*]u8,
|
||||||
|
buflen: usize,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
state.getgrent_iterator_mu.lock();
|
state.getgrent_iterator_mu.lock();
|
||||||
defer state.getgrent_iterator_mu.unlock();
|
defer state.getgrent_iterator_mu.unlock();
|
||||||
|
|
||||||
@ -303,7 +365,16 @@ export fn _nss_turbo_getpwent_r(
|
|||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
var state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
var state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
return getpwent_r(&state, result, buffer, buflen, errnop);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getpwent_r(
|
||||||
|
state: *State,
|
||||||
|
result: *CUser,
|
||||||
|
buffer: [*]u8,
|
||||||
|
buflen: usize,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
state.getpwent_iterator_mu.lock();
|
state.getpwent_iterator_mu.lock();
|
||||||
defer state.getpwent_iterator_mu.unlock();
|
defer state.getpwent_iterator_mu.unlock();
|
||||||
|
|
||||||
@ -332,7 +403,7 @@ export fn _nss_turbo_getpwent_r(
|
|||||||
|
|
||||||
export fn _nss_turbo_initgroups_dyn(
|
export fn _nss_turbo_initgroups_dyn(
|
||||||
user_name: [*:0]const u8,
|
user_name: [*:0]const u8,
|
||||||
_: u32,
|
gid: u32,
|
||||||
start: *c_long,
|
start: *c_long,
|
||||||
size: *c_long,
|
size: *c_long,
|
||||||
groupsp: *[*]u32,
|
groupsp: *[*]u32,
|
||||||
@ -340,8 +411,20 @@ export fn _nss_turbo_initgroups_dyn(
|
|||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
const db = state.file.db;
|
return initgroups_dyn(&state, user_name, gid, start, size, groupsp, limit, errnop);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initgroups_dyn(
|
||||||
|
state: *const State,
|
||||||
|
user_name: [*:0]const u8,
|
||||||
|
_: u32,
|
||||||
|
start: *c_long,
|
||||||
|
size: *c_long,
|
||||||
|
groupsp: *[*]u32,
|
||||||
|
limit: c_long,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
|
const db = state.file.db;
|
||||||
const user = db.getUser(mem.sliceTo(user_name, 0)) orelse {
|
const user = db.getUser(mem.sliceTo(user_name, 0)) orelse {
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
@ -413,19 +496,19 @@ const testing = std.testing;
|
|||||||
test "getpwuid_r and getpwnam_r" {
|
test "getpwuid_r and getpwnam_r" {
|
||||||
var tf = try File.TestDB.init(testing.allocator);
|
var tf = try File.TestDB.init(testing.allocator);
|
||||||
defer tf.deinit();
|
defer tf.deinit();
|
||||||
const turbonss_db_path_old = turbonss_db_path;
|
const state = State{
|
||||||
turbonss_db_path = tf.path;
|
.file = tf.file,
|
||||||
defer {
|
.omit_members = false,
|
||||||
turbonss_db_path = turbonss_db_path_old;
|
.initgroups_dyn_allocator = testing.failing_allocator,
|
||||||
}
|
};
|
||||||
|
|
||||||
var buffer: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
var errno: c_int = 0;
|
var errno: c_int = 0;
|
||||||
|
|
||||||
var passwd: CUser = undefined;
|
var passwd: CUser = undefined;
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
c.NSS_STATUS_SUCCESS,
|
c.NSS_STATUS_SUCCESS,
|
||||||
_nss_turbo_getpwuid_r(128, &passwd, &buffer, buffer.len, &errno),
|
getpwuid_r(&state.file.db, 128, &passwd, &buf, buf.len, &errno),
|
||||||
);
|
);
|
||||||
try testing.expectEqual(@as(c_int, 0), errno);
|
try testing.expectEqual(@as(c_int, 0), errno);
|
||||||
try testVidmantas(passwd);
|
try testVidmantas(passwd);
|
||||||
@ -433,7 +516,7 @@ test "getpwuid_r and getpwnam_r" {
|
|||||||
passwd = undefined;
|
passwd = undefined;
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
c.NSS_STATUS_SUCCESS,
|
c.NSS_STATUS_SUCCESS,
|
||||||
_nss_turbo_getpwnam_r("vidmantas", &passwd, &buffer, buffer.len, &errno),
|
getpwnam_r(&state.file.db, "vidmantas", &passwd, &buf, buf.len, &errno),
|
||||||
);
|
);
|
||||||
try testing.expectEqual(@as(c_int, 0), errno);
|
try testing.expectEqual(@as(c_int, 0), errno);
|
||||||
try testVidmantas(passwd);
|
try testVidmantas(passwd);
|
||||||
@ -441,7 +524,7 @@ test "getpwuid_r and getpwnam_r" {
|
|||||||
passwd = undefined;
|
passwd = undefined;
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
c.NSS_STATUS_NOTFOUND,
|
c.NSS_STATUS_NOTFOUND,
|
||||||
_nss_turbo_getpwnam_r("does not exist", &passwd, &buffer, buffer.len, &errno),
|
getpwnam_r(&state.file.db, "does not exist", &passwd, &buf, buf.len, &errno),
|
||||||
);
|
);
|
||||||
try testing.expectEqual(@enumToInt(os.E.NOENT), @intCast(u16, errno));
|
try testing.expectEqual(@enumToInt(os.E.NOENT), @intCast(u16, errno));
|
||||||
|
|
||||||
@ -449,7 +532,7 @@ test "getpwuid_r and getpwnam_r" {
|
|||||||
var small_buffer: [1]u8 = undefined;
|
var small_buffer: [1]u8 = undefined;
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
c.NSS_STATUS_TRYAGAIN,
|
c.NSS_STATUS_TRYAGAIN,
|
||||||
_nss_turbo_getpwuid_r(0, &passwd, &small_buffer, small_buffer.len, &errno),
|
getpwuid_r(&state.file.db, 0, &passwd, &small_buffer, small_buffer.len, &errno),
|
||||||
);
|
);
|
||||||
try testing.expectEqual(@enumToInt(os.E.RANGE), @intCast(u16, errno));
|
try testing.expectEqual(@enumToInt(os.E.RANGE), @intCast(u16, errno));
|
||||||
}
|
}
|
||||||
@ -471,12 +554,12 @@ test "getgrgid_r and getgrnam_r" {
|
|||||||
turbonss_db_path = turbonss_db_path_old;
|
turbonss_db_path = turbonss_db_path_old;
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
var errno: c_int = 0;
|
var errno: c_int = 0;
|
||||||
var group: CGroup = undefined;
|
var group: CGroup = undefined;
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
c.NSS_STATUS_SUCCESS,
|
c.NSS_STATUS_SUCCESS,
|
||||||
_nss_turbo_getgrgid_r(128, &group, &buffer, buffer.len, &errno),
|
_nss_turbo_getgrgid_r(128, &group, &buf, buf.len, &errno),
|
||||||
);
|
);
|
||||||
try testing.expectEqual(@as(c_int, 0), errno);
|
try testing.expectEqual(@as(c_int, 0), errno);
|
||||||
try testVidmantasGroup(group);
|
try testVidmantasGroup(group);
|
||||||
@ -484,7 +567,7 @@ test "getgrgid_r and getgrnam_r" {
|
|||||||
group = undefined;
|
group = undefined;
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
c.NSS_STATUS_SUCCESS,
|
c.NSS_STATUS_SUCCESS,
|
||||||
_nss_turbo_getgrnam_r("vidmantas", &group, &buffer, buffer.len, &errno),
|
_nss_turbo_getgrnam_r("vidmantas", &group, &buf, buf.len, &errno),
|
||||||
);
|
);
|
||||||
try testing.expectEqual(@as(c_int, 0), errno);
|
try testing.expectEqual(@as(c_int, 0), errno);
|
||||||
try testVidmantasGroup(group);
|
try testVidmantasGroup(group);
|
||||||
@ -492,21 +575,21 @@ test "getgrgid_r and getgrnam_r" {
|
|||||||
group = undefined;
|
group = undefined;
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
c.NSS_STATUS_NOTFOUND,
|
c.NSS_STATUS_NOTFOUND,
|
||||||
_nss_turbo_getgrnam_r("does not exist", &group, &buffer, buffer.len, &errno),
|
_nss_turbo_getgrnam_r("does not exist", &group, &buf, buf.len, &errno),
|
||||||
);
|
);
|
||||||
try testing.expectEqual(@enumToInt(os.E.NOENT), @intCast(u16, errno));
|
try testing.expectEqual(@enumToInt(os.E.NOENT), @intCast(u16, errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "initgroups_dyn" {
|
test "initgroups_dyn" {
|
||||||
var tf = try File.TestDB.init(testing.allocator);
|
|
||||||
defer tf.deinit();
|
|
||||||
const turbonss_db_path_old = turbonss_db_path;
|
|
||||||
turbonss_db_path = tf.path;
|
|
||||||
defer {
|
|
||||||
turbonss_db_path = turbonss_db_path_old;
|
|
||||||
}
|
|
||||||
const allocator = testing.allocator;
|
const allocator = testing.allocator;
|
||||||
global_state.?.initgroups_dyn_allocator = allocator;
|
|
||||||
|
var tf = try File.TestDB.init(allocator);
|
||||||
|
defer tf.deinit();
|
||||||
|
var state = State{
|
||||||
|
.file = tf.file,
|
||||||
|
.omit_members = false,
|
||||||
|
.initgroups_dyn_allocator = allocator,
|
||||||
|
};
|
||||||
|
|
||||||
var size: c_long = 3; // size of the gids array is this
|
var size: c_long = 3; // size of the gids array is this
|
||||||
var groups = try allocator.alloc(u32, @intCast(usize, size)); // buffer too small
|
var groups = try allocator.alloc(u32, @intCast(usize, size)); // buffer too small
|
||||||
@ -515,7 +598,8 @@ test "initgroups_dyn" {
|
|||||||
groups[0] = 42; // canary
|
groups[0] = 42; // canary
|
||||||
var start: c_long = 1; // canary is there
|
var start: c_long = 1; // canary is there
|
||||||
|
|
||||||
const status = _nss_turbo_initgroups_dyn(
|
const status = initgroups_dyn(
|
||||||
|
&state,
|
||||||
"vidmantas",
|
"vidmantas",
|
||||||
0, // gid, ignored
|
0, // gid, ignored
|
||||||
&start,
|
&start,
|
||||||
@ -528,6 +612,7 @@ test "initgroups_dyn" {
|
|||||||
try testing.expectEqual(@as(c_int, 42), errno);
|
try testing.expectEqual(@as(c_int, 42), errno);
|
||||||
try testing.expectEqual(@as(u32, 42), groups[0]);
|
try testing.expectEqual(@as(u32, 42), groups[0]);
|
||||||
try testing.expectEqual(@as(u32, 128), groups[1]);
|
try testing.expectEqual(@as(u32, 128), groups[1]);
|
||||||
|
try testing.expectEqual(@as(u32, 9999), groups[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testVidmantasGroup(g: CGroup) !void {
|
fn testVidmantasGroup(g: CGroup) !void {
|
||||||
|
Loading…
Reference in New Issue
Block a user