(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
tst-sync_file_range.c
       1  /* Basic sync_file_range (not specific flag is checked).
       2     Copyright (C) 2016-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  /* sync_file_range is only define for LFS.  */
      20  #define _FILE_OFFSET_BITS 64
      21  #include <errno.h>
      22  #include <fcntl.h>
      23  #include <limits.h>
      24  #include <stdint.h>
      25  #include <stdlib.h>
      26  #include <sys/stat.h>
      27  
      28  #include <support/temp_file.h>
      29  #include <support/check.h>
      30  
      31  #define XSTR(s) STR(S)
      32  #define STR(s)  #s
      33  
      34  static char *temp_filename;
      35  static int temp_fd;
      36  
      37  static char fifoname[] = "/tmp/tst-posix_fadvise-fifo-XXXXXX";
      38  static int fifofd;
      39  
      40  void
      41  do_prepare (int argc, char **argv)
      42  {
      43    temp_fd = create_temp_file ("tst-file_sync_range.", &temp_filename);
      44    if (temp_fd == -1)
      45      FAIL_EXIT1 ("cannot create temporary file: %m");
      46  
      47    if (mktemp (fifoname) == NULL)
      48      FAIL_EXIT1 ("cannot generate temp file name: %m");
      49    add_temp_file (fifoname);
      50  
      51    if (mkfifo (fifoname, S_IWUSR | S_IRUSR) != 0)
      52      FAIL_EXIT1 ("cannot create fifo: %m");
      53  
      54    fifofd = open (fifoname, O_RDONLY | O_NONBLOCK);
      55    if (fifofd == -1)
      56      FAIL_EXIT1 ("cannot open fifo: %m");
      57  }
      58  #define PREPARE do_prepare
      59  
      60  static int
      61  do_test (void)
      62  {
      63    int ret;
      64  
      65    /* This tests first check for some invalid usage and then check for
      66       a simple usage.  It does not cover for all possible issue since for
      67       EIO/ENOMEM/ENOSPC would require to create very specific scenarios that
      68       are outside the current test coverage (basically correct kernel argument
      69       passing.  */
      70  
      71    /* Check for invalid file descriptor.  */
      72    if ((ret = sync_file_range (-1, 0, 0, 0)) != -1)
      73      FAIL_EXIT1 ("sync_file_range did not fail on an invalid descriptor "
      74  		"(returned %d, expected -1)", ret);
      75    if (errno != EBADF)
      76      FAIL_EXIT1 ("sync_file_range on an invalid descriptor did not set errno to "
      77  		"EBADF (%d)", errno);
      78  
      79    if ((ret = sync_file_range (fifofd, 0, 0, 0)) != -1)
      80      FAIL_EXIT1 ("sync_file_range did not fail on an invalid descriptor "
      81  		"(returned %d, expected -1)", ret);
      82    if (errno != ESPIPE)
      83      FAIL_EXIT1 ("sync_file_range on an invalid descriptor did not set errno to "
      84  		"EBADF (%d)", errno);
      85  
      86    /* Check for invalid flags (it must be
      87       SYNC_FILE_RANGE_{WAIT_BEFORE,WRITE,WAIT_AFTER) or a 'or' combination of
      88       them.  */
      89    if ((ret = sync_file_range (temp_fd, 0, 0, -1)) != -1)
      90      FAIL_EXIT1 ("sync_file_range did not failed with invalid flags "
      91  		"(returned %d, " "expected -1)", ret);
      92    if (errno != EINVAL)
      93      FAIL_EXIT1 ("sync_file_range with invalid flag did not set errno to "
      94  		"EINVAL (%d)", errno);
      95  
      96    /* Check for negative offset.  */
      97    if ((ret = sync_file_range (temp_fd, -1, 1, 0)) != -1)
      98      FAIL_EXIT1 ("sync_file_range did not failed with invalid offset "
      99  		"(returned %d, expected -1)", ret);
     100    if (errno != EINVAL)
     101      FAIL_EXIT1 ("sync_file_range with invalid offset did not set errno to "
     102  		"EINVAL (%d)", errno);
     103  
     104    /* offset + nbytes must be a positive value.  */
     105    if ((ret = sync_file_range (temp_fd, 1024, -2048, 0)) != -1)
     106      FAIL_EXIT1 ("sync_file_range did not failed with invalid nbytes (returned %d, "
     107  	  "expected -1)", ret);
     108    if (errno != EINVAL)
     109      FAIL_EXIT1 ("sync_file_range with invalid offset did not set errno to "
     110  		"EINVAL (%d)", errno);
     111  
     112    /* offset + nbytes must be larger or equal than offset */
     113    if ((ret = sync_file_range (temp_fd, -1024, 1024, 0)) != -1)
     114      FAIL_EXIT1 ("sync_file_range did not failed with invalid offset "
     115  		"(returned %d, expected -1)", ret);
     116    if (errno != EINVAL)
     117      FAIL_EXIT1 ("sync_file_range with invalid offset did not set errno to "
     118  		"EINVAL (%d)", errno);
     119  
     120    /* Check simple successful case.  */
     121    if ((ret = sync_file_range (temp_fd, 0, 1024, 0)) == -1)
     122      FAIL_EXIT1 ("sync_file_range failed (errno = %d)", errno);
     123  
     124    /* Finally check also a successful case with a 64-bit offset.  */
     125    off_t large_offset = UINT32_MAX + 2048LL;
     126    if ((ret = sync_file_range (temp_fd, large_offset, 1024, 0)) == -1)
     127      FAIL_EXIT1 ("sync_file_range failed (errno = %d)", errno);
     128  
     129    return 0;
     130  }
     131  
     132  #include <support/test-driver.c>