Blame io/lockf.c

Packit 6c4009
/* Copyright (C) 1994-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/* We need to avoid the header declaration of lockf64, because
Packit 6c4009
   the types don't match lockf and then the compiler will
Packit 6c4009
   complain about the mismatch when we do the alias below.  */
Packit 6c4009
#define lockf64	__renamed_lockf64
Packit 6c4009
Packit 6c4009
#include <fcntl.h>
Packit 6c4009
Packit 6c4009
#undef	lockf64
Packit 6c4009
Packit 6c4009
#include <sys/types.h>
Packit 6c4009
#include <unistd.h>
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
Packit 6c4009
/* lockf is a simplified interface to fcntl's locking facilities.  */
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
lockf (int fd, int cmd, off_t len)
Packit 6c4009
{
Packit 6c4009
  struct flock fl;
Packit 6c4009
Packit 6c4009
  memset ((char *) &fl, '\0', sizeof (fl));
Packit 6c4009
Packit 6c4009
  /* lockf is always relative to the current file position.  */
Packit 6c4009
  fl.l_whence = SEEK_CUR;
Packit 6c4009
  fl.l_start = 0;
Packit 6c4009
  fl.l_len = len;
Packit 6c4009
Packit 6c4009
  switch (cmd)
Packit 6c4009
    {
Packit 6c4009
    case F_TEST:
Packit 6c4009
      /* Test the lock: return 0 if FD is unlocked or locked by this process;
Packit 6c4009
	 return -1, set errno to EACCES, if another process holds the lock.  */
Packit 6c4009
      fl.l_type = F_RDLCK;
Packit 6c4009
      if (__fcntl (fd, F_GETLK, &fl) < 0)
Packit 6c4009
	return -1;
Packit 6c4009
      if (fl.l_type == F_UNLCK || fl.l_pid == __getpid ())
Packit 6c4009
	return 0;
Packit 6c4009
      __set_errno (EACCES);
Packit 6c4009
      return -1;
Packit 6c4009
Packit 6c4009
    case F_ULOCK:
Packit 6c4009
      fl.l_type = F_UNLCK;
Packit 6c4009
      cmd = F_SETLK;
Packit 6c4009
      break;
Packit 6c4009
    case F_LOCK:
Packit 6c4009
      fl.l_type = F_WRLCK;
Packit 6c4009
      cmd = F_SETLKW;
Packit 6c4009
      break;
Packit 6c4009
    case F_TLOCK:
Packit 6c4009
      fl.l_type = F_WRLCK;
Packit 6c4009
      cmd = F_SETLK;
Packit 6c4009
      break;
Packit 6c4009
Packit 6c4009
    default:
Packit 6c4009
      __set_errno (EINVAL);
Packit 6c4009
      return -1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* lockf() is a cancellation point but so is fcntl() if F_SETLKW is
Packit 6c4009
     used.  Therefore we don't have to care about cancellation here,
Packit 6c4009
     the fcntl() function will take care of it.  */
Packit 6c4009
  return __fcntl (fd, cmd, &fl);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#ifdef __OFF_T_MATCHES_OFF64_T
Packit 6c4009
weak_alias (lockf, lockf64)
Packit 6c4009
#endif