port to Zig 0.13.0

This commit is contained in:
LordMZTE 2024-08-25 19:24:49 +02:00
parent b584002850
commit e08e44c43c
Signed by: LordMZTE
GPG key ID: B64802DC33A64FF6
16 changed files with 109 additions and 109 deletions

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
zig-cache/
.zig-cache/
zig-out/

View file

@ -19,12 +19,7 @@ irc.libera.chat.
## Zig Version
Right now nfm is developed against whatever is the latest available binary
on the zig website. I usually target zig releases in my project, however
the nfm code base crashes the zig v0.11.0 compiler without telling what
upset it. Once the next zig version is out we can hopefully go back to
targetting releases.
Right now, nfm is developed against Zig 0.13.0.
## Building

View file

@ -19,27 +19,27 @@ pub fn build(b: *std.Build) void {
const nfm = b.addExecutable(.{
.name = "nfm",
.root_source_file = .{ .path = "src/nfm.zig" },
.root_source_file = b.path("src/nfm.zig"),
.target = target,
.optimize = optimize,
});
nfm.addModule("exre", exre.module("exre"));
nfm.addModule("ini", ini.module("ini"));
nfm.addModule("spoon", spoon.module("spoon"));
nfm.root_module.addImport("exre", exre.module("exre"));
nfm.root_module.addImport("ini", ini.module("ini"));
nfm.root_module.addImport("spoon", spoon.module("spoon"));
b.installArtifact(nfm);
b.installFile("doc/nfm.1", "share/man/man1/nfm.1");
b.installFile("doc/nfm.5", "share/man/man5/nfm.5");
const tests = b.addTest(.{
.root_source_file = .{ .path = "src/nfm.zig" },
.root_source_file = b.path("src/nfm.zig"),
.target = target,
.optimize = optimize,
});
tests.addModule("exre", exre.module("exre"));
tests.addModule("ini", ini.module("ini"));
tests.addModule("spoon", spoon.module("spoon"));
tests.root_module.addImport("exre", exre.module("exre"));
tests.root_module.addImport("ini", ini.module("ini"));
tests.root_module.addImport("spoon", spoon.module("spoon"));
const test_step = b.step("test", "Run all tests");
test_step.dependOn(&tests.step);
}

View file

@ -6,16 +6,16 @@
.version = "0.1.0",
.dependencies = .{
.ini = .{
.url = "https://git.sr.ht/~leon_plickat/zig-ini/archive/v1.0.1.tar.gz",
.hash = "1220da4f57e15f09ef2b636eebfee38f08e3e50ad96dbe9d9046bfd97d9047df42b7",
.url = "https://git.sr.ht/~leon_plickat/zig-ini/archive/879c74a3a801d49fa34343aebd55a22f591899b3.tar.gz",
.hash = "12201bbf05e1fb73323a9b13d2599dc4bf82851e6d328d7523a1af5b861a87edf286",
},
.exre = .{
.url = "https://git.sr.ht/~leon_plickat/zig-exre/archive/7684b3d5289810dc0d50adb3340aadeaff445981.tar.gz",
.hash = "122012f085104cb9544203411aff1d46abe040831c58e6916903fbe9fb0c36e12b45",
.url = "https://git.sr.ht/~leon_plickat/zig-exre/archive/565ff0a83ea62389714ad439c49fa6bfdc21f5a9.tar.gz",
.hash = "1220c65aff8d8dd585df1ca026dc5d5860977cd0e303340029b77549ebb9c882b8c7",
},
.spoon = .{
.url = "https://git.sr.ht/~leon_plickat/zig-spoon/archive/9fa5bb1eafc30b3ff0cbe297a3e0f51dbc903831.tar.gz",
.hash = "122028572fcf87ae047f602c1ed806fc5ab8f59107152a54feaa9017247180349940",
.url = "https://git.sr.ht/~leon_plickat/zig-spoon/archive/fdba8e643c9558254bf4e6c600dfbd782fa7a267.tar.gz",
.hash = "12202727aaaf0e742d4945be55af1ace8b25902095e0c1b0a24b70cc80a81b7ac518",
},
},
}

View file

@ -26,6 +26,7 @@ const mem = std.mem;
const meta = std.meta;
const os = std.os;
const debug = std.debug;
const posix = std.posix;
const format = @import("format.zig");
const VisibilityConfig = @import("DirMap.zig").VisibilityConfig;
@ -369,11 +370,11 @@ pub fn init(self: *Self) !void {
try self.bind_modes.put(arena, cx_str_owned, .{});
const cx_mode = self.bind_modes.getPtr("C-x").?;
if (os.getenv("TERM")) |term| {
if (posix.getenv("TERM")) |term| {
// TODO BSD and other OSs?
if (mem.eql(u8, term, "linux")) self.ascii_only = true;
}
if (os.getenv("NO_COLOR") != null) self.theme = themes.mono;
if (posix.getenv("NO_COLOR") != null) self.theme = themes.mono;
(try parseConfigFile(self)) orelse {};
try normal_mode.addBindIfUndefined(self, .{ "j", "arrow-down", "C-n" }, impl.@"cursor-move-down", .none);
@ -459,12 +460,12 @@ pub fn deinit(self: *Self) void {
fn parseConfigFile(self: *Self) !?void {
const path = blk: {
if (os.getenv("XDG_CONFIG_HOME")) |xdg_config_home| {
if (posix.getenv("XDG_CONFIG_HOME")) |xdg_config_home| {
break :blk try fs.path.join(context.alloc, &[_][]const u8{
xdg_config_home,
"nfm/config.ini",
});
} else if (os.getenv("HOME")) |home| {
} else if (posix.getenv("HOME")) |home| {
break :blk try fs.path.join(context.alloc, &[_][]const u8{
home,
".config/nfm/config.ini",
@ -474,7 +475,7 @@ fn parseConfigFile(self: *Self) !?void {
}
};
defer context.alloc.free(path);
os.access(path, os.R_OK) catch return null;
posix.access(path, posix.R_OK) catch return null;
const file = try fs.cwd().openFile(path, .{});
defer file.close();
@ -540,7 +541,7 @@ fn parseConfigFile(self: *Self) !?void {
}
fn parseBool(value: []const u8, path: []const u8, line: usize) !bool {
const bool_options = std.ComptimeStringMap(bool, .{
const bool_options = std.StaticStringMap(bool).initComptime(.{
.{ "true", true },
.{ "false", false },
});

View file

@ -27,6 +27,7 @@ const unicode = std.unicode;
const log = std.log.scoped(.context);
const debug = std.debug;
const ascii = std.ascii;
const posix = std.posix;
const system = @import("system.zig");
const Config = @import("Config.zig");
@ -60,7 +61,7 @@ dump_cwd: bool = false,
active_search: ?Regex = null,
killed: bool = false,
time_of_last_mark_clear: ?os.timespec = null,
time_of_last_mark_clear: ?posix.timespec = null,
// The GeneralPurposeAllocator is not the fastest right now, but this
// project has grown complex enough that the automated memory debugging it
@ -236,7 +237,7 @@ pub fn run(self: *Self, command: [:0]const u8, comptime name: []const u8) !void
/// Wrapper around Self.run(), creating an edit command for a file
/// using $EDITOR.
pub fn edit(self: *Self, dir: []const u8, file: []const u8) !void {
const editor = os.getenv("EDITOR") orelse {
const editor = posix.getenv("EDITOR") orelse {
self.titlebar.setMessageStatic(.err, "$EDITOR is not set");
return;
};
@ -530,7 +531,7 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void {
return;
},
'\t' => {
var token = buffer.getCompletionToken() orelse return;
const token = buffer.getCompletionToken() orelse return;
if (try self.completion(token)) |compl| {
buffer.killCompletionToken();
try buffer.insertQuotedSliceAtCursor(compl);

View file

@ -41,7 +41,7 @@ dir_extension: system.DirExtension = undefined,
last_selected_id: usize,
last_scroll_offset: usize = 0,
pub fn init(self: *Self, map: *DirMap, dir: fs.IterableDir, name: []const u8) !void {
pub fn init(self: *Self, map: *DirMap, dir: fs.Dir, name: []const u8) !void {
self.* = .{
.name = name,
.last_selected_id = math.maxInt(usize),

View file

@ -26,6 +26,7 @@ const mem = std.mem;
const os = std.os;
const sort = std.sort;
const log = std.log.scoped(.dirmap);
const posix = std.posix;
const Self = @This();
@ -214,7 +215,7 @@ dirs: std.StringHashMapUnmanaged(*Dir) = .{},
id_counter: usize = 0,
pub fn new() !Self {
var self = Self{};
const self = Self{};
return self;
}
@ -366,10 +367,8 @@ pub fn setCwd(self: *Self, _relpath: []const u8) !void {
if (_relpath.len == 1 and _relpath[0] == '.') return;
const relpath = blk: {
if (_relpath[0] == '~') {
// TODO: Maybe add an additional heap buffer that gets used when
// the stack buffer is not enough.
const home = os.getenv("HOME") orelse return error.EnvMissingHome;
var buf: [100]u8 = undefined;
const home = posix.getenv("HOME") orelse return error.EnvMissingHome;
var buf: [fs.max_path_bytes]u8 = undefined;
break :blk fmt.bufPrint(&buf, "{s}{s}", .{ home, _relpath[1..] }) catch return error.DirNameTooLong;
}
break :blk _relpath;
@ -399,14 +398,14 @@ fn collectGarbage(self: *Self) void {
}
pub fn setCwdRaw(self: *Self, relpath: []const u8) !void {
var _dir = try fs.cwd().openIterableDir(relpath, .{});
var _dir = try fs.cwd().openDir(relpath, .{ .iterate = true });
defer _dir.close();
try _dir.dir.setAsCwd();
try _dir.setAsCwd();
const dir_path = try _dir.dir.realpathAlloc(context.alloc, ".");
const dir_path = try _dir.realpathAlloc(context.alloc, ".");
errdefer context.alloc.free(dir_path);
var mapentry = try self.dirs.getOrPut(context.alloc, dir_path);
const mapentry = try self.dirs.getOrPut(context.alloc, dir_path);
if (!mapentry.found_existing) {
mapentry.value_ptr.* = try context.alloc.create(Dir);
try mapentry.value_ptr.*.init(self, _dir, dir_path);

View file

@ -38,7 +38,7 @@ pub fn new(alloc: mem.Allocator) Self {
}
pub fn newWithCapacity(alloc: mem.Allocator, cap: usize) !Self {
var ret = Self{
const ret = Self{
.alloc = alloc,
.buffer = try std.ArrayListUnmanaged(u8).initCapacity(alloc, cap),
};
@ -109,7 +109,7 @@ test "EditableUTF8String.toOwnedSliceZ()" {
const testing = std.testing;
const str = "hello test";
var edbuf = try Self.from(testing.allocator, str);
var owned = edbuf.toOwnedSliceZ() orelse unreachable;
const owned = edbuf.toOwnedSliceZ() orelse unreachable;
defer testing.allocator.free(owned);
try testing.expectEqualSlices(u8, owned, str);
}
@ -128,7 +128,7 @@ pub fn moveCursorOneForward(self: *Self) void {
fn cursorRightOf(self: *Self, in: Cursor) ?Cursor {
if (in.byte == self.buffer.items.len) return null;
var i: usize = in.byte;
const i: usize = in.byte;
const len = unicode.utf8ByteSequenceLength(self.buffer.items[i]) catch unreachable;
debug.assert(in.byte + len <= self.buffer.items.len);
return Cursor{

View file

@ -23,6 +23,7 @@ const unicode = std.unicode;
const heap = std.heap;
const fmt = std.fmt;
const debug = std.debug;
const posix = std.posix;
const Dir = @import("Dir.zig");
@ -32,12 +33,12 @@ const context = &@import("nfm.zig").context;
dir: *Dir,
name: [:0]const u8,
kind: fs.IterableDir.Entry.Kind,
kind: fs.Dir.Entry.Kind,
mark: bool,
text: ?bool,
id: usize,
stat: os.system.Stat = mem.zeroes(os.system.Stat),
stat: os.linux.Stat = mem.zeroes(os.linux.Stat),
link_target: ?[]const u8 = null,
pub fn updateStats(self: *File) !void {
@ -58,7 +59,7 @@ pub fn updateStats(self: *File) !void {
break :blk try fmt.allocPrintZ(fba, "{s}/{s}", .{ self.dir.name, self.name });
};
_ = os.system.lstat(path, &self.stat);
_ = std.os.linux.lstat(path, &self.stat);
self.kind = fileKindFromStatMode(self.stat.mode);
if (self.kind == .sym_link) {
@ -66,21 +67,21 @@ pub fn updateStats(self: *File) !void {
// quickly overwrite them with different file types. So by the time we
// try to read the target, the file is no longer a link or no longer
// exists.
const target = os.readlinkZ(path, &buf) catch return;
const target = posix.readlinkZ(path, &buf) catch return;
self.link_target = try context.alloc.dupe(u8, target);
}
}
fn fileKindFromStatMode(mode: u32) fs.IterableDir.Entry.Kind {
fn fileKindFromStatMode(mode: u32) fs.Dir.Entry.Kind {
// TODO likely only works on linux.
return switch (mode & os.S.IFMT) {
os.S.IFBLK => .block_device,
os.S.IFCHR => .character_device,
os.S.IFDIR => .directory,
os.S.IFIFO => .named_pipe,
os.S.IFLNK => .sym_link,
os.S.IFREG => .file,
os.S.IFSOCK => .unix_domain_socket,
return switch (mode & posix.S.IFMT) {
posix.S.IFBLK => .block_device,
posix.S.IFCHR => .character_device,
posix.S.IFDIR => .directory,
posix.S.IFIFO => .named_pipe,
posix.S.IFLNK => .sym_link,
posix.S.IFREG => .file,
posix.S.IFSOCK => .unix_domain_socket,
else => .unknown,
};
}
@ -202,15 +203,15 @@ pub fn writeName(self: File, writer: anytype) !void {
pub fn writePermissions(self: File, writer: anytype) !void {
switch (context.config.permission_format) {
.text => {
try writer.writeByte(if (self.stat.mode & os.system.S.IRUSR > 0) 'r' else '-');
try writer.writeByte(if (self.stat.mode & os.system.S.IWUSR > 0) 'w' else '-');
try writer.writeByte(if (self.stat.mode & os.system.S.IXUSR > 0) 'x' else '-');
try writer.writeByte(if (self.stat.mode & os.system.S.IRGRP > 0) 'r' else '-');
try writer.writeByte(if (self.stat.mode & os.system.S.IWGRP > 0) 'w' else '-');
try writer.writeByte(if (self.stat.mode & os.system.S.IXGRP > 0) 'x' else '-');
try writer.writeByte(if (self.stat.mode & os.system.S.IROTH > 0) 'r' else '-');
try writer.writeByte(if (self.stat.mode & os.system.S.IWOTH > 0) 'w' else '-');
try writer.writeByte(if (self.stat.mode & os.system.S.IXOTH > 0) 'x' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IRUSR > 0) 'r' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IWUSR > 0) 'w' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IXUSR > 0) 'x' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IRGRP > 0) 'r' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IWGRP > 0) 'w' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IXGRP > 0) 'x' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IROTH > 0) 'r' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IWOTH > 0) 'w' else '-');
try writer.writeByte(if (self.stat.mode & posix.S.IXOTH > 0) 'x' else '-');
try writer.writeByte(' ');
},
.octal => try writer.print("{o} ", .{@as(u9, @truncate(self.stat.mode))}),

View file

@ -3,6 +3,7 @@ const fs = std.fs;
const mem = std.mem;
const os = std.os;
const heap = std.heap;
const posix = std.posix;
const Path = @This();
@ -16,11 +17,11 @@ pub fn new(alloc: mem.Allocator) !Path {
};
errdefer ret.deinit();
const all_paths = os.getenv("PATH") orelse return error.PathNotSet;
const all_paths = posix.getenv("PATH") orelse return error.PathNotSet;
var it = mem.split(u8, all_paths, ":");
while (it.next()) |path| {
var dir = fs.cwd().openIterableDir(path, .{}) catch |err| {
var dir = fs.cwd().openDir(path, .{ .iterate = true }) catch |err| {
switch (err) {
error.FileNotFound,
error.NotDir,

View file

@ -109,7 +109,7 @@ pub fn init(self: *Self) !void {
pub fn deinit(self: *Self) void {
// zig-spoon auto-cooks the terminal on deinit if necessary.
self.term.deinit();
self.term.deinit() catch {};
}
pub fn start(self: *Self) !void {

View file

@ -19,6 +19,7 @@ const ascii = std.ascii;
const mem = std.mem;
const io = std.io;
const os = std.os;
const posix = std.posix;
const KeyOperation = @import("../Config.zig").KeyOperation;
@ -97,7 +98,7 @@ pub fn commitMarksImpl(key_operation: *const KeyOperation) !void {
if (file.isTextFile()) |is_text| {
if (is_text) {
if (multi_editor == null) {
const editor = os.getenv("EDITOR") orelse {
const editor = posix.getenv("EDITOR") orelse {
context.titlebar.setMessageStatic(.err, "$EDITOR is not set");
return;
};
@ -142,7 +143,7 @@ fn isTextFileErrorMessage(err: anyerror) !void {
}
fn dumpSelection() !void {
var writer = io.getStdOut().writer();
const writer = io.getStdOut().writer();
var mark = false;
var it = context.dirmap.markIterator();
while (it.next()) |file| {

View file

@ -17,6 +17,7 @@
const std = @import("std");
const os = std.os;
const time = std.time;
const posix = std.posix;
const KeyOperation = @import("../Config.zig").KeyOperation;
@ -56,8 +57,8 @@ pub fn clearMarks(_: *const KeyOperation) !void {
// If this has been called two times with a delay of less than a second,
// clear all marks.
var now: os.timespec = undefined;
os.clock_gettime(os.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
var now: posix.timespec = undefined;
posix.clock_gettime(posix.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
if (context.time_of_last_mark_clear) |last| {
if (timespecDiffLessThanOneSecond(now, last)) {
// This automatically collects gargbae.
@ -77,7 +78,7 @@ pub fn clearMarks(_: *const KeyOperation) !void {
context.ui.list_dirty = true;
}
fn timespecDiffLessThanOneSecond(a: os.timespec, b: os.timespec) bool {
fn timespecDiffLessThanOneSecond(a: posix.timespec, b: posix.timespec) bool {
const diff: isize = blk: {
if ((a.tv_nsec - b.tv_nsec) < 0) {
const diff_sec = (a.tv_sec - b.tv_sec) - 1;

View file

@ -58,7 +58,7 @@ pub const EventLoop = struct {
loop: bool,
epoll_fd: i32,
inotify_fd: os.fd_t,
inotify_fd: std.posix.fd_t,
inotify_ev: os.linux.epoll_event,
tty_ev: os.linux.epoll_event,
inotify_move_queue: std.ArrayListUnmanaged(InotifyMove),
@ -70,15 +70,15 @@ pub const EventLoop = struct {
self.inotify_move_queue = .{};
// Init epoll.
self.epoll_fd = try os.epoll_create1(0);
self.epoll_fd = try std.posix.epoll_create1(0);
// Init inotify.
self.inotify_fd = try os.inotify_init1(0);
self.inotify_fd = try std.posix.inotify_init1(0);
self.inotify_ev = .{
.events = os.linux.EPOLL.IN,
.data = .{ .u32 = PollIndex.inotify },
};
try os.epoll_ctl(
try std.posix.epoll_ctl(
self.epoll_fd,
os.linux.EPOLL.CTL_ADD,
self.inotify_fd,
@ -89,7 +89,7 @@ pub const EventLoop = struct {
pub fn deinit(self: *Self) void {
log.debug("deinit'ing epoll and inotify", .{});
os.close(self.epoll_fd);
std.posix.close(self.epoll_fd);
// TODO deinit inotify
@ -100,12 +100,12 @@ pub const EventLoop = struct {
self.loop = false;
}
pub fn addTerminalFd(self: *Self, fd: os.fd_t) !void {
pub fn addTerminalFd(self: *Self, fd: std.posix.fd_t) !void {
self.tty_ev = .{
.events = os.linux.EPOLL.IN,
.data = .{ .u32 = PollIndex.ui },
};
try os.epoll_ctl(
try std.posix.epoll_ctl(
self.epoll_fd,
os.linux.EPOLL.CTL_ADD,
fd,
@ -114,7 +114,7 @@ pub const EventLoop = struct {
}
pub fn watchDir(self: *Self, dir: *Dir, full_path: []const u8) void {
dir.dir_extension = os.inotify_add_watch(
dir.dir_extension = std.posix.inotify_add_watch(
self.inotify_fd,
full_path,
os.linux.IN.CREATE | os.linux.IN.DELETE | os.linux.IN.DELETE_SELF |
@ -127,7 +127,7 @@ pub const EventLoop = struct {
pub fn unwatchDir(self: *Self, dir: *Dir) void {
if (dir.dir_extension) |wd| {
os.inotify_rm_watch(self.inotify_fd, wd);
std.posix.inotify_rm_watch(self.inotify_fd, wd);
}
}
@ -186,7 +186,7 @@ pub const EventLoop = struct {
}
var buf: [4096]u8 align(@alignOf(os.linux.inotify_event)) = undefined;
const read = try os.read(self.inotify_fd, &buf);
const read = try std.posix.read(self.inotify_fd, &buf);
if (read == 0) return;
var ptr: [*]u8 = &buf;

View file

@ -8,7 +8,7 @@ const log = std.log.scoped(.system_posix);
const context = &@import("../nfm.zig").context;
const loop = &@import("../nfm.zig").loop;
var child_pid: ?os.pid_t = null;
var child_pid: ?std.posix.pid_t = null;
/// POSIX bits missing from zigs std.
/// TODO [zig]
@ -18,7 +18,7 @@ const missme = switch (builtin.os.tag) {
return os.linux.syscall0(.setsid);
}
pub fn umask(mask: os.mode_t) usize {
pub fn umask(mask: std.posix.mode_t) usize {
return os.linux.syscall1(.umask, @as(usize, @bitCast(mask)));
}
},
@ -30,29 +30,29 @@ const missme = switch (builtin.os.tag) {
};
pub fn installSignalHandlers() !void {
try os.sigaction(os.SIG.TERM, &os.Sigaction{
try std.posix.sigaction(std.posix.SIG.TERM, &std.posix.Sigaction{
.handler = .{ .handler = handleSigTerm },
.mask = os.empty_sigset,
.mask = std.posix.empty_sigset,
.flags = 0,
}, null);
try os.sigaction(os.SIG.INT, &os.Sigaction{
try std.posix.sigaction(std.posix.SIG.INT, &std.posix.Sigaction{
.handler = .{ .handler = handleSigTerm },
.mask = os.empty_sigset,
.mask = std.posix.empty_sigset,
.flags = 0,
}, null);
// Someone honestly thought that the best way to make terminal programs
// aware of a size change is a signal...
try os.sigaction(os.SIG.WINCH, &os.Sigaction{
try std.posix.sigaction(std.posix.SIG.WINCH, &std.posix.Sigaction{
.handler = .{ .handler = handleSigWinch },
.mask = os.empty_sigset,
.mask = std.posix.empty_sigset,
.flags = 0,
}, null);
}
fn handleSigTerm(sig: c_int) callconv(.C) void {
if (child_pid) |cpid| {
os.kill(cpid, @as(u8, @intCast(sig))) catch {};
std.posix.kill(cpid, @as(u8, @intCast(sig))) catch {};
} else {
context.killed = true;
loop.stop();
@ -76,17 +76,17 @@ fn handleSigWinch(_: c_int) callconv(.C) void {
pub fn execForeground(cmd: [:0]const u8) !void {
log.debug("running foreground command: '{s}'", .{cmd});
const args = [_:null]?[*:0]const u8{ "/bin/sh", "-c", cmd, null };
const pid = os.fork() catch try os.fork();
const pid = std.posix.fork() catch try std.posix.fork();
if (pid == 0) {
os.execveZ("/bin/sh", &args, @as([*:null]?[*:0]u8, @ptrCast(os.environ.ptr))) catch os.exit(1);
std.posix.execveZ("/bin/sh", &args, @as([*:null]?[*:0]u8, @ptrCast(os.environ.ptr))) catch std.posix.exit(1);
unreachable;
} else {
child_pid = pid;
defer child_pid = null;
const stat = os.waitpid(pid, 0);
if (os.W.IFSIGNALED(stat.status)) return error.KilledBySignal;
if (os.W.IFEXITED(stat.status)) {
const exit = os.W.EXITSTATUS(stat.status);
const stat = std.posix.waitpid(pid, 0);
if (std.posix.W.IFSIGNALED(stat.status)) return error.KilledBySignal;
if (std.posix.W.IFEXITED(stat.status)) {
const exit = std.posix.W.EXITSTATUS(stat.status);
if (exit == 127) return error.UnknownCommand;
if (exit != 0) return error.NonZeroExit;
}
@ -99,7 +99,7 @@ pub fn execBackground(cmd: [:0]const u8) !void {
const args = [_:null]?[*:0]const u8{ "/bin/sh", "-c", cmd, null };
// Create first child.
const pid = os.fork() catch try os.fork();
const pid = std.posix.fork() catch try std.posix.fork();
if (pid == 0) {
// Make the forked child process group / session leader. We (the
// child process) now have lost our controlling terminal.
@ -108,7 +108,7 @@ pub fn execBackground(cmd: [:0]const u8) !void {
// Create second child. This is not a process group leader and as
// soon as the first child exits, the second child will have no
// way of ever aqcuiring a controlling terminal again.
const pid2 = os.fork() catch os.fork() catch os.exit(1);
const pid2 = std.posix.fork() catch std.posix.fork() catch std.posix.exit(1);
if (pid2 == 0) {
// Reset file create mode.
_ = missme.umask(0);
@ -117,25 +117,25 @@ pub fn execBackground(cmd: [:0]const u8) !void {
// background process we spawn to mess with our terminal. Then open
// new fd's for the standard channels as leaving them closed is
// undefined behaviour
const nullfd = os.open("/dev/null", 0, 0) catch os.exit(1);
const nullfd = std.posix.open("/dev/null", .{}, 0) catch std.posix.exit(1);
inline for ([_]u8{ 0, 1, 2 }) |fd| {
os.close(fd);
os.dup2(nullfd, fd) catch os.dup2(nullfd, fd) catch os.exit(1);
std.posix.close(fd);
std.posix.dup2(nullfd, fd) catch std.posix.dup2(nullfd, fd) catch std.posix.exit(1);
}
// Execute the command, or die should we fail.
os.execveZ("/bin/sh", &args, @as([*:null]?[*:0]u8, @ptrCast(os.environ.ptr))) catch os.exit(1);
std.posix.execveZ("/bin/sh", &args, @as([*:null]?[*:0]u8, @ptrCast(os.environ.ptr))) catch std.posix.exit(1);
unreachable;
} else {
// Exit first child immediately.
os.exit(0);
std.posix.exit(0);
}
} else {
// Wait for first child to die before we move on.
const stat = os.waitpid(pid, 0);
if (os.W.IFSIGNALED(stat.status)) return error.KilledBySignal;
if (os.W.IFEXITED(stat.status)) {
const exit = os.W.EXITSTATUS(stat.status);
const stat = std.posix.waitpid(pid, 0);
if (std.posix.W.IFSIGNALED(stat.status)) return error.KilledBySignal;
if (std.posix.W.IFEXITED(stat.status)) {
const exit = std.posix.W.EXITSTATUS(stat.status);
if (exit != 0) return error.FailedSecondFork;
}
}