(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
fcntl.c
       1  /* Linux fcntl syscall implementation.
       2     Copyright (C) 2000-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <fcntl.h>
      20  #include <stdarg.h>
      21  #include <errno.h>
      22  #include <sysdep-cancel.h>
      23  
      24  #ifndef __OFF_T_MATCHES_OFF64_T
      25  
      26  # ifndef FCNTL_ADJUST_CMD
      27  #  define FCNTL_ADJUST_CMD(__cmd) __cmd
      28  # endif
      29  
      30  int
      31  __libc_fcntl (int fd, int cmd, ...)
      32  {
      33    va_list ap;
      34    void *arg;
      35  
      36    va_start (ap, cmd);
      37    arg = va_arg (ap, void *);
      38    va_end (ap);
      39  
      40    cmd = FCNTL_ADJUST_CMD (cmd);
      41  
      42    switch (cmd)
      43      {
      44        case F_SETLKW:
      45        case F_SETLKW64:
      46  	return SYSCALL_CANCEL (fcntl64, fd, cmd, arg);
      47        case F_OFD_SETLKW:
      48  	{
      49  	  struct flock *flk = (struct flock *) arg;
      50  	  struct flock64 flk64 =
      51  	  {
      52  	    .l_type = flk->l_type,
      53  	    .l_whence = flk->l_whence,
      54  	    .l_start = flk->l_start,
      55  	    .l_len = flk->l_len,
      56  	    .l_pid = flk->l_pid
      57  	  };
      58  	  return SYSCALL_CANCEL (fcntl64, fd, cmd, &flk64);
      59  	}
      60        case F_OFD_GETLK:
      61        case F_OFD_SETLK:
      62  	{
      63  	  struct flock *flk = (struct flock *) arg;
      64  	  struct flock64 flk64 =
      65  	  {
      66  	    .l_type = flk->l_type,
      67  	    .l_whence = flk->l_whence,
      68  	    .l_start = flk->l_start,
      69  	    .l_len = flk->l_len,
      70  	    .l_pid = flk->l_pid
      71  	  };
      72  	  int ret = INLINE_SYSCALL_CALL (fcntl64, fd, cmd, &flk64);
      73  	  if (ret == -1)
      74  	    return -1;
      75  	  if ((off_t) flk64.l_start != flk64.l_start
      76  	      || (off_t) flk64.l_len != flk64.l_len)
      77  	    {
      78  	      __set_errno (EOVERFLOW);
      79  	      return -1;
      80  	    }
      81  	  flk->l_type = flk64.l_type;
      82  	  flk->l_whence = flk64.l_whence;
      83  	  flk->l_start = flk64.l_start;
      84  	  flk->l_len = flk64.l_len;
      85  	  flk->l_pid = flk64.l_pid;
      86  	  return ret;
      87  	}
      88        /* Since only F_SETLKW{64}/F_OLD_SETLK are cancellation entrypoints and
      89  	 only OFD locks require LFS handling, all others flags are handled
      90  	 unmodified by calling __NR_fcntl64.  */
      91        default:
      92          return __fcntl64_nocancel_adjusted (fd, cmd, arg);
      93      }
      94  }
      95  libc_hidden_def (__libc_fcntl)
      96  
      97  weak_alias (__libc_fcntl, __fcntl)
      98  libc_hidden_weak (__fcntl)
      99  
     100  # include <shlib-compat.h>
     101  # if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_28)
     102  int
     103  __old_libc_fcntl64 (int fd, int cmd, ...)
     104  {
     105    va_list ap;
     106    void *arg;
     107  
     108    va_start (ap, cmd);
     109    arg = va_arg (ap, void *);
     110    va_end (ap);
     111  
     112    /* Previous versions called __NR_fcntl64 for fcntl (which did not handle
     113       OFD locks in LFS mode).  */
     114    return __libc_fcntl64 (fd, cmd, arg);
     115  }
     116  compat_symbol (libc, __old_libc_fcntl64, fcntl, GLIBC_2_0);
     117  versioned_symbol (libc, __libc_fcntl, fcntl, GLIBC_2_28);
     118  # else
     119  weak_alias (__libc_fcntl, fcntl)
     120  # endif
     121  
     122  #endif /* __OFF_T_MATCHES_OFF64_T  */