_FILE_OFFSET_BITS=64 support for fcntl.
On Android, fcntl is always implemented by fcntl64(2). This means that
an LP32 binary can `fcntl(F_SETLK, struct flock)` (because fcntl64(2)
passes through to the 32-bit fcntl(2) to handle F_SETLK), and it can
also `fcntl(F_SETLK64, struct flock64)`. What it can't do before this
patch is set _FILE_OFFSET_BITS=64 and then `fcntl(F_SETLK, struct
flock)` where that `struct flock` is actually implicitly `struct
flock64`.
Move the kernel uapi structs out of the way, define them ourselves based
on __LP64__ and _FILE_OFFSET_BITS, and fix up the relevant F_ constants.
(Also add a .clang-format to turn off clang-format in libc/include/.)
Bug: N/A
Test: treehugger (and strace!)
Change-Id: Iccd6c83d9133e1efcf93a7b49a6ae0f1bbd3d58b
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 23a58d6..1ea94e6 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -51,14 +51,32 @@
__BEGIN_DECLS
-#ifdef __LP64__
+#if defined(__LP64__)
+
/* LP64 kernels don't have F_*64 defines because their flock is 64-bit. */
+
/** Flag for flock(). */
#define F_GETLK64 F_GETLK
/** Flag for flock(). */
#define F_SETLK64 F_SETLK
/** Flag for flock(). */
#define F_SETLKW64 F_SETLKW
+
+#elif defined(__USE_FILE_OFFSET64)
+
+/* For _FILE_OFFSET_BITS=64, redirect the constants to the off64_t variants. */
+
+#undef F_GETLK
+#undef F_SETLK
+#undef F_SETLKW
+
+/** Flag for flock(). */
+#define F_GETLK F_GETLK64
+/** Flag for flock(). */
+#define F_SETLK F_SETLK64
+/** Flag for flock(). */
+#define F_SETLKW F_SETLKW64
+
#endif
/** Flag for open(). */