mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
std.Io: introduce openSelfExe
This commit is contained in:
parent
1c67607397
commit
6d1b2c7f64
@ -678,6 +678,7 @@ pub const VTable = struct {
|
||||
fileReadPositional: *const fn (?*anyopaque, File, data: [][]u8, offset: u64) File.ReadPositionalError!usize,
|
||||
fileSeekBy: *const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void,
|
||||
fileSeekTo: *const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void,
|
||||
openSelfExe: *const fn (?*anyopaque, File.OpenFlags) File.OpenSelfExeError!File,
|
||||
|
||||
now: *const fn (?*anyopaque, Clock) Clock.Error!Timestamp,
|
||||
sleep: *const fn (?*anyopaque, Timeout) SleepError!void,
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
const Dir = @This();
|
||||
|
||||
const builtin = @import("builtin");
|
||||
const native_os = builtin.os.tag;
|
||||
|
||||
const std = @import("../std.zig");
|
||||
const Io = std.Io;
|
||||
const File = Io.File;
|
||||
@ -9,8 +12,20 @@ handle: Handle,
|
||||
pub const Mode = Io.File.Mode;
|
||||
pub const default_mode: Mode = 0o755;
|
||||
|
||||
/// Returns a handle to the current working directory.
|
||||
///
|
||||
/// It is not opened with iteration capability. Iterating over the result is
|
||||
/// illegal behavior.
|
||||
///
|
||||
/// Closing the returned `Dir` is checked illegal behavior.
|
||||
///
|
||||
/// On POSIX targets, this function is comptime-callable.
|
||||
pub fn cwd() Dir {
|
||||
return .{ .handle = std.fs.cwd().fd };
|
||||
return switch (native_os) {
|
||||
.windows => .{ .handle = std.os.windows.peb().ProcessParameters.CurrentDirectory.Handle },
|
||||
.wasi => .{ .handle = std.options.wasiCwd() },
|
||||
else => .{ .handle = std.posix.AT.FDCWD },
|
||||
};
|
||||
}
|
||||
|
||||
pub const Handle = std.posix.fd_t;
|
||||
|
||||
@ -207,6 +207,12 @@ pub fn close(file: File, io: Io) void {
|
||||
return io.vtable.fileClose(io.userdata, file);
|
||||
}
|
||||
|
||||
pub const OpenSelfExeError = OpenError || std.fs.SelfExePathError || std.posix.FlockError;
|
||||
|
||||
pub fn openSelfExe(io: Io, flags: OpenFlags) OpenSelfExeError!File {
|
||||
return io.vtable.openSelfExe(io.userdata, flags);
|
||||
}
|
||||
|
||||
pub const ReadStreamingError = error{
|
||||
InputOutput,
|
||||
SystemResources,
|
||||
|
||||
@ -209,6 +209,7 @@ pub fn io(t: *Threaded) Io {
|
||||
.fileReadPositional = fileReadPositional,
|
||||
.fileSeekBy = fileSeekBy,
|
||||
.fileSeekTo = fileSeekTo,
|
||||
.openSelfExe = openSelfExe,
|
||||
|
||||
.now = switch (builtin.os.tag) {
|
||||
.windows => nowWindows,
|
||||
@ -2241,6 +2242,26 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
|
||||
}
|
||||
}
|
||||
|
||||
fn openSelfExe(userdata: ?*anyopaque, flags: Io.File.OpenFlags) Io.File.OpenSelfExeError!Io.File {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
if (native_os == .linux or native_os == .serenity) {
|
||||
return dirOpenFilePosix(t, .{ .handle = posix.AT.FDCWD }, "/proc/self/exe", flags);
|
||||
}
|
||||
if (is_windows) {
|
||||
// If ImagePathName is a symlink, then it will contain the path of the symlink,
|
||||
// not the path that the symlink points to. However, because we are opening
|
||||
// the file, we can let the openFileW call follow the symlink for us.
|
||||
const image_path_unicode_string = &windows.peb().ProcessParameters.ImagePathName;
|
||||
const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];
|
||||
const prefixed_path_w_array = try windows.wToPrefixedFileW(null, image_path_name);
|
||||
const prefixed_path_w = prefixed_path_w_array.span();
|
||||
const cwd_handle = std.os.windows.peb().ProcessParameters.CurrentDirectory.Handle;
|
||||
|
||||
return dirOpenFileWindows(t, .{ .handle = cwd_handle }, prefixed_path_w, flags);
|
||||
}
|
||||
@panic("TODO");
|
||||
}
|
||||
|
||||
fn fileWritePositional(
|
||||
userdata: ?*anyopaque,
|
||||
file: Io.File,
|
||||
|
||||
@ -297,17 +297,7 @@ const Module = struct {
|
||||
// a binary is produced with -gdwarf, since the section names are longer than 8 bytes.
|
||||
const mapped_file: ?DebugInfo.MappedFile = mapped: {
|
||||
if (!coff_obj.strtabRequired()) break :mapped null;
|
||||
var name_buffer: [windows.PATH_MAX_WIDE + 4:0]u16 = undefined;
|
||||
name_buffer[0..4].* = .{ '\\', '?', '?', '\\' }; // openFileAbsoluteW requires the prefix to be present
|
||||
const process_handle = windows.GetCurrentProcess();
|
||||
const len = windows.kernel32.GetModuleFileNameExW(
|
||||
process_handle,
|
||||
module.handle,
|
||||
name_buffer[4..],
|
||||
windows.PATH_MAX_WIDE,
|
||||
);
|
||||
if (len == 0) return error.MissingDebugInfo;
|
||||
const coff_file = fs.openFileAbsoluteW(name_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) {
|
||||
const coff_file = Io.File.openSelfExe(io, .{}) catch |err| switch (err) {
|
||||
error.Canceled => |e| return e,
|
||||
error.Unexpected => |e| return e,
|
||||
error.FileNotFound => return error.MissingDebugInfo,
|
||||
@ -337,9 +327,15 @@ const Module = struct {
|
||||
error.SystemFdQuotaExceeded,
|
||||
error.FileLocksNotSupported,
|
||||
error.FileBusy,
|
||||
error.InputOutput,
|
||||
error.NotSupported,
|
||||
error.FileSystem,
|
||||
error.NotLink,
|
||||
error.UnrecognizedVolume,
|
||||
error.UnknownName,
|
||||
=> return error.ReadFailed,
|
||||
};
|
||||
errdefer coff_file.close();
|
||||
errdefer coff_file.close(io);
|
||||
var section_handle: windows.HANDLE = undefined;
|
||||
const create_section_rc = windows.ntdll.NtCreateSection(
|
||||
§ion_handle,
|
||||
@ -356,6 +352,7 @@ const Module = struct {
|
||||
errdefer windows.CloseHandle(section_handle);
|
||||
var coff_len: usize = 0;
|
||||
var section_view_ptr: ?[*]const u8 = null;
|
||||
const process_handle = windows.GetCurrentProcess();
|
||||
const map_section_rc = windows.ntdll.NtMapViewOfSection(
|
||||
section_handle,
|
||||
process_handle,
|
||||
@ -373,7 +370,7 @@ const Module = struct {
|
||||
const section_view = section_view_ptr.?[0..coff_len];
|
||||
coff_obj = coff.Coff.init(section_view, false) catch return error.InvalidDebugInfo;
|
||||
break :mapped .{
|
||||
.file = coff_file,
|
||||
.file = .adaptFromNewApi(coff_file),
|
||||
.section_handle = section_handle,
|
||||
.section_view = section_view,
|
||||
};
|
||||
|
||||
@ -180,9 +180,7 @@ pub fn renameZ(old_dir: Dir, old_sub_path_z: [*:0]const u8, new_dir: Dir, new_su
|
||||
return posix.renameatZ(old_dir.fd, old_sub_path_z, new_dir.fd, new_sub_path_z);
|
||||
}
|
||||
|
||||
/// Returns a handle to the current working directory. It is not opened with iteration capability.
|
||||
/// Closing the returned `Dir` is checked illegal behavior. Iterating over the result is illegal behavior.
|
||||
/// On POSIX targets, this function is comptime-callable.
|
||||
/// Deprecated in favor of `Io.Dir.cwd`.
|
||||
pub fn cwd() Dir {
|
||||
if (native_os == .windows) {
|
||||
return .{ .fd = windows.peb().ProcessParameters.CurrentDirectory.Handle };
|
||||
@ -336,20 +334,14 @@ pub fn symLinkAbsoluteW(
|
||||
return windows.CreateSymbolicLink(null, mem.span(sym_link_path_w), mem.span(target_path_w), flags.is_directory);
|
||||
}
|
||||
|
||||
pub const OpenSelfExeError = posix.OpenError || SelfExePathError || posix.FlockError;
|
||||
pub const OpenSelfExeError = Io.File.OpenSelfExeError;
|
||||
|
||||
/// Deprecated in favor of `Io.File.openSelfExe`.
|
||||
pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File {
|
||||
if (native_os == .linux or native_os == .serenity) {
|
||||
return openFileAbsolute("/proc/self/exe", flags);
|
||||
}
|
||||
if (native_os == .windows) {
|
||||
// If ImagePathName is a symlink, then it will contain the path of the symlink,
|
||||
// not the path that the symlink points to. However, because we are opening
|
||||
// the file, we can let the openFileW call follow the symlink for us.
|
||||
const image_path_unicode_string = &windows.peb().ProcessParameters.ImagePathName;
|
||||
const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];
|
||||
const prefixed_path_w = try windows.wToPrefixedFileW(null, image_path_name);
|
||||
return cwd().openFileW(prefixed_path_w.span(), flags);
|
||||
if (native_os == .linux or native_os == .serenity or native_os == .windows) {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
return .adaptFromNewApi(try Io.File.openSelfExe(io, flags));
|
||||
}
|
||||
// Use of max_path_bytes here is valid as the resulting path is immediately
|
||||
// opened with no modification.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user