| author | |
| committer | |
| log | 6d1b2c7f64fd1a1c671f357cff96b3dd39612857 |
| tree | 996e692c2b132f48827de477da5a8777bd8ee1fb |
| parent | 1c67607397be4efa962d64a1d80b7fd91fe161eb |
6 files changed, 61 insertions(+), 29 deletions(-)
lib/std/Io.zig+1| ... | @@ -678,6 +678,7 @@ pub const VTable = struct { | ... | @@ -678,6 +678,7 @@ pub const VTable = struct { |
| 678 | fileReadPositional: *const fn (?*anyopaque, File, data: [][]u8, offset: u64) File.ReadPositionalError!usize, | 678 | fileReadPositional: *const fn (?*anyopaque, File, data: [][]u8, offset: u64) File.ReadPositionalError!usize, |
| 679 | fileSeekBy: *const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void, | 679 | fileSeekBy: *const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void, |
| 680 | fileSeekTo: *const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void, | 680 | fileSeekTo: *const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void, |
| 681 | openSelfExe: *const fn (?*anyopaque, File.OpenFlags) File.OpenSelfExeError!File, | ||
| 681 | 682 | ||
| 682 | now: *const fn (?*anyopaque, Clock) Clock.Error!Timestamp, | 683 | now: *const fn (?*anyopaque, Clock) Clock.Error!Timestamp, |
| 683 | sleep: *const fn (?*anyopaque, Timeout) SleepError!void, | 684 | sleep: *const fn (?*anyopaque, Timeout) SleepError!void, |
lib/std/Io/Dir.zig+16-1| ... | @@ -1,5 +1,8 @@ | ... | @@ -1,5 +1,8 @@ |
| 1 | const Dir = @This(); | 1 | const Dir = @This(); |
| 2 | 2 | ||
| 3 | const builtin = @import("builtin"); | ||
| 4 | const native_os = builtin.os.tag; | ||
| 5 | |||
| 3 | const std = @import("../std.zig"); | 6 | const std = @import("../std.zig"); |
| 4 | const Io = std.Io; | 7 | const Io = std.Io; |
| 5 | const File = Io.File; | 8 | const File = Io.File; |
| ... | @@ -9,8 +12,20 @@ handle: Handle, | ... | @@ -9,8 +12,20 @@ handle: Handle, |
| 9 | pub const Mode = Io.File.Mode; | 12 | pub const Mode = Io.File.Mode; |
| 10 | pub const default_mode: Mode = 0o755; | 13 | pub const default_mode: Mode = 0o755; |
| 11 | 14 | ||
| 15 | /// Returns a handle to the current working directory. | ||
| 16 | /// | ||
| 17 | /// It is not opened with iteration capability. Iterating over the result is | ||
| 18 | /// illegal behavior. | ||
| 19 | /// | ||
| 20 | /// Closing the returned `Dir` is checked illegal behavior. | ||
| 21 | /// | ||
| 22 | /// On POSIX targets, this function is comptime-callable. | ||
| 12 | pub fn cwd() Dir { | 23 | pub fn cwd() Dir { |
| 13 | return .{ .handle = std.fs.cwd().fd }; | 24 | return switch (native_os) { |
| 25 | .windows => .{ .handle = std.os.windows.peb().ProcessParameters.CurrentDirectory.Handle }, | ||
| 26 | .wasi => .{ .handle = std.options.wasiCwd() }, | ||
| 27 | else => .{ .handle = std.posix.AT.FDCWD }, | ||
| 28 | }; | ||
| 14 | } | 29 | } |
| 15 | 30 | ||
| 16 | pub const Handle = std.posix.fd_t; | 31 | pub const Handle = std.posix.fd_t; |
lib/std/Io/File.zig+6| ... | @@ -207,6 +207,12 @@ pub fn close(file: File, io: Io) void { | ... | @@ -207,6 +207,12 @@ pub fn close(file: File, io: Io) void { |
| 207 | return io.vtable.fileClose(io.userdata, file); | 207 | return io.vtable.fileClose(io.userdata, file); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | pub const OpenSelfExeError = OpenError || std.fs.SelfExePathError || std.posix.FlockError; | ||
| 211 | |||
| 212 | pub fn openSelfExe(io: Io, flags: OpenFlags) OpenSelfExeError!File { | ||
| 213 | return io.vtable.openSelfExe(io.userdata, flags); | ||
| 214 | } | ||
| 215 | |||
| 210 | pub const ReadStreamingError = error{ | 216 | pub const ReadStreamingError = error{ |
| 211 | InputOutput, | 217 | InputOutput, |
| 212 | SystemResources, | 218 | SystemResources, |
lib/std/Io/Threaded.zig+21| ... | @@ -209,6 +209,7 @@ pub fn io(t: *Threaded) Io { | ... | @@ -209,6 +209,7 @@ pub fn io(t: *Threaded) Io { |
| 209 | .fileReadPositional = fileReadPositional, | 209 | .fileReadPositional = fileReadPositional, |
| 210 | .fileSeekBy = fileSeekBy, | 210 | .fileSeekBy = fileSeekBy, |
| 211 | .fileSeekTo = fileSeekTo, | 211 | .fileSeekTo = fileSeekTo, |
| 212 | .openSelfExe = openSelfExe, | ||
| 212 | 213 | ||
| 213 | .now = switch (builtin.os.tag) { | 214 | .now = switch (builtin.os.tag) { |
| 214 | .windows => nowWindows, | 215 | .windows => nowWindows, |
| ... | @@ -2241,6 +2242,26 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr | ... | @@ -2241,6 +2242,26 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr |
| 2241 | } | 2242 | } |
| 2242 | } | 2243 | } |
| 2243 | 2244 | ||
| 2245 | fn openSelfExe(userdata: ?*anyopaque, flags: Io.File.OpenFlags) Io.File.OpenSelfExeError!Io.File { | ||
| 2246 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | ||
| 2247 | if (native_os == .linux or native_os == .serenity) { | ||
| 2248 | return dirOpenFilePosix(t, .{ .handle = posix.AT.FDCWD }, "/proc/self/exe", flags); | ||
| 2249 | } | ||
| 2250 | if (is_windows) { | ||
| 2251 | // If ImagePathName is a symlink, then it will contain the path of the symlink, | ||
| 2252 | // not the path that the symlink points to. However, because we are opening | ||
| 2253 | // the file, we can let the openFileW call follow the symlink for us. | ||
| 2254 | const image_path_unicode_string = &windows.peb().ProcessParameters.ImagePathName; | ||
| 2255 | const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0]; | ||
| 2256 | const prefixed_path_w_array = try windows.wToPrefixedFileW(null, image_path_name); | ||
| 2257 | const prefixed_path_w = prefixed_path_w_array.span(); | ||
| 2258 | const cwd_handle = std.os.windows.peb().ProcessParameters.CurrentDirectory.Handle; | ||
| 2259 | |||
| 2260 | return dirOpenFileWindows(t, .{ .handle = cwd_handle }, prefixed_path_w, flags); | ||
| 2261 | } | ||
| 2262 | @panic("TODO"); | ||
| 2263 | } | ||
| 2264 | |||
| 2244 | fn fileWritePositional( | 2265 | fn fileWritePositional( |
| 2245 | userdata: ?*anyopaque, | 2266 | userdata: ?*anyopaque, |
| 2246 | file: Io.File, | 2267 | file: Io.File, |
lib/std/debug/SelfInfo/Windows.zig+10-13| ... | @@ -297,17 +297,7 @@ const Module = struct { | ... | @@ -297,17 +297,7 @@ const Module = struct { |
| 297 | // a binary is produced with -gdwarf, since the section names are longer than 8 bytes. | 297 | // a binary is produced with -gdwarf, since the section names are longer than 8 bytes. |
| 298 | const mapped_file: ?DebugInfo.MappedFile = mapped: { | 298 | const mapped_file: ?DebugInfo.MappedFile = mapped: { |
| 299 | if (!coff_obj.strtabRequired()) break :mapped null; | 299 | if (!coff_obj.strtabRequired()) break :mapped null; |
| 300 | var name_buffer: [windows.PATH_MAX_WIDE + 4:0]u16 = undefined; | 300 | const coff_file = Io.File.openSelfExe(io, .{}) catch |err| switch (err) { |
| 301 | name_buffer[0..4].* = .{ '\\', '?', '?', '\\' }; // openFileAbsoluteW requires the prefix to be present | ||
| 302 | const process_handle = windows.GetCurrentProcess(); | ||
| 303 | const len = windows.kernel32.GetModuleFileNameExW( | ||
| 304 | process_handle, | ||
| 305 | module.handle, | ||
| 306 | name_buffer[4..], | ||
| 307 | windows.PATH_MAX_WIDE, | ||
| 308 | ); | ||
| 309 | if (len == 0) return error.MissingDebugInfo; | ||
| 310 | const coff_file = fs.openFileAbsoluteW(name_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) { | ||
| 311 | error.Canceled => |e| return e, | 301 | error.Canceled => |e| return e, |
| 312 | error.Unexpected => |e| return e, | 302 | error.Unexpected => |e| return e, |
| 313 | error.FileNotFound => return error.MissingDebugInfo, | 303 | error.FileNotFound => return error.MissingDebugInfo, |
| ... | @@ -337,9 +327,15 @@ const Module = struct { | ... | @@ -337,9 +327,15 @@ const Module = struct { |
| 337 | error.SystemFdQuotaExceeded, | 327 | error.SystemFdQuotaExceeded, |
| 338 | error.FileLocksNotSupported, | 328 | error.FileLocksNotSupported, |
| 339 | error.FileBusy, | 329 | error.FileBusy, |
| 330 | error.InputOutput, | ||
| 331 | error.NotSupported, | ||
| 332 | error.FileSystem, | ||
| 333 | error.NotLink, | ||
| 334 | error.UnrecognizedVolume, | ||
| 335 | error.UnknownName, | ||
| 340 | => return error.ReadFailed, | 336 | => return error.ReadFailed, |
| 341 | }; | 337 | }; |
| 342 | errdefer coff_file.close(); | 338 | errdefer coff_file.close(io); |
| 343 | var section_handle: windows.HANDLE = undefined; | 339 | var section_handle: windows.HANDLE = undefined; |
| 344 | const create_section_rc = windows.ntdll.NtCreateSection( | 340 | const create_section_rc = windows.ntdll.NtCreateSection( |
| 345 | &section_handle, | 341 | &section_handle, |
| ... | @@ -356,6 +352,7 @@ const Module = struct { | ... | @@ -356,6 +352,7 @@ const Module = struct { |
| 356 | errdefer windows.CloseHandle(section_handle); | 352 | errdefer windows.CloseHandle(section_handle); |
| 357 | var coff_len: usize = 0; | 353 | var coff_len: usize = 0; |
| 358 | var section_view_ptr: ?[*]const u8 = null; | 354 | var section_view_ptr: ?[*]const u8 = null; |
| 355 | const process_handle = windows.GetCurrentProcess(); | ||
| 359 | const map_section_rc = windows.ntdll.NtMapViewOfSection( | 356 | const map_section_rc = windows.ntdll.NtMapViewOfSection( |
| 360 | section_handle, | 357 | section_handle, |
| 361 | process_handle, | 358 | process_handle, |
| ... | @@ -373,7 +370,7 @@ const Module = struct { | ... | @@ -373,7 +370,7 @@ const Module = struct { |
| 373 | const section_view = section_view_ptr.?[0..coff_len]; | 370 | const section_view = section_view_ptr.?[0..coff_len]; |
| 374 | coff_obj = coff.Coff.init(section_view, false) catch return error.InvalidDebugInfo; | 371 | coff_obj = coff.Coff.init(section_view, false) catch return error.InvalidDebugInfo; |
| 375 | break :mapped .{ | 372 | break :mapped .{ |
| 376 | .file = coff_file, | 373 | .file = .adaptFromNewApi(coff_file), |
| 377 | .section_handle = section_handle, | 374 | .section_handle = section_handle, |
| 378 | .section_view = section_view, | 375 | .section_view = section_view, |
| 379 | }; | 376 | }; |
lib/std/fs.zig+7-15| ... | @@ -180,9 +180,7 @@ pub fn renameZ(old_dir: Dir, old_sub_path_z: [*:0]const u8, new_dir: Dir, new_su | ... | @@ -180,9 +180,7 @@ pub fn renameZ(old_dir: Dir, old_sub_path_z: [*:0]const u8, new_dir: Dir, new_su |
| 180 | return posix.renameatZ(old_dir.fd, old_sub_path_z, new_dir.fd, new_sub_path_z); | 180 | return posix.renameatZ(old_dir.fd, old_sub_path_z, new_dir.fd, new_sub_path_z); |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | /// Returns a handle to the current working directory. It is not opened with iteration capability. | 183 | /// Deprecated in favor of `Io.Dir.cwd`. |
| 184 | /// Closing the returned `Dir` is checked illegal behavior. Iterating over the result is illegal behavior. | ||
| 185 | /// On POSIX targets, this function is comptime-callable. | ||
| 186 | pub fn cwd() Dir { | 184 | pub fn cwd() Dir { |
| 187 | if (native_os == .windows) { | 185 | if (native_os == .windows) { |
| 188 | return .{ .fd = windows.peb().ProcessParameters.CurrentDirectory.Handle }; | 186 | return .{ .fd = windows.peb().ProcessParameters.CurrentDirectory.Handle }; |
| ... | @@ -336,20 +334,14 @@ pub fn symLinkAbsoluteW( | ... | @@ -336,20 +334,14 @@ pub fn symLinkAbsoluteW( |
| 336 | return windows.CreateSymbolicLink(null, mem.span(sym_link_path_w), mem.span(target_path_w), flags.is_directory); | 334 | return windows.CreateSymbolicLink(null, mem.span(sym_link_path_w), mem.span(target_path_w), flags.is_directory); |
| 337 | } | 335 | } |
| 338 | 336 | ||
| 339 | pub const OpenSelfExeError = posix.OpenError || SelfExePathError || posix.FlockError; | 337 | pub const OpenSelfExeError = Io.File.OpenSelfExeError; |
| 340 | 338 | ||
| 339 | /// Deprecated in favor of `Io.File.openSelfExe`. | ||
| 341 | pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File { | 340 | pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File { |
| 342 | if (native_os == .linux or native_os == .serenity) { | 341 | if (native_os == .linux or native_os == .serenity or native_os == .windows) { |
| 343 | return openFileAbsolute("/proc/self/exe", flags); | 342 | var threaded: Io.Threaded = .init_single_threaded; |
| 344 | } | 343 | const io = threaded.io(); |
| 345 | if (native_os == .windows) { | 344 | return .adaptFromNewApi(try Io.File.openSelfExe(io, flags)); |
| 346 | // If ImagePathName is a symlink, then it will contain the path of the symlink, | ||
| 347 | // not the path that the symlink points to. However, because we are opening | ||
| 348 | // the file, we can let the openFileW call follow the symlink for us. | ||
| 349 | const image_path_unicode_string = &windows.peb().ProcessParameters.ImagePathName; | ||
| 350 | const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0]; | ||
| 351 | const prefixed_path_w = try windows.wToPrefixedFileW(null, image_path_name); | ||
| 352 | return cwd().openFileW(prefixed_path_w.span(), flags); | ||
| 353 | } | 345 | } |
| 354 | // Use of max_path_bytes here is valid as the resulting path is immediately | 346 | // Use of max_path_bytes here is valid as the resulting path is immediately |
| 355 | // opened with no modification. | 347 | // opened with no modification. |