fix compiler warnings
[xfstests-dev.git] / src / looptest.c
1 /*
2  * Copyright  2002 Silicon Graphics, Inc.  ALL RIGHTS RESERVED
3  * 
4  *  U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
5  * 
6  *  Use, duplication or disclosure by the Government is subject to restrictions
7  *  as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the 
8  *  Rights in Technical Data and Computer Software clause at DFARS 252.227-7013 
9  *  and/or in similar or successor clauses in the FAR, or the DOD or NASA FAR
10  *  Supplement. Unpublished -- rights reserved under the Copyright Laws 
11  *  of the United States. Contractor/manufacturer is Silicon Graphics, Inc.,
12  *  2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
13  * 
14  *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI
15  * 
16  *  The copyright notice above does not evidence any actual or intended 
17  *  publication or disclosure of this source code, which includes information 
18  *  that is the confidential and/or proprietary, and is a trade secret,
19  *  of Silicon Graphics, Inc. Any use, duplication or disclosure not 
20  *  specifically authorized in writing by Silicon Graphics is strictly 
21  *  prohibited. ANY DUPLICATION, MODIFICATION, DISTRIBUTION,PUBLIC PERFORMANCE,
22  *  OR PUBLIC DISPLAY OF THIS SOURCE CODE WITHOUT THE EXPRESS WRITTEN CONSENT 
23  *  OF SILICON GRAPHICS, INC. IS STRICTLY PROHIBITED.  THE RECEIPT OR POSSESSION
24  *  OF THIS SOURCE CODE AND/OR INFORMATION DOES NOT CONVEY ANY RIGHTS 
25  *  TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, 
26  *  OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
27  */
28  
29 /* dxm - 28/2/2 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <malloc.h>
34 #include <fcntl.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <sys/stat.h>
38 #include <sys/socket.h>
39
40 #include <unistd.h>
41 #include <sys/types.h>
42
43 FILE    *fp = NULL;
44
45 #define LL                  "ll"
46
47 #define PERROR(a,b)         perror(a)
48 #define GET_LAST_ERROR      errno
49
50 #define HANDLE              int
51 #define INVALID_HANDLE      -1
52 #define TRUNCATE_ERROR      -1
53 #define FLUSH_ERROR         EOF
54
55 #define FILE_BEGIN          SEEK_SET
56 #define FILE_CURRENT        SEEK_CUR
57
58 #define OPEN(N, F)          open(N, O_CREAT|O_RDWR|F, 0644); fp = fdopen(f, "r+")
59 #define SEEK(H, O, F)       (lseek(H, O, F))
60 #define READ(H, B, L)       (read(H, B, L))
61 #define WRITE(H, B, L)      (write(H, B, L))
62 #define CLOSE(H)            (close(H))
63 #define DELETE_FILE(F)      (unlink(F))
64 #define FLUSH(F)            (fflush(fp))
65 #define TRUNCATE(F)         (ftruncate(F, 0))
66
67 #define ALLOC_ALIGNED(S)    (memalign(65536, S))
68 #define FREE_ALIGNED(P)     (free(P))
69
70 #define DIRECT_IO_FLAG      O_DIRECT
71
72 enum {
73     FLAG_OPENCLOSE  = 1,
74     FLAG_READ       = 2,
75     FLAG_WRITE      = 4,
76     FLAG_VERBOSE    = 8,
77     FLAG_TRUNCATE   = 16,
78     FLAG_SEQUENTIAL = 32,
79     FLAG_FLUSH      = 64,
80     FLAG_DELETE     = 128,
81     FLAG_DIRECT     = 256,
82 };
83
84 void
85 usage(char *argv0)
86 {
87     printf(
88         "Usage: %s [switches] <filename>\n"
89         "              -i <count>   = repeat count (default forever)\n"
90         "              -o           = open/close\n"
91         "              -r           = read\n"
92         "              -w           = write\n"
93         "              -t           = truncate\n"
94         "              -d           = delete\n"
95         "              -b <size>    = buffer size\n"
96         "              -v           = verbose\n"
97         "              -s           = sequential\n"
98         "              -f           = flush\n"
99         "              -D           = direct-IO\n"
100         "              -h           = usage\n",
101             argv0);
102 }
103
104 extern int optind;
105 extern char *optarg;
106
107 int
108 main(int argc, char *argv[])
109 {
110     HANDLE              f               = INVALID_HANDLE;
111     char                *filename;
112     int                 i;
113     int                 c;
114     int                 count           = -1;
115     int                 bufsize         = 4096;
116     int                 flags           = 0;
117     char                *buf            = NULL;
118     int64_t             seek_to         = 0;
119         
120     while ((c = getopt(argc, argv, "i:orwb:svthfFDd?")) != EOF) {
121         switch (c) {
122             case 'i':
123                 count = atoi(optarg);
124                 break;
125             case 'o':
126                 flags |= FLAG_OPENCLOSE;
127                 break;
128             case 'r':
129                 flags |= FLAG_READ;
130                 break;
131             case 'w':
132                 flags |= FLAG_WRITE;
133                 break;
134             case 't':
135                 flags |= FLAG_TRUNCATE;
136                 break;
137             case 'v':
138                 flags |= FLAG_VERBOSE;
139                 break;
140             case 'b':
141                 bufsize = atoi(optarg);
142                 break;
143             case 's':
144                 flags |= FLAG_SEQUENTIAL;
145                 break;
146             case 'f':
147                 flags |= FLAG_FLUSH;
148                 break;
149             case 'D':
150                 flags |= FLAG_DIRECT;
151                 break;
152             case 'd':
153                 flags |= FLAG_DELETE;
154                 break;
155             case '?':
156             case 'h':
157             default:
158                 usage(argv[0]);
159                 return 1;
160         }
161     }
162     if (optind != argc - 1) {
163         usage(argv[0]);
164         return 1;
165     }
166
167     filename = argv[optind];
168     if (!flags) {
169         fprintf(stderr, "nothing to do!\n");
170         exit(1);
171     }
172
173     if (flags & FLAG_DIRECT)
174         buf = (char *)ALLOC_ALIGNED(bufsize);
175     else 
176         buf = (char *)malloc(bufsize);
177             
178     if (!buf)
179         PERROR("malloc", GET_LAST_ERROR);
180
181     for (i = 0; i < bufsize; i++) {
182         buf[i] = i & 127;
183     }
184
185     for (i = 0; count < 0 || i < count; i++) {
186         
187         if ((flags & FLAG_OPENCLOSE) || !i) {
188             int fileflags;
189             
190             if (flags & FLAG_VERBOSE)
191                 printf("open %s\n", filename);
192             
193             fileflags = 0;
194             if (flags & FLAG_DIRECT)
195                 fileflags |= DIRECT_IO_FLAG;
196             
197             f = OPEN(filename, fileflags);
198             if (f == INVALID_HANDLE)
199                 PERROR("OPEN", GET_LAST_ERROR);
200
201         }
202         
203         if ((flags & FLAG_OPENCLOSE) && (flags & FLAG_SEQUENTIAL)) {
204             if (flags & FLAG_VERBOSE)
205                 printf("seek %" LL "d\n", seek_to);
206             if (SEEK(f, seek_to, FILE_BEGIN) < 0)
207                 PERROR("SEEK", GET_LAST_ERROR);
208         }
209             
210         if (flags & FLAG_WRITE) {
211             int sizewritten;
212             
213             if (!(flags & FLAG_SEQUENTIAL)) {
214                 if (flags & FLAG_VERBOSE)
215                     printf("seek %" LL "d\n", seek_to);
216                 if (SEEK(f, seek_to, FILE_BEGIN) < 0)
217                     PERROR("SEEK", GET_LAST_ERROR);
218             }
219             
220             if (flags & FLAG_VERBOSE)
221                 printf("write %d\n", bufsize);
222             if ((sizewritten = WRITE(f, buf, bufsize)) != bufsize) {
223                 if (sizewritten < 0)
224                     PERROR("WRITE", GET_LAST_ERROR);
225                 else
226                     fprintf(stderr, "short write: %d of %d\n",
227                             sizewritten, bufsize);
228             }
229         }
230         
231         if (flags & FLAG_READ) {
232             int sizeread;
233             
234             if (!(flags & FLAG_SEQUENTIAL) || (flags & FLAG_WRITE)) {
235                 if (flags & FLAG_VERBOSE)
236                     printf("seek %" LL "d\n", seek_to);
237                 if (SEEK(f, seek_to, FILE_BEGIN) < 0)
238                     PERROR("SEEK", GET_LAST_ERROR);
239             }
240             
241             if (flags & FLAG_VERBOSE)
242                 printf("read %d\n", bufsize);
243             if ((sizeread = READ(f, buf, bufsize)) != bufsize) {
244                 if (sizeread < 0)
245                     PERROR("READ", GET_LAST_ERROR);
246                 else if (sizeread)
247                     fprintf(stderr, "short read: %d of %d\n",
248                         sizeread, bufsize);
249                 else {
250                     fprintf(stderr, "Read past EOF\n");
251                     exit(0);
252                 }
253             }
254         }
255         
256         if (flags & FLAG_TRUNCATE) {
257             if (flags & FLAG_VERBOSE)
258                 printf("seek 0\n");
259
260             if (SEEK(f, 0, FILE_BEGIN) < 0)
261                 PERROR("SEEK", GET_LAST_ERROR);
262             
263             if (flags & FLAG_VERBOSE)
264                 printf("truncate\n");
265             
266             if (TRUNCATE(f) == TRUNCATE_ERROR)
267                 PERROR("TRUNCATE", GET_LAST_ERROR);
268         }
269         
270         if (flags & FLAG_FLUSH) {
271             if (flags & FLAG_VERBOSE)
272                 printf("flush\n");
273             
274             if (FLUSH(f) == FLUSH_ERROR)
275                 PERROR("FLUSH", GET_LAST_ERROR);
276         }
277
278         if (flags & FLAG_SEQUENTIAL) {
279             seek_to += bufsize;
280             if (flags & FLAG_TRUNCATE) {
281                 if (flags & FLAG_VERBOSE)
282                     printf("seek %" LL "d\n", seek_to);
283                 if (SEEK(f, seek_to, FILE_BEGIN) < 0)
284                     PERROR("SEEK", GET_LAST_ERROR);
285             }
286         }
287         
288         if (flags & FLAG_OPENCLOSE) {
289             if (flags & FLAG_VERBOSE)
290                 printf("close %s\n", filename);
291             CLOSE(f);
292         }
293         
294         if (flags & FLAG_DELETE) {
295             if (flags & FLAG_VERBOSE)
296                 printf("delete %s\n", filename);
297             DELETE_FILE(filename);
298         }
299     }
300
301     if (buf) {
302         if (flags & FLAG_DIRECT)
303             FREE_ALIGNED(buf);
304         else
305             free(buf);
306     }
307     
308     return 0;
309 }