| /* Some basic tests for LFS. | 
 |    Copyright (C) 2000-2016 Free Software Foundation, Inc. | 
 |    This file is part of the GNU C Library. | 
 |    Contributed by Andreas Jaeger <aj@suse.de>, 2000. | 
 |  | 
 |    The GNU C Library is free software; you can redistribute it and/or | 
 |    modify it under the terms of the GNU Lesser General Public | 
 |    License as published by the Free Software Foundation; either | 
 |    version 2.1 of the License, or (at your option) any later version. | 
 |  | 
 |    The GNU C Library is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |    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, see | 
 |    <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #include <unistd.h> | 
 | #include <stdlib.h> | 
 | #include <sys/types.h> | 
 | #include <sys/stat.h> | 
 | #include <fcntl.h> | 
 | #include <error.h> | 
 | #include <errno.h> | 
 | #include <sys/resource.h> | 
 |  | 
 | /* Prototype for our test function.  */ | 
 | extern void do_prepare (int argc, char *argv[]); | 
 | extern int do_test (int argc, char *argv[]); | 
 |  | 
 | /* We have a preparation function.  */ | 
 | #define PREPARE do_prepare | 
 |  | 
 | /* We might need a bit longer timeout.  */ | 
 | #define TIMEOUT 20 /* sec */ | 
 |  | 
 | /* This defines the `main' function and some more.  */ | 
 | #include <test-skeleton.c> | 
 |  | 
 | /* These are for the temporary file we generate.  */ | 
 | char *name; | 
 | int fd; | 
 |  | 
 | /* 2^31 = 2GB.  */ | 
 | #define TWO_GB 2147483648LL | 
 |  | 
 | void | 
 | do_prepare (int argc, char *argv[]) | 
 | { | 
 |   size_t name_len; | 
 |   struct rlimit64 rlim; | 
 |  | 
 |   name_len = strlen (test_dir); | 
 |   name = malloc (name_len + sizeof ("/lfsXXXXXX")); | 
 |   mempcpy (mempcpy (name, test_dir, name_len), | 
 |            "/lfsXXXXXX", sizeof ("/lfsXXXXXX")); | 
 |  | 
 |   /* Open our test file.   */ | 
 |   fd = mkstemp64 (name); | 
 |   if (fd == -1) | 
 |     { | 
 |       if (errno == ENOSYS) | 
 | 	{ | 
 | 	  /* Fail silently.  */ | 
 | 	  error (0, 0, "open64 is not supported"); | 
 | 	  exit (EXIT_SUCCESS); | 
 | 	} | 
 |       else | 
 | 	error (EXIT_FAILURE, errno, "cannot create temporary file"); | 
 |     } | 
 |   add_temp_file (name); | 
 |  | 
 |   if (getrlimit64 (RLIMIT_FSIZE, &rlim) != 0) | 
 |     { | 
 |       error (0, errno, "cannot get resource limit"); | 
 |       exit (0); | 
 |     } | 
 |   if (rlim.rlim_cur < TWO_GB + 200) | 
 |     { | 
 |       rlim.rlim_cur = TWO_GB + 200; | 
 |       if (setrlimit64 (RLIMIT_FSIZE, &rlim) != 0) | 
 | 	{ | 
 | 	  error (0, errno, "cannot reset file size limits"); | 
 | 	  exit (0); | 
 | 	} | 
 |     } | 
 | } | 
 |  | 
 | static void | 
 | test_ftello (void) | 
 | { | 
 |   FILE *f; | 
 |   int ret; | 
 |   off64_t pos; | 
 |  | 
 |   f = fopen64 (name, "w"); | 
 |  | 
 |   ret = fseeko64 (f, TWO_GB+100, SEEK_SET); | 
 |   if (ret == -1 && errno == ENOSYS) | 
 |     { | 
 |       error (0, 0, "fseeko64 is not supported."); | 
 |       exit (EXIT_SUCCESS); | 
 |     } | 
 |   if (ret == -1 && errno == EINVAL) | 
 |     { | 
 |       error (0, 0, "LFS seems not to be supported"); | 
 |       exit (EXIT_SUCCESS); | 
 |     } | 
 |   if (ret == -1) | 
 |     { | 
 |       error (0, errno, "fseeko64 failed with error"); | 
 |       exit (EXIT_FAILURE); | 
 |     } | 
 |  | 
 |   ret = fwrite ("Hello", 1, 5, f); | 
 |   if (ret == -1 && errno == EFBIG) | 
 |     { | 
 |       error (0, errno, "LFS seems not to be supported"); | 
 |       exit (EXIT_SUCCESS); | 
 |     } | 
 |  | 
 |   if (ret == -1 && errno == ENOSPC) | 
 |     { | 
 |       error (0, 0, "Not enough space to write file."); | 
 |       exit (EXIT_SUCCESS); | 
 |     } | 
 |  | 
 |   if (ret != 5) | 
 |     error (EXIT_FAILURE, errno, "Cannot write test string to large file"); | 
 |  | 
 |   pos = ftello64 (f); | 
 |  | 
 |   if (pos != TWO_GB+105) | 
 |     { | 
 |       error (0, 0, "ftello64 gives wrong result."); | 
 |       exit (EXIT_FAILURE); | 
 |     } | 
 |  | 
 |   fclose (f); | 
 | } | 
 |  | 
 | int | 
 | do_test (int argc, char *argv[]) | 
 | { | 
 |   int ret, fd2; | 
 |   struct stat64 statbuf; | 
 |  | 
 |   ret = lseek64 (fd, TWO_GB+100, SEEK_SET); | 
 |   if (ret == -1 && errno == ENOSYS) | 
 |     { | 
 |       error (0, 0, "lseek64 is not supported."); | 
 |       exit (EXIT_SUCCESS); | 
 |     } | 
 |   if (ret == -1 && errno == EINVAL) | 
 |     { | 
 |       error (0, 0, "LFS seems not to be supported."); | 
 |       exit (EXIT_SUCCESS); | 
 |     } | 
 |   if (ret == -1) | 
 |     { | 
 |       error (0, errno, "lseek64 failed with error"); | 
 |       exit (EXIT_FAILURE); | 
 |     } | 
 |  | 
 |   ret = write (fd, "Hello", 5); | 
 |   if (ret == -1 && errno == EFBIG) | 
 |     { | 
 |       error (0, 0, "LFS seems not to be supported."); | 
 |       exit (EXIT_SUCCESS); | 
 |     } | 
 |  | 
 |   if (ret == -1 && errno == ENOSPC) | 
 |     { | 
 |       error (0, 0, "Not enough space to write file."); | 
 |       exit (EXIT_SUCCESS); | 
 |     } | 
 |  | 
 |   if (ret != 5) | 
 |     error (EXIT_FAILURE, errno, "cannot write test string to large file"); | 
 |  | 
 |   ret = close (fd); | 
 |  | 
 |   if (ret == -1) | 
 |     error (EXIT_FAILURE, errno, "error closing file"); | 
 |  | 
 |   ret = stat64 (name, &statbuf); | 
 |  | 
 |   if (ret == -1 && (errno == ENOSYS || errno == EOVERFLOW)) | 
 |     error (0, 0, "stat64 is not supported."); | 
 |   else if (ret == -1) | 
 |     error (EXIT_FAILURE, errno, "cannot stat file `%s'", name); | 
 |   else if (statbuf.st_size != (TWO_GB + 100 + 5)) | 
 |     error (EXIT_FAILURE, 0, "stat reported size %lld instead of %lld.", | 
 | 	   (long long int) statbuf.st_size, (TWO_GB + 100 + 5)); | 
 |  | 
 |   fd2 = openat64 (AT_FDCWD, name, O_RDWR); | 
 |   if (fd2 == -1) | 
 |     { | 
 |       if (errno == ENOSYS) | 
 | 	{ | 
 | 	  /* Silently ignore this test.  */ | 
 | 	  error (0, 0, "openat64 is not supported"); | 
 | 	} | 
 |       else | 
 | 	error (EXIT_FAILURE, errno, "openat64 failed to open big file"); | 
 |     } | 
 |   else | 
 |     { | 
 |       ret = close (fd2); | 
 |  | 
 |       if (ret == -1) | 
 | 	error (EXIT_FAILURE, errno, "error closing file"); | 
 |     } | 
 |  | 
 |   test_ftello (); | 
 |  | 
 |   return 0; | 
 | } |