40 lines
2.0 KiB
Zig
40 lines
2.0 KiB
Zig
//! Pure path utilities for the VFS mount router — no IPC, no state, so they are
|
|
//! host-testable in isolation. The router uses these to decide whether an opened
|
|
//! path lies under a mount point and, if so, what it looks like relative to that
|
|
//! mount.
|
|
|
|
const std = @import("std");
|
|
|
|
/// If `path` lies under `mount_prefix` — equal to it, or the prefix followed by a
|
|
/// path separator — return the path relative to the mount ("/" for an exact
|
|
/// match, otherwise the tail beginning with '/'). Returns null when `path` is not
|
|
/// under the mount, so a prefix like "/mnt/usb" never captures "/mnt/usbextra".
|
|
pub fn underMount(path: []const u8, mount_prefix: []const u8) ?[]const u8 {
|
|
if (path.len < mount_prefix.len) return null;
|
|
if (!std.mem.eql(u8, path[0..mount_prefix.len], mount_prefix)) return null;
|
|
if (path.len == mount_prefix.len) return "/";
|
|
if (path[mount_prefix.len] != '/') return null;
|
|
return path[mount_prefix.len..];
|
|
}
|
|
|
|
/// Whether `path` is absolute (rooted at '/'). Bare names — what the flat ramfs
|
|
/// uses — are relative and never route through a mount.
|
|
pub fn isAbsolute(path: []const u8) bool {
|
|
return path.len > 0 and path[0] == '/';
|
|
}
|
|
|
|
test "underMount matches only at path boundaries" {
|
|
try std.testing.expectEqualStrings("/", underMount("/mnt/usb", "/mnt/usb").?);
|
|
try std.testing.expectEqualStrings("/system/kernel", underMount("/mnt/usb/system/kernel", "/mnt/usb").?);
|
|
try std.testing.expect(underMount("/mnt/usbextra", "/mnt/usb") == null); // not a boundary
|
|
try std.testing.expect(underMount("/mnt", "/mnt/usb") == null); // shorter than the prefix
|
|
try std.testing.expect(underMount("/other", "/mnt/usb") == null);
|
|
try std.testing.expect(underMount("greeting", "/mnt/usb") == null); // a bare name
|
|
}
|
|
|
|
test "isAbsolute distinguishes paths from bare names" {
|
|
try std.testing.expect(isAbsolute("/mnt/usb"));
|
|
try std.testing.expect(!isAbsolute("greeting"));
|
|
try std.testing.expect(!isAbsolute(""));
|
|
}
|