port to Zig 0.13.0
This commit is contained in:
parent
b584002850
commit
e08e44c43c
16 changed files with 109 additions and 109 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
zig-cache/
|
||||
.zig-cache/
|
||||
zig-out/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
16
build.zig
16
build.zig
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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{
|
||||
|
|
45
src/File.zig
45
src/File.zig
|
@ -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))}),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue