| ... | ... | @@ -16,6 +16,10 @@ const c_stdlib = @cImport( |
| 16 | 16 | @cInclude("stdlib.h"), // for atexit |
| 17 | 17 | ); |
| 18 | 18 | |
| 19 | const c_string = @cImport( |
| 20 | @cInclude("string.h"), // for strlcpy |
| 21 | ); |
| 22 | |
| 19 | 23 | // Version of glibc this test is being built to run against |
| 20 | 24 | const glibc_ver = builtin.target.os.version_range.linux.glibc; |
| 21 | 25 | |
| ... | ... | @@ -73,6 +77,23 @@ fn checkGetAuxVal_v2_16() !void { |
| 73 | 77 | assert(pgsz != 0); |
| 74 | 78 | } |
| 75 | 79 | |
| 80 | // strlcpy introduced in v2.38, which is newer than many installed glibcs |
| 81 | fn checkStrlcpy() !void { |
| 82 | if (comptime glibc_ver.order(.{ .major = 2, .minor = 38, .patch = 0 }) == .lt) { |
| 83 | if (@hasDecl(c_string, "strlcpy")) { |
| 84 | @compileError("Before v2.38 glibc does not define 'strlcpy'"); |
| 85 | } |
| 86 | } else { |
| 87 | try checkStrlcpy_v2_38(); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | fn checkStrlcpy_v2_38() !void { |
| 92 | var buf: [99]u8 = undefined; |
| 93 | const used = c_string.strlcpy(&buf, "strlcpy works!", buf.len); |
| 94 | assert(used == 15); |
| 95 | } |
| 96 | |
| 76 | 97 | // atexit is part of libc_nonshared, so ensure its linked in correctly |
| 77 | 98 | fn forceExit0Callback() callconv(.C) void { |
| 78 | 99 | std.c.exit(0); // Override the main() exit code |
| ... | ... | @@ -86,6 +107,7 @@ fn checkAtExit() !void { |
| 86 | 107 | pub fn main() !u8 { |
| 87 | 108 | try checkStat(); |
| 88 | 109 | try checkReallocarray(); |
| 110 | try checkStrlcpy(); |
| 89 | 111 | |
| 90 | 112 | try checkGetAuxVal(); |
| 91 | 113 | try checkAtExit(); |