about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/i386/fchownat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/fchownat.c')
-rw-r--r--sysdeps/unix/sysv/linux/i386/fchownat.c120
1 files changed, 17 insertions, 103 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/fchownat.c b/sysdeps/unix/sysv/linux/i386/fchownat.c
index db5481705a..34acf10c27 100644
--- a/sysdeps/unix/sysv/linux/i386/fchownat.c
+++ b/sysdeps/unix/sysv/linux/i386/fchownat.c
@@ -30,33 +30,6 @@
 #include <linux/posix_types.h>
 #include <kernel-features.h>
 
-/*
-  In Linux 2.1.x the chown functions have been changed.  A new function lchown
-  was introduced.  The new chown now follows symlinks - the old chown and the
-  new lchown do not follow symlinks.
-  The new lchown function has the same number as the old chown had and the
-  new chown has a new number.  When compiling with headers from Linux > 2.1.8x
-  it's impossible to run this libc with older kernels.  In these cases libc
-  has therefore to route calls to chown to the old chown function.
-*/
-
-extern int __chown_is_lchown (const char *__file, uid_t __owner,
-			      gid_t __group);
-extern int __real_chown (const char *__file, uid_t __owner, gid_t __group);
-
-
-#if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
-/* Running under Linux > 2.1.80.  */
-
-# ifdef __NR_chown32
-#  if __ASSUME_32BITUIDS == 0
-/* This variable is shared with all files that need to check for 32bit
-   uids.  */
-extern int __libc_missing_32bit_uids;
-#  endif
-# endif /* __NR_chown32 */
-#endif
-
 
 int
 fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
@@ -105,92 +78,33 @@ fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
       file = buf;
     }
 
+# if __ASSUME_32BITUIDS > 0
+  /* This implies __ASSUME_LCHOWN_SYSCALL.  */
   INTERNAL_SYSCALL_DECL (err);
 
-# if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
-#  if __ASSUME_LCHOWN_SYSCALL == 0
-  static int __libc_old_chown;
-
-#   ifdef __NR_chown32
-  if (__libc_missing_32bit_uids <= 0)
-    {
-      if (flag & AT_SYMLINK_NOFOLLOW)
-	result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file),
-				   owner, group);
-      else
-	result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file),
-				   owner, group);
-
-      if (!INTERNAL_SYSCALL_ERROR_P (result, err))
-	return result;
-      if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
-	goto fail;
-
-      __libc_missing_32bit_uids = 1;
-    }
-#   endif /* __NR_chown32 */
-
-  if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
-      || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
+  if (flag & AT_SYMLINK_NOFOLLOW)
+    result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file), owner,
+			       group);
+  else
+    result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
+			       group);
 
-  if (!__libc_old_chown && (flag & AT_SYMLINK_NOFOLLOW) == 0)
-    {
-      result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner,
-				 group);
-
-      if (!INTERNAL_SYSCALL_ERROR_P (result, err))
-	return result;
-      if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
-	goto fail;
-
-      __libc_old_chown = 1;
-    }
-
-  result = INTERNAL_SYSCALL (lchown, err, 3, CHECK_STRING (file), owner,
-			     group);
-#  elif __ASSUME_32BITUIDS
-  /* This implies __ASSUME_LCHOWN_SYSCALL.  */
-  result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
-			     group);
-#  else
-  /* !__ASSUME_32BITUIDS && ASSUME_LCHOWN_SYSCALL  */
-#   ifdef __NR_chown32
-  if (__libc_missing_32bit_uids <= 0)
-    {
-      result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
-				 group);
-      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
-	return result;
-      if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
-	goto fail;
-
-      __libc_missing_32bit_uids = 1;
-    }
-#   endif /* __NR_chown32 */
-  if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
-      || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
     {
-      __set_errno (EINVAL);
+      __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
       return -1;
     }
-
-  result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, group);
-#  endif
 # else
-  result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, group);
+  /* Don't inline the rest to avoid unnecessary code duplication.  */
+  if (flag & AT_SYMLINK_NOFOLLOW)
+    result = __lchown (file, owner, group);
+  else
+    result = __chown (file, owner, group);
+  if (result < 0)
+    __atfct_seterrno (errno, fd, buf);
 # endif
 
-  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
-    goto fail;
-
   return result;
 
- fail:
-  __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
-  return -1;
 #endif
 }