]> git.proxmox.com Git - mirror_zfs.git/blob - tests/zfs-tests/cmd/file_write/file_write.c
Fixes for issues found with cppcheck tool
[mirror_zfs.git] / tests / zfs-tests / cmd / file_write / file_write.c
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include "../file_common.h"
28 #include <libgen.h>
29 #include <string.h>
30 #include <inttypes.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33
34 typedef unsigned char uchar_t;
35 typedef long long longlong_t;
36 typedef longlong_t offset_t;
37
38 static unsigned char bigbuffer[BIGBUFFERSIZE];
39
40 /*
41 * Writes (or appends) a given value to a file repeatedly.
42 * See header file for defaults.
43 */
44
45 static void usage(char *);
46
47 int
48 main(int argc, char **argv)
49 {
50 int bigfd;
51 int c;
52 int oflag = 0;
53 int err = 0;
54 int k;
55 long i;
56 int64_t good_writes = 0;
57 uchar_t nxtfillchar;
58 char *prog = argv[0];
59 /*
60 * Default Parameters
61 */
62 int write_count = BIGFILESIZE;
63 uchar_t fillchar = DATA;
64 int block_size = BLOCKSZ;
65 char *filename = NULL;
66 char *operation = NULL;
67 offset_t noffset, offset = 0;
68 int verbose = 0;
69 int rsync = 0;
70 int wsync = 0;
71
72 /*
73 * Process Arguments
74 */
75 while ((c = getopt(argc, argv, "b:c:d:s:f:o:vwr")) != -1) {
76 switch (c) {
77 case 'b':
78 block_size = atoi(optarg);
79 break;
80 case 'c':
81 write_count = atoi(optarg);
82 break;
83 case 'd':
84 fillchar = atoi(optarg);
85 break;
86 case 's':
87 offset = atoll(optarg);
88 break;
89 case 'f':
90 filename = optarg;
91 break;
92 case 'o':
93 operation = optarg;
94 break;
95 case 'v':
96 verbose = 1;
97 break;
98 case 'w':
99 wsync = 1;
100 break;
101 case 'r':
102 rsync = 1;
103 break;
104 case '?':
105 (void) printf("unknown arg %c\n", optopt);
106 usage(prog);
107 break;
108 }
109 }
110
111 /*
112 * Validate Parameters
113 */
114 if (!filename) {
115 (void) printf("Filename not specified (-f <file>)\n");
116 err++;
117 }
118
119 if (!operation) {
120 (void) printf("Operation not specified (-o <operation>).\n");
121 err++;
122 }
123
124 if (block_size > BIGBUFFERSIZE) {
125 (void) printf("block_size is too large max==%d.\n",
126 BIGBUFFERSIZE);
127 err++;
128 }
129
130 if (err) {
131 usage(prog); /* no return */
132 return (1);
133 }
134
135 /*
136 * Prepare the buffer and determine the requested operation
137 */
138 nxtfillchar = fillchar;
139 k = 0;
140
141 for (i = 0; i < block_size; i++) {
142 bigbuffer[i] = nxtfillchar;
143
144 if (fillchar == 0) {
145 if ((k % DATA_RANGE) == 0) {
146 k = 0;
147 }
148 nxtfillchar = k++;
149 }
150 }
151
152 /*
153 * using the strncmp of operation will make the operation match the
154 * first shortest match - as the operations are unique from the first
155 * character this means that we match single character operations
156 */
157 if ((strncmp(operation, "create", strlen(operation) + 1)) == 0 ||
158 (strncmp(operation, "overwrite", strlen(operation) + 1)) == 0) {
159 oflag = (O_RDWR|O_CREAT);
160 } else if ((strncmp(operation, "append", strlen(operation) + 1)) == 0) {
161 oflag = (O_RDWR|O_APPEND);
162 } else {
163 (void) printf("valid operations are <create|append> not '%s'\n",
164 operation);
165 usage(prog);
166 }
167
168 if (rsync) {
169 oflag = oflag | O_RSYNC;
170 }
171
172 if (wsync) {
173 oflag = oflag | O_SYNC;
174 }
175
176 /*
177 * Given an operation (create/overwrite/append), open the file
178 * accordingly and perform a write of the appropriate type.
179 */
180 if ((bigfd = open(filename, oflag, 0666)) == -1) {
181 (void) printf("open %s: failed [%s]%d. Aborting!\n", filename,
182 strerror(errno), errno);
183 exit(errno);
184 }
185 noffset = lseek64(bigfd, offset, SEEK_SET);
186 if (noffset != offset) {
187 (void) printf("llseek %s (%lld/%lld) failed [%s]%d.Aborting!\n",
188 filename, offset, noffset, strerror(errno), errno);
189 exit(errno);
190 }
191
192 if (verbose) {
193 (void) printf("%s: block_size = %d, write_count = %d, "
194 "offset = %lld, data = %s%d\n", filename, block_size,
195 write_count, offset,
196 (fillchar == 0) ? "0->" : "",
197 (fillchar == 0) ? DATA_RANGE : fillchar);
198 }
199
200 for (i = 0; i < write_count; i++) {
201 ssize_t n;
202
203 if ((n = write(bigfd, &bigbuffer, block_size)) == -1) {
204 (void) printf("write failed (%ld), good_writes = %"
205 PRId64 ", " "error: %s[%d]\n",
206 (long)n, good_writes,
207 strerror(errno),
208 errno);
209 exit(errno);
210 }
211 good_writes++;
212 }
213
214 if (verbose) {
215 (void) printf("Success: good_writes = %" PRId64 "(%"
216 PRId64 ")\n", good_writes, (good_writes * block_size));
217 }
218
219 return (0);
220 }
221
222 static void
223 usage(char *prog)
224 {
225 (void) printf("Usage: %s [-v] -o {create,overwrite,append} -f file_name"
226 " [-b block_size]\n"
227 "\t[-s offset] [-c write_count] [-d data]\n"
228 "\twhere [data] equal to zero causes chars "
229 "0->%d to be repeated throughout\n", prog, DATA_RANGE);
230
231 exit(1);
232 }