12fae26bdSAlan Somers /*
22fae26bdSAlan Somers * CDDL HEADER START
32fae26bdSAlan Somers *
42fae26bdSAlan Somers * The contents of this file are subject to the terms of the
52fae26bdSAlan Somers * Common Development and Distribution License (the "License").
62fae26bdSAlan Somers * You may not use this file except in compliance with the License.
72fae26bdSAlan Somers *
82fae26bdSAlan Somers * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92fae26bdSAlan Somers * or http://www.opensolaris.org/os/licensing.
102fae26bdSAlan Somers * See the License for the specific language governing permissions
112fae26bdSAlan Somers * and limitations under the License.
122fae26bdSAlan Somers *
132fae26bdSAlan Somers * When distributing Covered Code, include this CDDL HEADER in each
142fae26bdSAlan Somers * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152fae26bdSAlan Somers * If applicable, add the following below this CDDL HEADER, with the
162fae26bdSAlan Somers * fields enclosed by brackets "[]" replaced with your own identifying
172fae26bdSAlan Somers * information: Portions Copyright [yyyy] [name of copyright owner]
182fae26bdSAlan Somers *
192fae26bdSAlan Somers * CDDL HEADER END
202fae26bdSAlan Somers */
212fae26bdSAlan Somers
222fae26bdSAlan Somers /*
232fae26bdSAlan Somers * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
242fae26bdSAlan Somers * Use is subject to license terms.
252fae26bdSAlan Somers */
262fae26bdSAlan Somers
272fae26bdSAlan Somers
282fae26bdSAlan Somers #include "file_common.h"
299e5787d2SMatt Macy #include <inttypes.h>
302fae26bdSAlan Somers #include <libgen.h>
312fae26bdSAlan Somers
322fae26bdSAlan Somers static unsigned char bigbuffer[BIGBUFFERSIZE];
332fae26bdSAlan Somers
342fae26bdSAlan Somers /*
352fae26bdSAlan Somers * Writes (or appends) a given value to a file repeatedly.
362fae26bdSAlan Somers * See header file for defaults.
372fae26bdSAlan Somers */
382fae26bdSAlan Somers
39*6fde0662SAlfonso Gregory static void usage(void) __dead2;
402fae26bdSAlan Somers static char *execname;
412fae26bdSAlan Somers
422fae26bdSAlan Somers int
main(int argc,char ** argv)432fae26bdSAlan Somers main(int argc, char **argv)
442fae26bdSAlan Somers {
452fae26bdSAlan Somers int bigfd;
462fae26bdSAlan Somers int c;
472fae26bdSAlan Somers int oflag = 0;
482fae26bdSAlan Somers int err = 0;
492fae26bdSAlan Somers int k;
502fae26bdSAlan Somers long i;
512fae26bdSAlan Somers int64_t good_writes = 0;
522fae26bdSAlan Somers uint8_t nxtfillchar;
532fae26bdSAlan Somers /*
542fae26bdSAlan Somers * Default Parameters
552fae26bdSAlan Somers */
562fae26bdSAlan Somers int write_count = BIGFILESIZE;
572fae26bdSAlan Somers uint8_t fillchar = DATA;
582fae26bdSAlan Somers int block_size = BLOCKSZ;
592fae26bdSAlan Somers char *filename = NULL;
602fae26bdSAlan Somers char *operation = NULL;
612fae26bdSAlan Somers off_t noffset, offset = 0;
622fae26bdSAlan Somers int verbose = 0;
632fae26bdSAlan Somers int rsync = 0;
642fae26bdSAlan Somers int wsync = 0;
652fae26bdSAlan Somers
662fae26bdSAlan Somers execname = argv[0];
672fae26bdSAlan Somers
682fae26bdSAlan Somers /*
692fae26bdSAlan Somers * Process Arguments
702fae26bdSAlan Somers */
712fae26bdSAlan Somers while ((c = getopt(argc, argv, "b:c:d:s:f:o:vwr")) != -1) {
722fae26bdSAlan Somers switch (c) {
732fae26bdSAlan Somers case 'b':
742fae26bdSAlan Somers block_size = atoi(optarg);
752fae26bdSAlan Somers break;
762fae26bdSAlan Somers case 'c':
772fae26bdSAlan Somers write_count = atoi(optarg);
782fae26bdSAlan Somers break;
792fae26bdSAlan Somers case 'd':
802fae26bdSAlan Somers fillchar = atoi(optarg);
812fae26bdSAlan Somers break;
822fae26bdSAlan Somers case 's':
832fae26bdSAlan Somers offset = atoll(optarg);
842fae26bdSAlan Somers break;
852fae26bdSAlan Somers case 'f':
862fae26bdSAlan Somers filename = optarg;
872fae26bdSAlan Somers break;
882fae26bdSAlan Somers case 'o':
892fae26bdSAlan Somers operation = optarg;
902fae26bdSAlan Somers break;
912fae26bdSAlan Somers case 'v':
922fae26bdSAlan Somers verbose = 1;
932fae26bdSAlan Somers break;
942fae26bdSAlan Somers case 'w':
952fae26bdSAlan Somers wsync = 1;
962fae26bdSAlan Somers break;
972fae26bdSAlan Somers case 'r':
982fae26bdSAlan Somers rsync = 1;
992fae26bdSAlan Somers break;
1002fae26bdSAlan Somers case '?':
1012fae26bdSAlan Somers (void) printf("unknown arg %c\n", optopt);
1022fae26bdSAlan Somers usage();
1032fae26bdSAlan Somers break;
1042fae26bdSAlan Somers }
1052fae26bdSAlan Somers }
1062fae26bdSAlan Somers
1072fae26bdSAlan Somers /*
1082fae26bdSAlan Somers * Validate Parameters
1092fae26bdSAlan Somers */
1102fae26bdSAlan Somers if (!filename) {
1112fae26bdSAlan Somers (void) printf("Filename not specified (-f <file>)\n");
1122fae26bdSAlan Somers err++;
1132fae26bdSAlan Somers }
1142fae26bdSAlan Somers
1152fae26bdSAlan Somers if (!operation) {
1162fae26bdSAlan Somers (void) printf("Operation not specified (-o <operation>).\n");
1172fae26bdSAlan Somers err++;
1182fae26bdSAlan Somers }
1192fae26bdSAlan Somers
1202fae26bdSAlan Somers if (block_size > BIGBUFFERSIZE) {
1212fae26bdSAlan Somers (void) printf("block_size is too large max==%d.\n",
1222fae26bdSAlan Somers BIGBUFFERSIZE);
1232fae26bdSAlan Somers err++;
1242fae26bdSAlan Somers }
1252fae26bdSAlan Somers
1262fae26bdSAlan Somers if (err) usage();
1272fae26bdSAlan Somers
1282fae26bdSAlan Somers /*
1292fae26bdSAlan Somers * Prepare the buffer and determine the requested operation
1302fae26bdSAlan Somers */
1312fae26bdSAlan Somers nxtfillchar = fillchar;
1322fae26bdSAlan Somers k = 0;
1332fae26bdSAlan Somers
1342fae26bdSAlan Somers for (i = 0; i < block_size; i++) {
1352fae26bdSAlan Somers bigbuffer[i] = nxtfillchar;
1362fae26bdSAlan Somers
1372fae26bdSAlan Somers if (fillchar == 0) {
1382fae26bdSAlan Somers if ((k % DATA_RANGE) == 0) {
1392fae26bdSAlan Somers k = 0;
1402fae26bdSAlan Somers }
1412fae26bdSAlan Somers nxtfillchar = k++;
1422fae26bdSAlan Somers }
1432fae26bdSAlan Somers }
1442fae26bdSAlan Somers
1452fae26bdSAlan Somers /*
1462fae26bdSAlan Somers * using the strncmp of operation will make the operation match the
1472fae26bdSAlan Somers * first shortest match - as the operations are unique from the first
1482fae26bdSAlan Somers * character this means that we match single character operations
1492fae26bdSAlan Somers */
1502fae26bdSAlan Somers if ((strncmp(operation, "create", strlen(operation) + 1)) == 0 ||
1512fae26bdSAlan Somers (strncmp(operation, "overwrite", strlen(operation) + 1)) == 0) {
1522fae26bdSAlan Somers oflag = (O_RDWR|O_CREAT);
1532fae26bdSAlan Somers } else if ((strncmp(operation, "append", strlen(operation) + 1)) == 0) {
1542fae26bdSAlan Somers oflag = (O_RDWR|O_APPEND);
1552fae26bdSAlan Somers } else {
1562fae26bdSAlan Somers (void) printf("valid operations are <create|append> not '%s'\n",
1572fae26bdSAlan Somers operation);
1582fae26bdSAlan Somers usage();
1592fae26bdSAlan Somers }
1602fae26bdSAlan Somers
1612fae26bdSAlan Somers #ifdef UNSUPPORTED
1622fae26bdSAlan Somers if (rsync) {
1632fae26bdSAlan Somers oflag = oflag | O_RSYNC;
1642fae26bdSAlan Somers }
1652fae26bdSAlan Somers #endif
1662fae26bdSAlan Somers
1672fae26bdSAlan Somers if (wsync) {
1682fae26bdSAlan Somers oflag = oflag | O_SYNC;
1692fae26bdSAlan Somers }
1702fae26bdSAlan Somers
1712fae26bdSAlan Somers /*
1722fae26bdSAlan Somers * Given an operation (create/overwrite/append), open the file
1732fae26bdSAlan Somers * accordingly and perform a write of the appropriate type.
1742fae26bdSAlan Somers */
1752fae26bdSAlan Somers if ((bigfd = open(filename, oflag, 0666)) == -1) {
1762fae26bdSAlan Somers (void) printf("open %s: failed [%s]%d. Aborting!\n", filename,
1772fae26bdSAlan Somers strerror(errno), errno);
1782fae26bdSAlan Somers exit(errno);
1792fae26bdSAlan Somers }
1802fae26bdSAlan Somers noffset = lseek(bigfd, offset, SEEK_SET);
1812fae26bdSAlan Somers if (noffset != offset) {
1829e5787d2SMatt Macy (void) printf("lseek %s (%"PRId64"/%"PRId64") "
1839e5787d2SMatt Macy "failed [%s]%d. Aborting!\n",
1842fae26bdSAlan Somers filename, offset, noffset, strerror(errno), errno);
1852fae26bdSAlan Somers exit(errno);
1862fae26bdSAlan Somers }
1872fae26bdSAlan Somers
1882fae26bdSAlan Somers if (verbose) {
1892fae26bdSAlan Somers (void) printf("%s: block_size = %d, write_count = %d, "
1909e5787d2SMatt Macy "offset = %"PRId64", data = %s%d\n", filename, block_size,
1912fae26bdSAlan Somers write_count, offset,
1922fae26bdSAlan Somers (fillchar == 0) ? "0->" : "",
1932fae26bdSAlan Somers (fillchar == 0) ? DATA_RANGE : fillchar);
1942fae26bdSAlan Somers }
1952fae26bdSAlan Somers
1962fae26bdSAlan Somers for (i = 0; i < write_count; i++) {
1972fae26bdSAlan Somers ssize_t n;
1982fae26bdSAlan Somers
1992fae26bdSAlan Somers if ((n = write(bigfd, &bigbuffer, block_size)) == -1) {
2009e5787d2SMatt Macy (void) printf("write failed (%ld), "
2019e5787d2SMatt Macy "good_writes = %"PRId64", "
2022fae26bdSAlan Somers "error: %s[%d]\n", (long)n, good_writes,
2039e5787d2SMatt Macy strerror(errno), errno);
2042fae26bdSAlan Somers exit(errno);
2052fae26bdSAlan Somers }
2062fae26bdSAlan Somers good_writes++;
2072fae26bdSAlan Somers }
2082fae26bdSAlan Somers
2092fae26bdSAlan Somers if (verbose) {
2109e5787d2SMatt Macy (void) printf("Success: good_writes = %"PRId64" (%"PRId64")\n",
2112fae26bdSAlan Somers good_writes, (good_writes * block_size));
2122fae26bdSAlan Somers }
2132fae26bdSAlan Somers
2142fae26bdSAlan Somers return (0);
2152fae26bdSAlan Somers }
2162fae26bdSAlan Somers
2172fae26bdSAlan Somers static void
usage(void)2182fae26bdSAlan Somers usage(void)
2192fae26bdSAlan Somers {
2202fae26bdSAlan Somers char *base = (char *)"file_write";
2212fae26bdSAlan Somers char *exec = (char *)execname;
2222fae26bdSAlan Somers
2232fae26bdSAlan Somers if (exec != NULL)
2242fae26bdSAlan Somers exec = strdup(exec);
2252fae26bdSAlan Somers if (exec != NULL)
2262fae26bdSAlan Somers base = basename(exec);
2272fae26bdSAlan Somers
2282fae26bdSAlan Somers (void) printf("Usage: %s [-v] -o {create,overwrite,append} -f file_name"
2292fae26bdSAlan Somers " [-b block_size]\n"
2302fae26bdSAlan Somers "\t[-s offset] [-c write_count] [-d data]\n"
2312fae26bdSAlan Somers "\twhere [data] equal to zero causes chars "
2322fae26bdSAlan Somers "0->%d to be repeated throughout\n", base, DATA_RANGE);
2332fae26bdSAlan Somers
2342fae26bdSAlan Somers if (exec) {
2352fae26bdSAlan Somers free(exec);
2362fae26bdSAlan Somers }
2372fae26bdSAlan Somers
2382fae26bdSAlan Somers exit(1);
2392fae26bdSAlan Somers }
240