| ... | @@ -158,57 +158,18 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix. | ... | @@ -158,57 +158,18 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix. |
| 158 | return target; | 158 | return target; |
| 159 | }, | 159 | }, |
| 160 | .freebsd => { | 160 | .freebsd => { |
| 161 | if (builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) { | 161 | var kfile: std.c.kinfo_file = undefined; |
| 162 | var kfile: std.c.kinfo_file = undefined; | 162 | kfile.structsize = std.c.KINFO_FILE_SIZE; |
| 163 | kfile.structsize = std.c.KINFO_FILE_SIZE; | 163 | switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&kfile)))) { |
| 164 | switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&kfile)))) { | 164 | .SUCCESS => {}, |
| 165 | .SUCCESS => {}, | 165 | .BADF => return error.FileNotFound, |
| 166 | .BADF => return error.FileNotFound, | 166 | else => |err| return posix.unexpectedErrno(err), |
| 167 | else => |err| return posix.unexpectedErrno(err), | | |
| 168 | } | | |
| 169 | const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse max_path_bytes; | | |
| 170 | if (len == 0) return error.NameTooLong; | | |
| 171 | const result = out_buffer[0..len]; | | |
| 172 | @memcpy(result, kfile.path[0..len]); | | |
| 173 | return result; | | |
| 174 | } else { | | |
| 175 | // This fallback implementation reimplements libutil's `kinfo_getfile()`. | | |
| 176 | // The motivation is to avoid linking -lutil when building zig or general | | |
| 177 | // user executables. | | |
| 178 | var mib = [4]c_int{ posix.CTL.KERN, posix.KERN.PROC, posix.KERN.PROC_FILEDESC, std.c.getpid() }; | | |
| 179 | var len: usize = undefined; | | |
| 180 | posix.sysctl(&mib, null, &len, null, 0) catch |err| switch (err) { | | |
| 181 | error.PermissionDenied => unreachable, | | |
| 182 | error.SystemResources => return error.SystemResources, | | |
| 183 | error.NameTooLong => unreachable, | | |
| 184 | error.UnknownName => unreachable, | | |
| 185 | else => return error.Unexpected, | | |
| 186 | }; | | |
| 187 | len = len * 4 / 3; | | |
| 188 | const buf = std.heap.c_allocator.alloc(u8, len) catch return error.SystemResources; | | |
| 189 | defer std.heap.c_allocator.free(buf); | | |
| 190 | len = buf.len; | | |
| 191 | posix.sysctl(&mib, &buf[0], &len, null, 0) catch |err| switch (err) { | | |
| 192 | error.PermissionDenied => unreachable, | | |
| 193 | error.SystemResources => return error.SystemResources, | | |
| 194 | error.NameTooLong => unreachable, | | |
| 195 | error.UnknownName => unreachable, | | |
| 196 | else => return error.Unexpected, | | |
| 197 | }; | | |
| 198 | var i: usize = 0; | | |
| 199 | while (i < len) { | | |
| 200 | const kf: *align(1) std.c.kinfo_file = @ptrCast(&buf[i]); | | |
| 201 | if (kf.fd == fd) { | | |
| 202 | len = mem.indexOfScalar(u8, &kf.path, 0) orelse max_path_bytes; | | |
| 203 | if (len == 0) return error.NameTooLong; | | |
| 204 | const result = out_buffer[0..len]; | | |
| 205 | @memcpy(result, kf.path[0..len]); | | |
| 206 | return result; | | |
| 207 | } | | |
| 208 | i += @intCast(kf.structsize); | | |
| 209 | } | | |
| 210 | return error.FileNotFound; | | |
| 211 | } | 167 | } |
| | 168 | const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse max_path_bytes; |
| | 169 | if (len == 0) return error.NameTooLong; |
| | 170 | const result = out_buffer[0..len]; |
| | 171 | @memcpy(result, kfile.path[0..len]); |
| | 172 | return result; |
| 212 | }, | 173 | }, |
| 213 | .dragonfly => { | 174 | .dragonfly => { |
| 214 | @memset(out_buffer[0..max_path_bytes], 0); | 175 | @memset(out_buffer[0..max_path_bytes], 0); |