/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- lseek_fd_device
- lseek_file_stdin
- lseek_loc_negative
- lseek_whence_inval
- lseek_loc_pasteof
- test_lseek
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * lseek
32 */
33
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <errno.h>
41 #include <err.h>
42
43 #include "config.h"
44 #include "test.h"
45
46 static
47 void
48 lseek_fd_device(void)
49 {
50 int fd, rv;
51
52 fd = open("null:", O_RDONLY);
53 if (fd<0) {
54 warn("UH-OH: opening null: failed");
55 return;
56 }
57
58 rv = lseek(fd, 309, SEEK_SET);
59 report_test(rv, errno, ESPIPE, "lseek on device");
60
61 close(fd);
62 }
63
64 static
65 void
66 lseek_file_stdin(void)
67 {
68 int fd, fd2, rv, status;
69 const char slogan[] = "There ain't no such thing as a free lunch";
70 size_t len = strlen(slogan);
71 pid_t pid;
72
73 /* fork so we don't affect our own stdin */
74 pid = fork();
75 if (pid<0) {
76 warn("UH-OH: fork failed");
77 return;
78 }
79 else if (pid!=0) {
80 /* parent */
81 rv = waitpid(pid, &status, 0);
82 if (rv<0) {
83 warn("UH-OH: waitpid failed");
84 }
85 if (WIFSIGNALED(status)) {
86 warn("UH-OH: subprocess exited with signal %d",
87 WTERMSIG(status));
88 }
89 else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
90 warn("UH-OH: subprocess exited with code %d",
91 WEXITSTATUS(status));
92 }
93 return;
94 }
95
96 /* child */
97
98 fd = open_testfile(NULL);
99 if (fd<0) {
100 _exit(0);
101 }
102
103 /*
104 * Move file to stdin.
105 * Use stdin (rather than stdout or stderr) to maximize the
106 * chances of detecting any special-case handling of fds 0-2.
107 * (Writing to stdin is fine as long as it's open for write,
108 * and it will be.)
109 */
110 fd2 = dup2(fd, STDIN_FILENO);
111 if (fd2<0) {
112 warn("UH-OH: dup2 to stdin failed");
113 close(fd);
114 remove(TESTFILE);
115 _exit(0);
116 }
117 if (fd2 != STDIN_FILENO) {
118 warn("UH-OH: dup2 returned wrong file handle");
119 close(fd);
120 remove(TESTFILE);
121 _exit(0);
122 }
123 close(fd);
124
125 rv = write(STDIN_FILENO, slogan, len);
126 if (rv<0) {
127 warn("UH-OH: write to %s (via stdin) failed", TESTFILE);
128 remove(TESTFILE);
129 _exit(0);
130 }
131
132 if ((unsigned)rv != len) {
133 warnx("UH-OH: write to %s (via stdin) got short count",
134 TESTFILE);
135 remove(TESTFILE);
136 _exit(0);
137 }
138
139 rv = lseek(STDIN_FILENO, 0, SEEK_SET);
140 report_test(rv, errno, 0, "lseek stdin when open on file (try 1)");
141
142 rv = lseek(STDIN_FILENO, 0, SEEK_END);
143 report_test(rv, errno, 0, "lseek stdin when open on file (try 2)");
144
145 remove(TESTFILE);
146 _exit(0);
147 }
148
149 static
150 void
151 lseek_loc_negative(void)
152 {
153 int fd, rv;
154
155 fd = open_testfile(NULL);
156 if (fd<0) {
157 return;
158 }
159
160 rv = lseek(fd, -309, SEEK_SET);
161 report_test(rv, errno, EINVAL, "lseek to negative offset");
162
163 close(fd);
164 remove(TESTFILE);
165 }
166
167 static
168 void
169 lseek_whence_inval(void)
170 {
171 int fd, rv;
172
173 fd = open_testfile(0);
174 if (fd<0) {
175 return;
176 }
177
178 rv = lseek(fd, 0, 3594);
179 report_test(rv, errno, EINVAL, "lseek with invalid whence code");
180
181 close(fd);
182 remove(TESTFILE);
183 }
184
185 static
186 void
187 lseek_loc_pasteof(void)
188 {
189 const char *message = "blahblah";
190 int fd;
191 off_t pos;
192
193 fd = open_testfile(message);
194 if (fd<0) {
195 return;
196 }
197
198 pos = lseek(fd, 5340, SEEK_SET);
199 if (pos == -1) {
200 warn("FAILURE: lseek past EOF failed");
201 goto out;
202 }
203 if (pos != 5340) {
204 warnx("FAILURE: lseek to 5340 got offset %ld", (long) pos);
205 goto out;
206 }
207
208 pos = lseek(fd, -50, SEEK_CUR);
209 if (pos == -1) {
210 warn("FAILURE: small seek beyond EOF failed");
211 goto out;
212 }
213 if (pos != 5290) {
214 warnx("FAILURE: SEEK_CUR to 5290 got offset %ld", (long) pos);
215 goto out;
216 }
217
218 pos = lseek(fd, 0, SEEK_END);
219 if (pos == -1) {
220 warn("FAILURE: seek to EOF failed");
221 goto out;
222 }
223
224 if (pos != (off_t) strlen(message)) {
225 warnx("FAILURE: seek to EOF got %ld (should be %d)",
226 (long) pos, strlen(message));
227 goto out;
228 }
229
230 warnx("passed: seek past/to EOF");
231
232 out:
233 close(fd);
234 remove(TESTFILE);
235 return;
236 }
237
238 void
239 test_lseek(void)
240 {
241 test_lseek_fd();
242
243 lseek_fd_device();
244 lseek_file_stdin();
245 lseek_loc_negative();
246 lseek_loc_pasteof();
247 lseek_whence_inval();
248 }