| ... | ... | @@ -7191,35 +7191,57 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex |
| 7191 | 7191 | return error.FileNotFound; |
| 7192 | 7192 | |
| 7193 | 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 | 7195 | // argv[0] is a path (relative or absolute): use realpath(3) directly |
| 7196 | | var real_path_buf: [posix.PATH_MAX]u8 = undefined; |
| 7197 | | const real_path_len = Io.Dir.realPathFileAbsolute(ioBasic(t), argv0, &real_path_buf) catch |err| switch (err) { |
| 7198 | | error.NetworkNotFound => unreachable, // Windows-only |
| 7199 | | else => |e| return e, |
| 7200 | | }; |
| 7201 | | if (real_path_len > out_buffer.len) |
| 7196 | const current_thread = Thread.getCurrent(t); |
| 7197 | var resolved_buf: [std.c.PATH_MAX]u8 = undefined; |
| 7198 | { |
| 7199 | try current_thread.beginSyscall(); |
| 7200 | defer current_thread.endSyscall(); |
| 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 | 7216 | return error.NameTooLong; |
| 7203 | | @memcpy(out_buffer[0..real_path_len], real_path_buf[0..real_path_len]); |
| 7204 | | return real_path_len; |
| 7217 | @memcpy(out_buffer[0..resolved.len], resolved); |
| 7218 | return resolved.len; |
| 7205 | 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 | 7222 | const PATH = posix.getenvZ("PATH") orelse return error.FileNotFound; |
| 7208 | | var path_it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter); |
| 7209 | | while (path_it.next()) |a_path| { |
| 7210 | | var resolved_path_buf: [posix.PATH_MAX - 1:0]u8 = undefined; |
| 7211 | | const resolved_path = std.fmt.bufPrintSentinel(&resolved_path_buf, "{s}/{s}", .{ |
| 7212 | | a_path, std.os.argv[0], |
| 7213 | | }, 0) catch continue; |
| 7214 | | |
| 7215 | | var real_path_buf: [posix.PATH_MAX]u8 = undefined; |
| 7216 | | if (Io.Dir.realPathFileAbsolute(ioBasic(t), resolved_path, &real_path_buf)) |real_path_len| { |
| 7217 | | // found a file, and hope it is the right file |
| 7218 | | if (real_path_len > out_buffer.len) |
| 7219 | | return error.NameTooLong; |
| 7220 | | @memcpy(out_buffer[0..real_path_len], real_path_buf[0..real_path_len]); |
| 7221 | | return real_path_len; |
| 7222 | | } else |_| continue; |
| 7223 | var it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter); |
| 7224 | while (it.next()) |dir| { |
| 7225 | var prospect_buf: [std.c.PATH_MAX]u8 = undefined; |
| 7226 | _ = std.fmt.bufPrintSentinel( |
| 7227 | &prospect_buf, |
| 7228 | "{s}" ++ std.fs.path.sep_str_posix ++ "{s}", |
| 7229 | .{ dir, std.os.argv[0] }, |
| 7230 | 0, |
| 7231 | ) catch continue; |
| 7232 | |
| 7233 | var resolved_buf: [std.c.PATH_MAX]u8 = undefined; |
| 7234 | try current_thread.beginSyscall(); |
| 7235 | _ = std.c.realpath(@ptrCast(&prospect_buf), &resolved_buf) orelse { |
| 7236 | current_thread.endSyscall(); |
| 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 | 7247 | return error.FileNotFound; |