Commit e06052f201

Michal Ziulek <michalziulek@gmail.com>
2021-09-15 19:38:00
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.
1 parent 2b90e2c
Changed files (4)
lib
libc
mingw
src
test
standalone
issue_9402
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 <stdio.h>
+#include <io.h>
+#include <errno.h>
+
+#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;
+
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",
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;
+}
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", .{});