]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/unix/sysv/linux/fcntl.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / fcntl.c
index ab8d9cfb9cd0f17540ac7bff510aaa9f779367d2..fa184db7fe00d5355ed972174dd6293da9afc544 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #include <assert.h>
 #include <errno.h>
+#include <sysdep-cancel.h>     /* Must come before <fcntl.h>.  */
 #include <fcntl.h>
 #include <stdarg.h>
 
-#include <sysdep-cancel.h>
 #include <sys/syscall.h>
 
 
+static int
+do_fcntl (int fd, int cmd, void *arg)
+{
+  if (cmd != F_GETOWN)
+    return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+
+  INTERNAL_SYSCALL_DECL (err);
+  struct f_owner_ex fex;
+  int res = INTERNAL_SYSCALL (fcntl, err, 3, fd, F_GETOWN_EX, &fex);
+  if (!INTERNAL_SYSCALL_ERROR_P (res, err))
+    return fex.type == F_OWNER_GID ? -fex.pid : fex.pid;
+
+  __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
+  return -1;
+}
+
+
+#ifndef NO_CANCELLATION
 int
-#ifdef NO_CANCELLATION
-static inline __attribute ((always_inline))
-#endif
 __fcntl_nocancel (int fd, int cmd, ...)
 {
   va_list ap;
@@ -38,8 +52,9 @@ __fcntl_nocancel (int fd, int cmd, ...)
   arg = va_arg (ap, void *);
   va_end (ap);
 
-  return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+  return do_fcntl (fd, cmd, arg);
 }
+#endif
 
 
 int
@@ -53,11 +68,11 @@ __libc_fcntl (int fd, int cmd, ...)
   va_end (ap);
 
   if (SINGLE_THREAD_P || cmd != F_SETLKW)
-    return __fcntl_nocancel (fd, cmd, arg);
+    return do_fcntl (fd, cmd, arg);
 
   int oldtype = LIBC_CANCEL_ASYNC ();
 
-  int result = __fcntl_nocancel (fd, cmd, arg);
+  int result = do_fcntl (fd, cmd, arg);
 
   LIBC_CANCEL_RESET (oldtype);