1 /* Test truncating a file.
2    Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16 
17 #include <config.h>
18 
19 #include <unistd.h>
20 
21 #include "signature.h"
22 SIGNATURE_CHECK (truncate, int, (const char *, off_t));
23 
24 #include <errno.h>
25 #include <fcntl.h>
26 
27 #include "ignore-value.h"
28 #include "macros.h"
29 
30 #define BASE "test-truncate.t"
31 
32 int
main(int argc,char * argv[])33 main (int argc, char *argv[])
34 {
35   /* Clean up any trash from prior testsuite runs.  */
36   ignore_value (system ("rm -rf " BASE "*"));
37 
38   {
39     int fd = open (BASE "file", O_RDWR | O_TRUNC | O_CREAT, 0600);
40     ASSERT (fd >= 0);
41     ASSERT (write (fd, "Hello", 5) == 5);
42     close (fd);
43   }
44 
45   {
46     int fd = open (BASE "file", O_RDONLY);
47     ASSERT (fd >= 0);
48     ASSERT (lseek (fd, 0, SEEK_END) == 5);
49     close (fd);
50   }
51 
52   /* Test increasing the size.  */
53   ASSERT (truncate (BASE "file", 314159) == 0);
54   {
55     int fd = open (BASE "file", O_RDONLY);
56     ASSERT (fd >= 0);
57     ASSERT (lseek (fd, 0, SEEK_END) == 314159);
58     close (fd);
59   }
60 
61   /* Test reducing the size.  */
62   ASSERT (truncate (BASE "file", 3) == 0);
63   {
64     int fd = open (BASE "file", O_RDONLY);
65     ASSERT (fd >= 0);
66     ASSERT (lseek (fd, 0, SEEK_END) == 3);
67     close (fd);
68   }
69 
70   /* Test reducing the size to 0.  */
71   ASSERT (truncate (BASE "file", 0) == 0);
72   {
73     int fd = open (BASE "file", O_RDONLY);
74     ASSERT (fd >= 0);
75     ASSERT (lseek (fd, 0, SEEK_END) == 0);
76     close (fd);
77   }
78 
79   /* Test behaviour for nonexistent files.  */
80   {
81     errno = 0;
82     ASSERT (truncate ("/nonexistent", 0) == -1);
83     ASSERT (errno == ENOENT);
84   }
85   /* Test behaviour for directories.  */
86   {
87     errno = 0;
88     ASSERT (truncate (".", 0) == -1);
89     ASSERT (errno == EISDIR
90             || /* on native Windows */ errno == EACCES);
91   }
92   /* Test behaviour for trailing slashes.  */
93   {
94     errno = 0;
95     ASSERT (truncate (BASE "file/", 0) == -1);
96     ASSERT (errno == ENOTDIR
97             || /* on native Windows */ errno == EINVAL);
98   }
99   /* Test behaviour for invalid lengths.  */
100   {
101     errno = 0;
102     ASSERT (truncate (BASE "file", -3) == -1);
103     ASSERT (errno == EINVAL);
104   }
105 
106   /* Cleanup.  */
107   ASSERT (unlink (BASE "file") == 0);
108 
109   return 0;
110 }
111