]> git.proxmox.com Git - mirror_zfs.git/blame - tests/zfs-tests/cmd/mkfile/mkfile.c
Prune /*NOTREACHED*/
[mirror_zfs.git] / tests / zfs-tests / cmd / mkfile / mkfile.c
CommitLineData
6bb24f4d
BB
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, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23/*
24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28#include <stdio.h>
29#include <ctype.h>
30#include <unistd.h>
31#include <sys/stat.h>
32#include <fcntl.h>
33#include <stdlib.h>
34#include <string.h>
35#include <libintl.h>
36#include <errno.h>
13dd63ff 37#include <sys/stdtypes.h>
38#include <sys/sysmacros.h>
6bb24f4d 39
d31277ab 40#define BLOCKSIZE 512 /* bytes */
6bb24f4d
BB
41#define KILOBYTE 1024
42#define MEGABYTE (KILOBYTE * KILOBYTE)
43#define GIGABYTE (KILOBYTE * MEGABYTE)
44
45#define FILE_MODE (S_ISVTX + S_IRUSR + S_IWUSR)
46
90f1c3c9 47static void usage(void) __attribute__((noreturn));
6bb24f4d
BB
48
49int
50main(int argc, char **argv)
51{
52 char *opts;
53 off_t size;
54 size_t len;
55 size_t mult = 1;
56 char *buf = NULL;
57 size_t bufsz = 0;
58 int errors = 0;
59 int i;
60 int verbose = 0; /* option variable */
61 int nobytes = 0; /* option variable */
62 int saverr;
63
64 if (argc == 1)
65 usage();
66
67 while (argv[1] && argv[1][0] == '-') {
68 opts = &argv[1][0];
69 while (*(++opts)) {
70 switch (*opts) {
71 case 'v':
72 verbose++;
73 break;
74 case 'n':
75 nobytes++;
76 break;
77 default:
78 usage();
79 }
80 }
81 argc--;
82 argv++;
83 }
84 if (argc < 3)
85 usage();
86
87 len = strlen(argv[1]);
88 if (len && isalpha(argv[1][len-1])) {
89 switch (argv[1][len-1]) {
90 case 'k':
91 case 'K':
92 mult = KILOBYTE;
93 break;
94 case 'b':
95 case 'B':
d31277ab 96 mult = BLOCKSIZE;
6bb24f4d
BB
97 break;
98 case 'm':
99 case 'M':
100 mult = MEGABYTE;
101 break;
102 case 'g':
103 case 'G':
104 mult = GIGABYTE;
105 break;
106 default:
107 (void) fprintf(stderr,
108 gettext("unknown size %s\n"), argv[1]);
109 usage();
110 }
111
112 for (i = 0; i <= (len-2); i++) {
113 if (!isdigit(argv[1][i])) {
114 (void) fprintf(stderr,
115 gettext("unknown size %s\n"), argv[1]);
116 usage();
117 }
118 }
119 argv[1][len-1] = '\0';
120 }
121 size = ((off_t)atoll(argv[1]) * (off_t)mult);
122
123 argv++;
124 argc--;
125
126 while (argc > 1) {
127 int fd;
128
129 if (verbose)
130 (void) fprintf(stdout, gettext("%s %lld bytes\n"),
131 argv[1], (offset_t)size);
132 fd = open(argv[1], O_CREAT|O_TRUNC|O_RDWR, FILE_MODE);
133 if (fd < 0) {
134 saverr = errno;
135 (void) fprintf(stderr,
136 gettext("Could not open %s: %s\n"),
137 argv[1], strerror(saverr));
138 errors++;
139 argv++;
140 argc--;
141 continue;
7839c4b5
MM
142 } else if (fchown(fd, getuid(), getgid()) < 0) {
143 saverr = errno;
144 (void) fprintf(stderr, gettext(
145 "Could not set owner/group of %s: %s\n"),
146 argv[1], strerror(saverr));
147 (void) close(fd);
148 errors++;
149 argv++;
150 argc--;
151 continue;
152 } else if (lseek(fd, (off_t)size-1, SEEK_SET) < 0) {
6bb24f4d
BB
153 saverr = errno;
154 (void) fprintf(stderr, gettext(
155 "Could not seek to offset %ld in %s: %s\n"),
156 (unsigned long)size-1, argv[1], strerror(saverr));
157 (void) close(fd);
158 errors++;
159 argv++;
160 argc--;
161 continue;
162 } else if (write(fd, "", 1) != 1) {
163 saverr = errno;
164 (void) fprintf(stderr, gettext(
165 "Could not set length of %s: %s\n"),
166 argv[1], strerror(saverr));
167 (void) close(fd);
168 errors++;
169 argv++;
170 argc--;
171 continue;
172 }
173
174 if (!nobytes) {
175 off_t written = 0;
176 struct stat64 st;
177
178 if (lseek(fd, (off_t)0, SEEK_SET) < 0) {
179 saverr = errno;
180 (void) fprintf(stderr, gettext(
181 "Could not seek to beginning of %s: %s\n"),
182 argv[1], strerror(saverr));
183 (void) close(fd);
184 errors++;
185 argv++;
186 argc--;
187 continue;
188 }
189 if (fstat64(fd, &st) < 0) {
190 saverr = errno;
191 (void) fprintf(stderr, gettext(
192 "Could not fstat64 %s: %s\n"),
193 argv[1], strerror(saverr));
194 (void) close(fd);
195 errors++;
196 argv++;
197 argc--;
198 continue;
199 }
200 if (bufsz != st.st_blksize) {
201 if (buf)
202 free(buf);
203 bufsz = (size_t)st.st_blksize;
8111eb4a 204 buf = calloc(1, bufsz);
6bb24f4d
BB
205 if (buf == NULL) {
206 (void) fprintf(stderr, gettext(
207 "Could not allocate buffer of"
208 " size %d\n"), (int)bufsz);
209 (void) close(fd);
210 bufsz = 0;
211 errors++;
212 argv++;
213 argc--;
214 continue;
215 }
216 }
217 while (written < size) {
218 ssize_t result;
219 size_t bytes = (size_t)MIN(bufsz, size-written);
220
221 if ((result = write(fd, buf, bytes)) !=
222 (ssize_t)bytes) {
223 saverr = errno;
224 if (result < 0)
02730c33 225 result = 0;
6bb24f4d
BB
226 written += result;
227 (void) fprintf(stderr, gettext(
228 "%s: initialized %lu of %lu bytes: %s\n"),
229 argv[1], (unsigned long)written,
230 (unsigned long)size,
231 strerror(saverr));
232 errors++;
233 break;
234 }
235 written += bytes;
236 }
237
238 /*
239 * A write(2) call in the above loop failed so
240 * close out this file and go on (error was
241 * already incremented when the write(2) failed).
242 */
243 if (written < size) {
244 (void) close(fd);
245 argv++;
246 argc--;
247 continue;
248 }
249 }
250 if (close(fd) < 0) {
251 saverr = errno;
252 (void) fprintf(stderr, gettext(
253 "Error encountered when closing %s: %s\n"),
254 argv[1], strerror(saverr));
255 errors++;
256 argv++;
257 argc--;
258 continue;
259 }
260
261 /*
262 * Only set the modes (including the sticky bit) if we
263 * had no problems. It is not an error for the chmod(2)
264 * to fail, but do issue a warning.
265 */
266 if (chmod(argv[1], FILE_MODE) < 0)
267 (void) fprintf(stderr, gettext(
268 "warning: couldn't set mode to %#o\n"), FILE_MODE);
269
270 argv++;
271 argc--;
272 }
273 return (errors);
274}
275
276static void usage()
277{
278 (void) fprintf(stderr, gettext(
02730c33 279 "Usage: mkfile [-nv] <size>[g|k|b|m] <name1> [<name2>] ...\n"));
6bb24f4d 280 exit(1);
6bb24f4d 281}