feature. See also
. The project being documented here (as the example) is the Zig library itself.
system.glibcVerFromRPath
fn glibcVerFromRPath(io: Io, rpath: []const u8) !std.SemanticVersion
File
Code
fn glibcVerFromRPath(io: Io, rpath: []const u8) !std.SemanticVersion {
const cwd: Io.Dir = .cwd();
var dir = cwd.openDir(io, rpath, .{}) catch |err| switch (err) {
error.NameTooLong => return error.Unexpected,
error.BadPathName => return error.Unexpected,
error.NetworkNotFound => return error.Unexpected,
error.FileNotFound => return error.GLibCNotFound,
error.NotDir => return error.GLibCNotFound,
error.AccessDenied => return error.GLibCNotFound,
error.PermissionDenied => return error.GLibCNotFound,
error.NoDevice => return error.GLibCNotFound,
error.ProcessFdQuotaExceeded => |e| return e,
error.SystemFdQuotaExceeded => |e| return e,
error.SystemResources => |e| return e,
error.SymLinkLoop => |e| return e,
error.Unexpected => |e| return e,
error.Canceled => |e| return e,
};
defer dir.close(io);
// the past, we used readlink() here because the link name would
// reveal the glibc version. However, in more recent GNU/Linux
// installations, there is no symlink. Thus we instead use a more
// robust check of opening the libc shared object and looking at the
// .dynstr section, and finding the max version number of symbols
// that start with "GLIBC_2.".
const glibc_so_basename = "libc.so.6";
var file = dir.openFile(io, glibc_so_basename, .{}) catch |err| switch (err) {
error.NameTooLong => return error.Unexpected,
error.BadPathName => return error.Unexpected,
error.PipeBusy => return error.Unexpected,
error.NetworkNotFound => return error.Unexpected,
error.AntivirusInterference => return error.Unexpected,
error.FileLocksUnsupported => return error.Unexpected,
error.NoSpaceLeft => return error.Unexpected,
error.PathAlreadyExists => return error.Unexpected,
error.DeviceBusy => return error.Unexpected,
error.FileBusy => return error.Unexpected,
error.ReadOnlyFileSystem => return error.Unexpected,
error.NoDevice => return error.Unexpected,
error.FileTooBig => return error.Unexpected,
error.WouldBlock => return error.Unexpected,
error.AccessDenied => return error.GLibCNotFound,
error.PermissionDenied => return error.GLibCNotFound,
error.FileNotFound => return error.GLibCNotFound,
error.NotDir => return error.GLibCNotFound,
error.IsDir => return error.GLibCNotFound,
error.ProcessFdQuotaExceeded => |e| return e,
error.SystemFdQuotaExceeded => |e| return e,
error.SystemResources => |e| return e,
error.SymLinkLoop => |e| return e,
error.Unexpected => |e| return e,
error.Canceled => |e| return e,
};
defer file.close(io);
var buffer: [8000]u8 = undefined;
var file_reader: Io.File.Reader = .init(file, io, &buffer);
return glibcVerFromSoFile(&file_reader) catch |err| switch (err) {
error.InvalidElfMagic,
error.InvalidElfEndian,
error.InvalidElfClass,
error.InvalidElfVersion,
error.InvalidGnuLibCVersion,
error.EndOfStream,
=> return error.GLibCNotFound,
error.ReadFailed => return file_reader.err.?,
else => |e| return e,
};
}