hjl / source-git / glibc

Forked from source-git/glibc 3 years ago
Clone

Blame sysdeps/unix/sysv/linux/tst-ofdlocks.c

Packit 6c4009
/* Check non representable OFD locks regions in non-LFS mode (BZ #20251)
Packit 6c4009
   Copyright (C) 2018 Free Software Foundation, Inc.
Packit 6c4009
Packit 6c4009
   This program is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU General Public License
Packit 6c4009
   as published by the Free Software Foundation; either version 2
Packit 6c4009
   of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   This program 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
Packit 6c4009
   GNU General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU General Public License
Packit 6c4009
   along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit 6c4009
*/
Packit 6c4009
Packit 6c4009
#include <unistd.h>
Packit 6c4009
#include <fcntl.h>
Packit 6c4009
#include <stdint.h>
Packit 6c4009
#include <errno.h>
Packit 6c4009
Packit 6c4009
#include <support/temp_file.h>
Packit 6c4009
#include <support/check.h>
Packit 6c4009
Packit 6c4009
static char *temp_filename;
Packit 6c4009
static int temp_fd;
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
do_prepare (int argc, char **argv)
Packit 6c4009
{
Packit 6c4009
  temp_fd = create_temp_file ("tst-ofdlocks.", &temp_filename);
Packit 6c4009
  TEST_VERIFY_EXIT (temp_fd != -1);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#define PREPARE do_prepare
Packit 6c4009
Packit 6c4009
static int
Packit 6c4009
do_test (void)
Packit 6c4009
{
Packit 6c4009
  /* It first allocates a open file description lock range which can not
Packit 6c4009
     be represented in a 32 bit struct flock.   */
Packit 6c4009
  struct flock64 lck64 = {
Packit 6c4009
    .l_type   = F_WRLCK,
Packit 6c4009
    .l_whence = SEEK_SET,
Packit 6c4009
    .l_start  = (off64_t)INT32_MAX + 1024,
Packit 6c4009
    .l_len    = 1024,
Packit 6c4009
  };
Packit 6c4009
  int ret = fcntl64 (temp_fd, F_OFD_SETLKW, &lck64);
Packit 6c4009
  if (ret == -1 && errno == EINVAL)
Packit 6c4009
    /* OFD locks are only available on Linux 3.15.  */
Packit 6c4009
    FAIL_UNSUPPORTED ("fcntl (F_OFD_SETLKW) not supported");
Packit 6c4009
Packit 6c4009
  TEST_VERIFY_EXIT (ret == 0);
Packit 6c4009
Packit 6c4009
  /* Open file description locks placed through the same open file description
Packit 6c4009
     (either by same file descriptor or a duplicated one created by fork,
Packit 6c4009
     dup, fcntl F_DUPFD, etc.) overwrites then old lock.  To force a
Packit 6c4009
     conflicting lock combination, it creates a new file descriptor.  */
Packit 6c4009
  int fd = open64 (temp_filename, O_RDWR, 0666);
Packit 6c4009
  TEST_VERIFY_EXIT (fd != -1);
Packit 6c4009
Packit 6c4009
  /* It tries then to allocate another open file descriptior with a valid
Packit 6c4009
     non-LFS bits struct flock but which will result in a conflicted region
Packit 6c4009
     which can not be represented in a non-LFS struct flock.  */
Packit 6c4009
  struct flock lck = {
Packit 6c4009
    .l_type   = F_WRLCK,
Packit 6c4009
    .l_whence = SEEK_SET,
Packit 6c4009
    .l_start  = INT32_MAX - 1024,
Packit 6c4009
    .l_len    = 4 * 1024,
Packit 6c4009
  };
Packit 6c4009
  int r = fcntl (fd, F_OFD_GETLK, &lck;;
Packit 6c4009
  if (sizeof (off_t) != sizeof (off64_t))
Packit 6c4009
    TEST_VERIFY (r == -1 && errno == EOVERFLOW);
Packit 6c4009
  else
Packit 6c4009
    TEST_VERIFY (r == 0);
Packit 6c4009
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#include <support/test-driver.c>