wip: setgrent/setpwent + endpwent/endgrent

This commit is contained in:
Motiejus Jakštys 2022-07-07 16:42:45 +03:00
parent 50e116275c
commit 98db4ce0b2

View File

@ -5,6 +5,7 @@ const log = std.log;
const mem = std.mem;
const process = std.process;
const once = std.once;
const Mutex = std.Thread.Mutex;
const DB = @import("DB.zig");
const File = @import("File.zig");
@ -13,6 +14,7 @@ const CGroup = @import("Group.zig").CGroup;
const PackedGroup = @import("PackedGroup.zig");
const CUser = @import("User.zig").CUser;
const PackedUser = @import("PackedUser.zig");
const ShellReader = @import("shell.zig").ShellReader;
const c = @cImport({
@cInclude("nss.h");
@ -29,14 +31,18 @@ pub var log_level: std.log.Level = .err;
// State is a type of the global variable holding the process state:
// the DB handle and all the iterators.
const State = struct {
file: ?File,
getpwent_iterator: ?PackedUser.Iterator = null,
getgrent_iterator: ?PackedGroup.Iterator = null,
file: File,
omit_members: bool,
getpwent_iterator_mu: Mutex = Mutex{},
getpwent_iterator: ?PackedUser.Iterator = null,
getgrent_iterator_mu: Mutex = Mutex{},
getgrent_iterator: ?PackedGroup.Iterator = null,
};
// global_state is initialized on first call to an nss function
var global_state: State = undefined;
var global_state: ?State = null;
var global_init = once(init);
// assigns State from environment variables et al
@ -193,10 +199,56 @@ export fn _nss_turbo_getgrnam_r(
}
}
export fn _nss_turbo_setpwent(_: c_int) void {
global_init.call();
if (global_state) |*state| {
state.getpwent_iterator_mu.lock();
defer state.getpwent_iterator_mu.unlock();
state.getpwent_iterator = PackedUser.iterator(
state.file.db.users,
ShellReader{
.index = state.file.db.shell_index,
.blob = state.file.db.shell_blob,
},
);
}
}
export fn _nss_turbo_endpwent() void {
global_init.call();
if (global_state) |*state| {
state.getpwent_iterator_mu.lock();
defer state.getpwent_iterator_mu.unlock();
state.getpwent_iterator = null;
}
}
export fn _nss_turbo_setgrent(_: c_int) void {
global_init.call();
if (global_state) |*state| {
state.getgrent_iterator_mu.lock();
defer state.getgrent_iterator_mu.unlock();
state.getgrent_iterator = PackedGroup.iterator(
state.file.db.groups,
);
}
}
export fn _nss_turbo_endgrent() void {
global_init.call();
if (global_state) |*state| {
state.getgrent_iterator_mu.lock();
defer state.getgrent_iterator_mu.unlock();
state.getgrent_iterator = null;
}
}
fn getDb(errnop: *c_int) ?DB {
global_init.call();
if (global_state.file) |file| {
return file.db;
if (global_state) |state| {
return state.file.db;
} else {
errnop.* = @enumToInt(os.E.AGAIN);
return null;