[libc] adding linux SYS_fchmodat2 syscall. (#89819)

GitOrigin-RevId: 418212089e95e2d39d2997699a149a09d4c5185c
diff --git a/config/linux/syscall_numbers.h.inc b/config/linux/syscall_numbers.h.inc
index 9f910c5..4a19d9a 100644
--- a/config/linux/syscall_numbers.h.inc
+++ b/config/linux/syscall_numbers.h.inc
@@ -338,6 +338,10 @@
 #define SYS_fchmodat __NR_fchmodat
 #endif
 
+#ifdef __NR_fchmodat2
+#define SYS_fchmodat2 __NR_fchmodat2
+#endif
+
 #ifdef __NR_fchown
 #define SYS_fchown __NR_fchown
 #endif
diff --git a/src/sys/stat/linux/chmod.cpp b/src/sys/stat/linux/chmod.cpp
index 085b916..25e5e69 100644
--- a/src/sys/stat/linux/chmod.cpp
+++ b/src/sys/stat/linux/chmod.cpp
@@ -21,11 +21,14 @@
 LLVM_LIBC_FUNCTION(int, chmod, (const char *path, mode_t mode)) {
 #ifdef SYS_chmod
   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_chmod, path, mode);
+#elif defined(SYS_fchmodat2)
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat2, AT_FDCWD, path,
+                                              mode, 0, AT_SYMLINK_NOFOLLOW);
 #elif defined(SYS_fchmodat)
   int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat, AT_FDCWD, path, mode);
+      LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat, AT_FDCWD, path, mode, 0);
 #else
-#error "chmod and fchmodat syscalls not available."
+#error "chmod, fchmodat and fchmodat2 syscalls not available."
 #endif
 
   if (ret < 0) {