| ... | @@ -7191,35 +7191,57 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex | ... | @@ -7191,35 +7191,57 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex |
| 7191 | return error.FileNotFound; | 7191 | return error.FileNotFound; |
| 7192 | | 7192 | |
| 7193 | const argv0 = std.mem.span(std.os.argv[0]); | 7193 | const argv0 = std.mem.span(std.os.argv[0]); |
| 7194 | if (std.mem.indexOf(u8, argv0, "/") != null) { | 7194 | if (std.mem.findScalar(u8, argv0, std.fs.path.sep_posix) != null) { |
| 7195 | // argv[0] is a path (relative or absolute): use realpath(3) directly | 7195 | // argv[0] is a path (relative or absolute): use realpath(3) directly |
| 7196 | var real_path_buf: [posix.PATH_MAX]u8 = undefined; | 7196 | const current_thread = Thread.getCurrent(t); |
| 7197 | const real_path_len = Io.Dir.realPathFileAbsolute(ioBasic(t), argv0, &real_path_buf) catch |err| switch (err) { | 7197 | var resolved_buf: [std.c.PATH_MAX]u8 = undefined; |
| 7198 | error.NetworkNotFound => unreachable, // Windows-only | 7198 | { |
| 7199 | else => |e| return e, | 7199 | try current_thread.beginSyscall(); |
| 7200 | }; | 7200 | defer current_thread.endSyscall(); |
| 7201 | if (real_path_len > out_buffer.len) | 7201 | _ = std.c.realpath(std.os.argv[0], &resolved_buf) orelse switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) { |
| | 7202 | .SUCCESS => unreachable, |
| | 7203 | .ACCES => return error.AccessDenied, |
| | 7204 | .INVAL => unreachable, // the pathname argument is a null pointer |
| | 7205 | .IO => return error.InputOutput, |
| | 7206 | .LOOP => return error.SymLinkLoop, |
| | 7207 | .NAMETOOLONG => return error.NameTooLong, |
| | 7208 | .NOENT => return error.FileNotFound, |
| | 7209 | .NOTDIR => return error.NotDir, |
| | 7210 | .NOMEM => unreachable, // sufficient storage space is unavailable for allocation |
| | 7211 | else => |err| return posix.unexpectedErrno(err), |
| | 7212 | }; |
| | 7213 | } |
| | 7214 | const resolved = std.mem.sliceTo(&resolved_buf, 0); |
| | 7215 | if (resolved.len > out_buffer.len) |
| 7202 | return error.NameTooLong; | 7216 | return error.NameTooLong; |
| 7203 | @memcpy(out_buffer[0..real_path_len], real_path_buf[0..real_path_len]); | 7217 | @memcpy(out_buffer[0..resolved.len], resolved); |
| 7204 | return real_path_len; | 7218 | return resolved.len; |
| 7205 | } else if (argv0.len != 0) { | 7219 | } else if (argv0.len != 0) { |
| 7206 | // argv[0] is not empty (and not a path): search it inside PATH | 7220 | // argv[0] is not empty (and not a path): search PATH |
| | 7221 | const current_thread = Thread.getCurrent(t); |
| 7207 | const PATH = posix.getenvZ("PATH") orelse return error.FileNotFound; | 7222 | const PATH = posix.getenvZ("PATH") orelse return error.FileNotFound; |
| 7208 | var path_it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter); | 7223 | var it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter); |
| 7209 | while (path_it.next()) |a_path| { | 7224 | while (it.next()) |dir| { |
| 7210 | var resolved_path_buf: [posix.PATH_MAX - 1:0]u8 = undefined; | 7225 | var prospect_buf: [std.c.PATH_MAX]u8 = undefined; |
| 7211 | const resolved_path = std.fmt.bufPrintSentinel(&resolved_path_buf, "{s}/{s}", .{ | 7226 | _ = std.fmt.bufPrintSentinel( |
| 7212 | a_path, std.os.argv[0], | 7227 | &prospect_buf, |
| 7213 | }, 0) catch continue; | 7228 | "{s}" ++ std.fs.path.sep_str_posix ++ "{s}", |
| 7214 | | 7229 | .{ dir, std.os.argv[0] }, |
| 7215 | var real_path_buf: [posix.PATH_MAX]u8 = undefined; | 7230 | 0, |
| 7216 | if (Io.Dir.realPathFileAbsolute(ioBasic(t), resolved_path, &real_path_buf)) |real_path_len| { | 7231 | ) catch continue; |
| 7217 | // found a file, and hope it is the right file | 7232 | |
| 7218 | if (real_path_len > out_buffer.len) | 7233 | var resolved_buf: [std.c.PATH_MAX]u8 = undefined; |
| 7219 | return error.NameTooLong; | 7234 | try current_thread.beginSyscall(); |
| 7220 | @memcpy(out_buffer[0..real_path_len], real_path_buf[0..real_path_len]); | 7235 | _ = std.c.realpath(@ptrCast(&prospect_buf), &resolved_buf) orelse { |
| 7221 | return real_path_len; | 7236 | current_thread.endSyscall(); |
| 7222 | } else |_| continue; | 7237 | continue; |
| | 7238 | }; |
| | 7239 | current_thread.endSyscall(); |
| | 7240 | const resolved = std.mem.sliceTo(&resolved_buf, 0); |
| | 7241 | if (resolved.len > out_buffer.len) |
| | 7242 | return error.NameTooLong; |
| | 7243 | @memcpy(out_buffer[0..resolved.len], resolved); |
| | 7244 | return resolved.len; |
| 7223 | } | 7245 | } |
| 7224 | } | 7246 | } |
| 7225 | return error.FileNotFound; | 7247 | return error.FileNotFound; |