From e06052f201a63edd772ffade74551d159c7a7784 Mon Sep 17 00:00:00 2001 From: Michal Ziulek Date: Wed, 15 Sep 2021 19:38:00 +0200 Subject: [PATCH] Added implementation for _fseeki64 and _ftelli64 from mingw-w64 9.0.0 (#9402). (#9766) * Added fseeki64.c from mingw-w64 9.0.0. This file was missing in Zig distribution. This file contains implementation for _fseeki64 and _ftelli64 functions. --- lib/libc/mingw/stdio/fseeki64.c | 50 +++++++++++++++++++++++++++++ src/mingw.zig | 1 + test/standalone.zig | 3 ++ test/standalone/issue_9402/main.zig | 14 ++++++++ 4 files changed, 68 insertions(+) create mode 100644 lib/libc/mingw/stdio/fseeki64.c create mode 100644 test/standalone/issue_9402/main.zig diff --git a/lib/libc/mingw/stdio/fseeki64.c b/lib/libc/mingw/stdio/fseeki64.c new file mode 100644 index 0000000000..f70062e391 --- /dev/null +++ b/lib/libc/mingw/stdio/fseeki64.c @@ -0,0 +1,50 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include +#include +#include + +#if !defined(__arm__) && !defined(__aarch64__) /* we have F_ARM_ANY(_fseeki64) in msvcrt.def.in */ +int __cdecl _fseeki64(FILE* stream, __int64 offset, int whence) +{ + fpos_t pos; + if (whence == SEEK_CUR) + { + /* If stream is invalid, fgetpos sets errno. */ + if (fgetpos (stream, &pos)) + return (-1); + pos += (fpos_t) offset; + } + else if (whence == SEEK_END) + { + /* If writing, we need to flush before getting file length. */ + fflush (stream); + pos = (fpos_t) (_filelengthi64 (_fileno (stream)) + offset); + } + else if (whence == SEEK_SET) + pos = (fpos_t) offset; + else + { + errno = EINVAL; + return (-1); + } + return fsetpos (stream, &pos); +} + +int __cdecl (*__MINGW_IMP_SYMBOL(_fseeki64))(FILE*, __int64, int) = _fseeki64; +#endif /* !defined(__arm__) && !defined(__aarch64__) */ + +__int64 __cdecl _ftelli64(FILE* stream) +{ + fpos_t pos; + if (fgetpos (stream, &pos)) + return -1LL; + else + return (__int64) pos; +} + +__int64 __cdecl (*__MINGW_IMP_SYMBOL(_ftelli64))(FILE*) = _ftelli64; + diff --git a/src/mingw.zig b/src/mingw.zig index 587f019270..84857df5b5 100644 --- a/src/mingw.zig +++ b/src/mingw.zig @@ -857,6 +857,7 @@ const mingwex_generic_src = [_][]const u8{ "stdio" ++ path.sep_str ++ "fopen64.c", "stdio" ++ path.sep_str ++ "fseeko32.c", "stdio" ++ path.sep_str ++ "fseeko64.c", + "stdio" ++ path.sep_str ++ "fseeki64.c", "stdio" ++ path.sep_str ++ "fsetpos64.c", "stdio" ++ path.sep_str ++ "ftello.c", "stdio" ++ path.sep_str ++ "ftello64.c", diff --git a/test/standalone.zig b/test/standalone.zig index 6c074642dd..45158f1057 100644 --- a/test/standalone.zig +++ b/test/standalone.zig @@ -36,6 +36,9 @@ pub fn addCases(cases: *tests.StandaloneContext) void { } cases.addBuildFile("test/standalone/c_compiler/build.zig", .{ .build_modes = true, .cross_targets = true }); + if (std.Target.current.os.tag == .windows) { + cases.addC("test/standalone/issue_9402/main.zig"); + } // Try to build and run a PIE executable. if (std.Target.current.os.tag == .linux) { cases.addBuildFile("test/standalone/pie/build.zig", .{}); diff --git a/test/standalone/issue_9402/main.zig b/test/standalone/issue_9402/main.zig new file mode 100644 index 0000000000..eea6bbf4b5 --- /dev/null +++ b/test/standalone/issue_9402/main.zig @@ -0,0 +1,14 @@ +const FILE = extern struct { + dummy_field: u8, +}; + +extern fn _ftelli64([*c]FILE) i64; +extern fn _fseeki64([*c]FILE, i64, c_int) c_int; + +pub export fn main(argc: c_int, argv: **u8) c_int { + _ = argv; + _ = argc; + _ = _ftelli64(null); + _ = _fseeki64(null, 123, 2); + return 0; +}