NixOS-based container for running GitHub actions
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

use linux syscall directly to exec

+95 -7
+9 -7
src/bash.zig
··· 8 8 9 9 pub fn main(init: std.process.Init) !void { 10 10 const arena: std.mem.Allocator = init.arena.allocator(); 11 - const io = init.io; 11 + // const io = init.io; 12 12 13 13 var environ_map = try lib.fixupEnvironMap(arena, init.environ_map, .user); 14 14 defer environ_map.deinit(); ··· 16 16 var argv: std.ArrayList([]const u8) = .empty; 17 17 defer argv.deinit(arena); 18 18 19 - try argv.append(arena, options.bash); 19 + try argv.append(arena, "bash"); 20 20 21 21 var it = try init.minimal.args.iterateAllocator(arena); 22 22 defer it.deinit(); ··· 28 28 29 29 try lib.switchToUser(); 30 30 31 - const err = std.process.replace(io, .{ 32 - .argv = argv.items, 33 - .environ_map = &environ_map, 34 - }); 31 + try lib.exec(init.gpa, options.bash, argv, &environ_map); 35 32 36 - std.debug.print("unable to execute: {t}\n", .{err}); 33 + // const err = std.process.replace(io, .{ 34 + // .argv = argv.items, 35 + // .environ_map = &environ_map, 36 + // }); 37 + 38 + // std.debug.print("unable to execute: {t}\n", .{err}); 37 39 }
+2
src/lib.zig
··· 3 3 4 4 const std = @import("std"); 5 5 6 + pub const exec = @import("lib/process.zig").exec; 6 7 pub const fixupEnvironMap = @import("lib/env.zig").fixupEnvironMap; 7 8 pub const switchToUser = @import("lib/switchtouser.zig").switchToUser; 8 9 9 10 test { 10 11 _ = @import("lib/env.zig"); 12 + _ = @import("lib/process.zig"); 11 13 _ = @import("lib/switchtouser.zig"); 12 14 }
+58
src/lib/passwd.zig
··· 1 + // SPDX-FileCopyrightText: © 2023 Jeffrey C. Ollie 2 + // SPDX-License-Identifier: MIT 3 + 4 + const std = @import("std"); 5 + const options = @import("options"); 6 + 7 + pub fn getUserUid( 8 + io: std.Io, 9 + name: []const u8, 10 + ) !?u32 { 11 + var passwd_file = try std.Io.Dir.openFileAbsolute(io, "/etc/passwd", .{ .mode = .read_only }); 12 + defer passwd_file.close(io); 13 + 14 + // room for 2 paths (home directory and shell) plus a generous amount for the rest 15 + var passwd_buf: [1024 + std.fs.max_path_bytes * 2]u8 = undefined; 16 + var passwd_file_reader = passwd_file.reader(io, &passwd_buf); 17 + const reader = &passwd_file_reader.interface; 18 + 19 + while (true) { 20 + const line = reader.takeDelimiter('\n') catch |err| switch (err) { 21 + error.ReadFailed => return error.ReadFailed, 22 + error.StreamTooLong => return error.StreamTooLong, 23 + } orelse return null; 24 + var it = std.mem.splitScalar(u8, line, ':'); 25 + const username = it.next() orelse continue; 26 + if (!std.mem.eql(u8, username, name)) continue; 27 + _ = it.next(); // skip password field 28 + const uid_str = it.next() orelse return error.MissingUID; 29 + return try std.fmt.parseUnsigned(u32, uid_str, 10); 30 + } 31 + } 32 + 33 + pub fn getUserGid( 34 + io: std.Io, 35 + name: []const u8, 36 + ) !?u32 { 37 + var passwd_file = try std.Io.Dir.openFileAbsolute(io, "/etc/passwd", .{ .mode = .read_only }); 38 + defer passwd_file.close(io); 39 + 40 + // room for 2 paths (home directory and shell) plus a generous amount for the rest 41 + var passwd_buf: [1024 + std.fs.max_path_bytes * 2]u8 = undefined; 42 + var passwd_file_reader = passwd_file.reader(io, &passwd_buf); 43 + const reader = &passwd_file_reader.interface; 44 + 45 + while (true) { 46 + const line = reader.takeDelimiter('\n') catch |err| switch (err) { 47 + error.ReadFailed => return error.ReadFailed, 48 + error.StreamTooLong => return error.StreamTooLong, 49 + } orelse return null; 50 + var it = std.mem.splitScalar(u8, line, ':'); 51 + const username = it.next() orelse continue; 52 + if (!std.mem.eql(u8, username, name)) continue; 53 + _ = it.next(); // skip password field 54 + _ = it.next(); // skip uid field 55 + const gid_str = it.next() orelse return error.MissingGID; 56 + return try std.fmt.parseUnsigned(u32, gid_str, 10); 57 + } 58 + }
+26
src/lib/process.zig
··· 1 + // SPDX-FileCopyrightText: © 2023 Jeffrey C. Ollie 2 + // SPDX-License-Identifier: MIT 3 + 4 + const std = @import("std"); 5 + const options = @import("options"); 6 + 7 + pub fn exec(gpa: std.mem.Allocator, path: []const u8, argv: []const []const u8, map: *const std.process.Environ.Map) !void { 8 + var arena: std.heap.ArenaAllocator = .init(gpa); 9 + defer arena.deinit(); 10 + const alloc = arena.allocator(); 11 + 12 + const path0 = try alloc.dupeZ(u8, path); 13 + 14 + const argv0 = try alloc.allocSentinel(?[*:0]const u8, argv.len, null); 15 + for (argv, 0..) |arg, i| argv0[i] = (try alloc.dupeZ(u8, arg)).ptr; 16 + 17 + const block = try map.createPosixBlock(alloc, .{ .zig_progress_fd = -1 }); 18 + 19 + const rc = std.os.linux.execve( 20 + path0.ptr, 21 + argv0.ptr, 22 + block, 23 + ); 24 + 25 + return std.posix.unexpectedErrno(rc); 26 + }