detypo #5411 continues: Sun grep doesn't have -e.
[p5sagit/p5-mst-13.2.git] / t / op / lfs.t
1 # NOTE: this file tests how large files (>2GB) work with perlio (stdio/sfio).
2 # sysopen(), sysseek(), syswrite(), sysread() are tested in t/lib/syslfs.t.
3 # If you modify/add tests here, remember to update also t/lib/syslfs.t.
4
5 BEGIN {
6         chdir 't' if -d 't';
7         unshift @INC, '../lib';
8         # Don't bother if there are no quad offsets.
9         require Config; import Config;
10         if ($Config{lseeksize} < 8) {
11                 print "1..0\n# no 64-bit file offsets\n";
12                 exit(0);
13         }
14 }
15
16 sub bye {
17     close(BIG);
18     unlink "big";
19     exit(0);
20 }
21
22 sub explain {
23     print <<EOM;
24 #
25 # If the lfs (large file support: large meaning larger than two gigabytes)
26 # tests are skipped or fail, it may mean either that your process
27 # (or process group) is not allowed to write large files (resource
28 # limits) or that the file system you are running the tests on doesn't
29 # let your user/group have large files (quota) or the filesystem simply
30 # doesn't support large files.  You may even need to reconfigure your kernel.
31 # (This is all very operating system and site-dependent.)
32 #
33 # Perl may still be able to support large files, once you have
34 # such a process, enough quota, and such a (file) system.
35 #
36 EOM
37 }
38
39 print "# checking whether we have sparse files...\n";
40
41 # Known have-nots.
42 if ($^O eq 'win32' || $^O eq 'vms') {
43     print "1..0\n# no sparse files (because this is $^O) \n";
44     bye();
45 }
46
47 # Known haves that have problems running this test
48 # (for example because they do not support sparse files, like UNICOS)
49 if ($^O eq 'unicos') {
50     print "1..0\n# large files known to work but unable to test them here ($^O)\n";
51     bye();
52 }
53
54 # Then try to heuristically deduce whether we have sparse files.
55
56 # Let's not depend on Fcntl or any other extension.
57
58 my ($SEEK_SET, $SEEK_CUR, $SEEK_END) = (0, 1, 2);
59
60 # We'll start off by creating a one megabyte file which has
61 # only three "true" bytes.  If we have sparseness, we should
62 # consume less blocks than one megabyte (assuming nobody has
63 # one megabyte blocks...)
64
65 open(BIG, ">big") or do { warn "open failed: $!\n"; bye };
66 binmode BIG;
67 seek(BIG, 1_000_000, $SEEK_SET);
68 print BIG "big";
69 close(BIG);
70
71 my @s;
72
73 @s = stat("big");
74
75 print "# @s\n";
76
77 my $BLOCKSIZE = $s[11] || 512;
78
79 unless (@s == 13 &&
80         $s[7] == 1_000_003 &&
81         defined $s[12] &&
82         $BLOCKSIZE * $s[12] < 1_000_003) {
83     print "1..0\n# no sparse files?\n";
84     bye();
85 }
86
87 print "# we seem to have sparse files...\n";
88
89 # By now we better be sure that we do have sparse files:
90 # if we are not, the following will hog 5 gigabytes of disk.  Ooops.
91
92 $ENV{LC_ALL} = "C";
93
94 open(BIG, ">big") or do { warn "open failed: $!\n"; bye };
95 binmode BIG;
96 unless (seek(BIG, 5_000_000_000, $SEEK_SET)) {
97     print "1..0\n# seeking past 2GB failed: $!\n";
98     explain();
99     bye();
100 }
101
102 # Either the print or (more likely, thanks to buffering) the close will
103 # fail if there are are filesize limitations (process or fs).
104 my $print = print BIG "big";
105 print "# print failed: $!\n" unless $print;
106 my $close = close BIG;
107 print "# close failed: $!\n" unless $close;
108 unless ($print && $close) {
109     if ($! =~/too large/i) {
110         print "1..0\n# writing past 2GB failed: process limits?\n";
111     } elsif ($! =~ /quota/i) {
112         print "1..0\n# filesystem quota limits?\n";
113     }
114     explain();
115     bye();
116 }
117
118 @s = stat("big");
119
120 print "# @s\n";
121
122 unless ($s[7] == 5_000_000_003) {
123     print "1..0\n# not configured to use large files?\n";
124     explain();
125     bye();
126 }
127
128 sub fail () {
129     print "not ";
130     $fail++;
131 }
132
133 print "1..17\n";
134
135 my $fail = 0;
136
137 fail unless $s[7] == 5_000_000_003;     # exercizes pp_stat
138 print "ok 1\n";
139
140 fail unless -s "big" == 5_000_000_003;  # exercizes pp_ftsize
141 print "ok 2\n";
142
143 fail unless -e "big";
144 print "ok 3\n";
145
146 fail unless -f "big";
147 print "ok 4\n";
148
149 open(BIG, "big") or do { warn "open failed: $!\n"; bye };
150 binmode BIG;
151
152 fail unless seek(BIG, 4_500_000_000, $SEEK_SET);
153 print "ok 5\n";
154
155 fail unless tell(BIG) == 4_500_000_000;
156 print "ok 6\n";
157
158 fail unless seek(BIG, 1, $SEEK_CUR);
159 print "ok 7\n";
160
161 fail unless tell(BIG) == 4_500_000_001;
162 print "ok 8\n";
163
164 fail unless seek(BIG, -1, $SEEK_CUR);
165 print "ok 9\n";
166
167 fail unless tell(BIG) == 4_500_000_000;
168 print "ok 10\n";
169
170 fail unless seek(BIG, -3, $SEEK_END);
171 print "ok 11\n";
172
173 fail unless tell(BIG) == 5_000_000_000;
174 print "ok 12\n";
175
176 my $big;
177
178 fail unless read(BIG, $big, 3) == 3;
179 print "ok 13\n";
180
181 fail unless $big eq "big";
182 print "ok 14\n";
183
184 # 705_032_704 = (I32)5_000_000_000
185 fail unless seek(BIG, 705_032_704, $SEEK_SET);
186 print "ok 15\n";
187
188 my $zero;
189
190 fail unless read(BIG, $zero, 3) == 3;
191 print "ok 16\n";
192
193 fail unless $zero eq "\0\0\0";
194 print "ok 17\n";
195
196 explain if $fail;
197
198 bye(); # does the necessary cleanup
199
200 END {
201    unlink "big"; # be paranoid about leaving 5 gig files lying around
202 }
203
204 # eof