2 * Copyright (c) 2013 SGI. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write the Free Software Foundation,
15 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <sys/socket.h>
30 #include <sys/types.h>
36 #define PERROR(a,b) perror(a)
37 #define GET_LAST_ERROR errno
40 #define INVALID_HANDLE -1
41 #define TRUNCATE_ERROR -1
42 #define FLUSH_ERROR EOF
44 #define FILE_BEGIN SEEK_SET
45 #define FILE_CURRENT SEEK_CUR
47 #define OPEN(N, F) open(N, O_CREAT|O_RDWR|F, 0644); fp = fdopen(f, "r+")
48 #define SEEK(H, O, F) (lseek(H, O, F))
49 #define READ(H, B, L) (read(H, B, L))
50 #define WRITE(H, B, L) (write(H, B, L))
51 #define CLOSE(H) (close(H))
52 #define DELETE_FILE(F) (unlink(F))
53 #define FLUSH(F) (fflush(fp))
54 #define TRUNCATE(F) (ftruncate(F, 0))
56 #define ALLOC_ALIGNED(S) (memalign(65536, S))
57 #define FREE_ALIGNED(P) (free(P))
59 #define DIRECT_IO_FLAG O_DIRECT
77 "Usage: %s [switches] <filename>\n"
78 " -i <count> = repeat count (default forever)\n"
84 " -b <size> = buffer size\n"
97 main(int argc, char *argv[])
99 HANDLE f = INVALID_HANDLE;
109 while ((c = getopt(argc, argv, "i:orwb:svthfFDd?")) != EOF) {
112 count = atoi(optarg);
115 flags |= FLAG_OPENCLOSE;
124 flags |= FLAG_TRUNCATE;
127 flags |= FLAG_VERBOSE;
130 bufsize = atoi(optarg);
133 flags |= FLAG_SEQUENTIAL;
139 flags |= FLAG_DIRECT;
142 flags |= FLAG_DELETE;
151 if (optind != argc - 1) {
156 filename = argv[optind];
158 fprintf(stderr, "nothing to do!\n");
162 if (flags & FLAG_DIRECT)
163 buf = (char *)ALLOC_ALIGNED(bufsize);
165 buf = (char *)malloc(bufsize);
168 PERROR("malloc", GET_LAST_ERROR);
170 for (i = 0; i < bufsize; i++) {
174 for (i = 0; count < 0 || i < count; i++) {
176 if ((flags & FLAG_OPENCLOSE) || !i) {
179 if (flags & FLAG_VERBOSE)
180 printf("open %s\n", filename);
183 if (flags & FLAG_DIRECT)
184 fileflags |= DIRECT_IO_FLAG;
186 f = OPEN(filename, fileflags);
187 if (f == INVALID_HANDLE)
188 PERROR("OPEN", GET_LAST_ERROR);
192 if ((flags & FLAG_OPENCLOSE) && (flags & FLAG_SEQUENTIAL)) {
193 if (flags & FLAG_VERBOSE)
194 printf("seek %" LL "d\n", (long long)seek_to);
195 if (SEEK(f, seek_to, FILE_BEGIN) < 0)
196 PERROR("SEEK", GET_LAST_ERROR);
199 if (flags & FLAG_WRITE) {
202 if (!(flags & FLAG_SEQUENTIAL)) {
203 if (flags & FLAG_VERBOSE)
204 printf("seek %" LL "d\n", (long long)seek_to);
205 if (SEEK(f, seek_to, FILE_BEGIN) < 0)
206 PERROR("SEEK", GET_LAST_ERROR);
209 if (flags & FLAG_VERBOSE)
210 printf("write %d\n", bufsize);
211 if ((sizewritten = WRITE(f, buf, bufsize)) != bufsize) {
213 PERROR("WRITE", GET_LAST_ERROR);
215 fprintf(stderr, "short write: %d of %d\n",
216 sizewritten, bufsize);
220 if (flags & FLAG_READ) {
223 if (!(flags & FLAG_SEQUENTIAL) || (flags & FLAG_WRITE)) {
224 if (flags & FLAG_VERBOSE)
225 printf("seek %" LL "d\n", (long long)seek_to);
226 if (SEEK(f, seek_to, FILE_BEGIN) < 0)
227 PERROR("SEEK", GET_LAST_ERROR);
230 if (flags & FLAG_VERBOSE)
231 printf("read %d\n", bufsize);
232 if ((sizeread = READ(f, buf, bufsize)) != bufsize) {
234 PERROR("READ", GET_LAST_ERROR);
236 fprintf(stderr, "short read: %d of %d\n",
239 fprintf(stderr, "Read past EOF\n");
245 if (flags & FLAG_TRUNCATE) {
246 if (flags & FLAG_VERBOSE)
249 if (SEEK(f, 0, FILE_BEGIN) < 0)
250 PERROR("SEEK", GET_LAST_ERROR);
252 if (flags & FLAG_VERBOSE)
253 printf("truncate\n");
255 if (TRUNCATE(f) == TRUNCATE_ERROR)
256 PERROR("TRUNCATE", GET_LAST_ERROR);
259 if (flags & FLAG_FLUSH) {
260 if (flags & FLAG_VERBOSE)
263 if (FLUSH(f) == FLUSH_ERROR)
264 PERROR("FLUSH", GET_LAST_ERROR);
267 if (flags & FLAG_SEQUENTIAL) {
269 if (flags & FLAG_TRUNCATE) {
270 if (flags & FLAG_VERBOSE)
271 printf("seek %" LL "d\n", (long long)seek_to);
272 if (SEEK(f, seek_to, FILE_BEGIN) < 0)
273 PERROR("SEEK", GET_LAST_ERROR);
277 if (flags & FLAG_OPENCLOSE) {
278 if (flags & FLAG_VERBOSE)
279 printf("close %s\n", filename);
283 if (flags & FLAG_DELETE) {
284 if (flags & FLAG_VERBOSE)
285 printf("delete %s\n", filename);
286 DELETE_FILE(filename);
291 if (flags & FLAG_DIRECT)