xref: /illumos-gate/usr/src/test/smbclient-tests/cmd/file_trunc/file_trunc.c (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
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 2009 Sun Microsystems, Inc.  All rights reserved.
24  */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <limits.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <sys/fcntl.h>
34 #include <sys/stat.h>
35 #include <sys/statvfs.h>
36 #include <sys/errno.h>
37 #include <sys/time.h>
38 #include <sys/ioctl.h>
39 #include <sys/wait.h>
40 #include <sys/param.h>
41 #include <string.h>
42 
43 #define	FSIZE	256*1024*1024
44 #define	BSIZE	512
45 
46 /* Initialize Globals */
47 static long	fsize = FSIZE;
48 static size_t	bsize = BSIZE;
49 static int	count = 0;
50 static int	rflag = 0;
51 static int	seed = 0;
52 static int	vflag = 0;
53 static int	errflag = 0;
54 static off_t	offset = 0;
55 static char	*filename = NULL;
56 
57 static void usage(char *execname);
58 static void parse_options(int argc, char *argv[]);
59 static void do_write(int fd);
60 static void do_trunc(int fd);
61 
62 static void
63 usage(char *execname)
64 {
65 	(void) fprintf(stderr,
66 	    "usage: %s [-b blocksize] [-c count] [-f filesize]"
67 	    " [-o offset] [-s seed] [-r] [-v] filename\n", execname);
68 	(void) exit(1);
69 }
70 
71 int
72 main(int argc, char *argv[])
73 {
74 	int i = 0;
75 	int fd = -1;
76 
77 	parse_options(argc, argv);
78 
79 	fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
80 	if (fd < 0) {
81 		perror("open");
82 		exit(3);
83 	}
84 
85 	while (i < count) {
86 		(void) do_write(fd);
87 		(void) do_trunc(fd);
88 
89 		i++;
90 	}
91 
92 	(void) close(fd);
93 	return (0);
94 }
95 
96 static void
97 parse_options(int argc, char *argv[])
98 {
99 	int c;
100 
101 	extern char *optarg;
102 	extern int optind, optopt;
103 
104 	count = fsize / bsize;
105 	seed = time(NULL);
106 	while ((c = getopt(argc, argv, "b:c:f:o:rs:v")) != -1) {
107 		switch (c) {
108 			case 'b':
109 				bsize = atoi(optarg);
110 				break;
111 
112 			case 'c':
113 				count = atoi(optarg);
114 				break;
115 
116 			case 'f':
117 				fsize = atoi(optarg);
118 				break;
119 
120 			case 'o':
121 				offset = atoi(optarg);
122 				break;
123 
124 			case 'r':
125 				rflag++;
126 				break;
127 
128 			case 's':
129 				seed = atoi(optarg);
130 				break;
131 
132 			case 'v':
133 				vflag++;
134 				break;
135 
136 			case ':':
137 				(void) fprintf(stderr,
138 				    "Option -%c requires an operand\n", optopt);
139 				errflag++;
140 				break;
141 
142 			case '?':
143 				(void) fprintf(stderr,
144 				    "Unrecognized option: -%c\n", optopt);
145 				errflag++;
146 				break;
147 		}
148 
149 		if (errflag) {
150 			(void) usage(argv[0]);
151 		}
152 	}
153 	if (argc <= optind) {
154 		(void) fprintf(stderr,
155 		    "No filename specified\n");
156 		usage(argv[0]);
157 	}
158 	filename = argv[optind];
159 
160 	if (vflag) {
161 		(void) fprintf(stderr, "Seed = %d\n", seed);
162 	}
163 	srandom(seed);
164 }
165 
166 static void
167 do_write(int fd)
168 {
169 	off_t	roffset = 0;
170 	char	*buf = NULL;
171 	char	*rbuf = NULL;
172 
173 	buf = (char *)calloc(1, bsize);
174 	rbuf = (char *)calloc(1, bsize);
175 	if (buf == NULL || rbuf == NULL) {
176 		perror("malloc");
177 		exit(4);
178 	}
179 
180 	roffset = random() % fsize;
181 	if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) {
182 		perror("lseek");
183 		exit(5);
184 	}
185 
186 	buf = "SMBFS Test Suite Truncation Test";
187 	if (write(fd, buf, bsize) < bsize) {
188 		perror("write");
189 		exit(6);
190 	}
191 
192 	if (rflag) {
193 		if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) {
194 			perror("lseek");
195 			exit(7);
196 		}
197 
198 		if (read(fd, rbuf, bsize) < bsize) {
199 			perror("read");
200 			exit(8);
201 		}
202 
203 		if (memcmp(buf, rbuf, bsize) != 0) {
204 			perror("memcmp");
205 			exit(9);
206 		}
207 	}
208 	if (vflag) {
209 		(void) fprintf(stderr,
210 		    "Wrote to offset %jd\n", (intmax_t)(offset + roffset));
211 		if (rflag) {
212 			(void) fprintf(stderr,
213 			    "Read back from offset %jd\n",
214 			    (intmax_t)(offset + roffset));
215 		}
216 	}
217 
218 	(void) free(buf);
219 	(void) free(rbuf);
220 }
221 
222 static void
223 do_trunc(int fd)
224 {
225 	off_t   roffset = 0;
226 
227 	roffset = random() % fsize;
228 	if (ftruncate64(fd, (offset + roffset))  < 0) {
229 		perror("truncate");
230 		exit(7);
231 	}
232 
233 	if (vflag) {
234 		(void) fprintf(stderr,
235 		    "Truncated at offset %jd\n",
236 		    (intmax_t)(offset + roffset));
237 	}
238 }
239