Implement _FILE_OFFSET_BITS (mostly).

I still don't think we can make stdio's fseeko and ftello work, but we can
have everything else, and very few programs use fseeko/ftello (and they can
just refrain from using _FILE_OFFSET_BITS and be no worse off than they are
today).

Bug: 11865851
Change-Id: Ic3cb409aae6713f4b345de954bcc4241fcd969ec
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 48763d7..29665e5 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -378,6 +378,15 @@
 # define __USE_BSD 1
 #endif
 
+/*
+ * _FILE_OFFSET_BITS 64 support.
+ */
+#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS)
+#if _FILE_OFFSET_BITS == 64
+#define __USE_FILE_OFFSET64 1
+#endif
+#endif
+
 /*-
  * POSIX.1 requires that the macros we test be defined before any standard
  * header file is included.
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 1663222..6857f60 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -49,8 +49,13 @@
 #define POSIX_MADV_WILLNEED   MADV_WILLNEED
 #define POSIX_MADV_DONTNEED   MADV_DONTNEED
 
+#if defined(__USE_FILE_OFFSET64)
+extern void* mmap(void*, size_t, int, int, int, off_t) __RENAME(mmap64);
+#else
 extern void* mmap(void*, size_t, int, int, int, off_t);
+#endif
 extern void* mmap64(void*, size_t, int, int, int, off64_t);
+
 extern int munmap(void*, size_t);
 extern int msync(const void*, size_t, int);
 extern int mprotect(const void*, size_t, int);
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index 81a3c44..c588e68 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -34,7 +34,11 @@
 
 __BEGIN_DECLS
 
+#if defined(__USE_FILE_OFFSET64)
+extern ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) __RENAME(sendfile64);
+#else
 extern ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
+#endif
 extern ssize_t sendfile64(int out_fd, int in_fd, off64_t* offset, size_t count);
 
 __END_DECLS
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index a5fa692..a6b0fd8 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -90,16 +90,14 @@
 typedef __kernel_time_t __time_t;
 typedef __time_t time_t;
 
-/* This historical accident means that we had a 32-bit off_t on 32-bit architectures. */
-#if !defined(__LP64__)
-typedef __kernel_off_t off_t;
-typedef __kernel_loff_t loff_t;
+#if defined(__USE_FILE_OFFSET64) || defined(__LP64__)
+typedef int64_t off_t;
+typedef off_t loff_t;
 typedef loff_t off64_t;
 #else
-/* We could re-use the LP32 definitions, but that would mean that although off_t and loff_t/off64_t
- * would be the same size, they wouldn't actually be the same type, which can lead to warnings. */
+/* This historical accident means that we had a 32-bit off_t on 32-bit architectures. */
 typedef __kernel_off_t off_t;
-typedef off_t loff_t;
+typedef __kernel_loff_t loff_t;
 typedef loff_t off64_t;
 #endif