Path: blob/main/tests/sys/cddl/zfs/bin/file_write.c
39536 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License (the "License").5* You may not use this file except in compliance with the License.6*7* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE8* or http://www.opensolaris.org/os/licensing.9* See the License for the specific language governing permissions10* and limitations under the License.11*12* When distributing Covered Code, include this CDDL HEADER in each13* file and include the License file at usr/src/OPENSOLARIS.LICENSE.14* If applicable, add the following below this CDDL HEADER, with the15* fields enclosed by brackets "[]" replaced with your own identifying16* information: Portions Copyright [yyyy] [name of copyright owner]17*18* CDDL HEADER END19*/2021/*22* Copyright 2007 Sun Microsystems, Inc. All rights reserved.23* Use is subject to license terms.24*/252627#include "file_common.h"28#include <inttypes.h>29#include <libgen.h>3031static unsigned char bigbuffer[BIGBUFFERSIZE];3233/*34* Writes (or appends) a given value to a file repeatedly.35* See header file for defaults.36*/3738static void usage(void) __dead2;39static char *execname;4041int42main(int argc, char **argv)43{44int bigfd;45int c;46int oflag = 0;47int err = 0;48int k;49long i;50int64_t good_writes = 0;51uint8_t nxtfillchar;52/*53* Default Parameters54*/55int write_count = BIGFILESIZE;56uint8_t fillchar = DATA;57int block_size = BLOCKSZ;58char *filename = NULL;59char *operation = NULL;60off_t noffset, offset = 0;61int verbose = 0;62int rsync = 0;63int wsync = 0;6465execname = argv[0];6667/*68* Process Arguments69*/70while ((c = getopt(argc, argv, "b:c:d:s:f:o:vwr")) != -1) {71switch (c) {72case 'b':73block_size = atoi(optarg);74break;75case 'c':76write_count = atoi(optarg);77break;78case 'd':79fillchar = atoi(optarg);80break;81case 's':82offset = atoll(optarg);83break;84case 'f':85filename = optarg;86break;87case 'o':88operation = optarg;89break;90case 'v':91verbose = 1;92break;93case 'w':94wsync = 1;95break;96case 'r':97rsync = 1;98break;99case '?':100(void) printf("unknown arg %c\n", optopt);101usage();102break;103}104}105106/*107* Validate Parameters108*/109if (!filename) {110(void) printf("Filename not specified (-f <file>)\n");111err++;112}113114if (!operation) {115(void) printf("Operation not specified (-o <operation>).\n");116err++;117}118119if (block_size > BIGBUFFERSIZE) {120(void) printf("block_size is too large max==%d.\n",121BIGBUFFERSIZE);122err++;123}124125if (err) usage();126127/*128* Prepare the buffer and determine the requested operation129*/130nxtfillchar = fillchar;131k = 0;132133for (i = 0; i < block_size; i++) {134bigbuffer[i] = nxtfillchar;135136if (fillchar == 0) {137if ((k % DATA_RANGE) == 0) {138k = 0;139}140nxtfillchar = k++;141}142}143144/*145* using the strncmp of operation will make the operation match the146* first shortest match - as the operations are unique from the first147* character this means that we match single character operations148*/149if ((strncmp(operation, "create", strlen(operation) + 1)) == 0 ||150(strncmp(operation, "overwrite", strlen(operation) + 1)) == 0) {151oflag = (O_RDWR|O_CREAT);152} else if ((strncmp(operation, "append", strlen(operation) + 1)) == 0) {153oflag = (O_RDWR|O_APPEND);154} else {155(void) printf("valid operations are <create|append> not '%s'\n",156operation);157usage();158}159160#ifdef UNSUPPORTED161if (rsync) {162oflag = oflag | O_RSYNC;163}164#endif165166if (wsync) {167oflag = oflag | O_SYNC;168}169170/*171* Given an operation (create/overwrite/append), open the file172* accordingly and perform a write of the appropriate type.173*/174if ((bigfd = open(filename, oflag, 0666)) == -1) {175(void) printf("open %s: failed [%s]%d. Aborting!\n", filename,176strerror(errno), errno);177exit(errno);178}179noffset = lseek(bigfd, offset, SEEK_SET);180if (noffset != offset) {181(void) printf("lseek %s (%"PRId64"/%"PRId64") "182"failed [%s]%d. Aborting!\n",183filename, offset, noffset, strerror(errno), errno);184exit(errno);185}186187if (verbose) {188(void) printf("%s: block_size = %d, write_count = %d, "189"offset = %"PRId64", data = %s%d\n", filename, block_size,190write_count, offset,191(fillchar == 0) ? "0->" : "",192(fillchar == 0) ? DATA_RANGE : fillchar);193}194195for (i = 0; i < write_count; i++) {196ssize_t n;197198if ((n = write(bigfd, &bigbuffer, block_size)) == -1) {199(void) printf("write failed (%ld), "200"good_writes = %"PRId64", "201"error: %s[%d]\n", (long)n, good_writes,202strerror(errno), errno);203exit(errno);204}205good_writes++;206}207208if (verbose) {209(void) printf("Success: good_writes = %"PRId64" (%"PRId64")\n",210good_writes, (good_writes * block_size));211}212213return (0);214}215216static void217usage(void)218{219char *base = (char *)"file_write";220char *exec = (char *)execname;221222if (exec != NULL)223exec = strdup(exec);224if (exec != NULL)225base = basename(exec);226227(void) printf("Usage: %s [-v] -o {create,overwrite,append} -f file_name"228" [-b block_size]\n"229"\t[-s offset] [-c write_count] [-d data]\n"230"\twhere [data] equal to zero causes chars "231"0->%d to be repeated throughout\n", base, DATA_RANGE);232233if (exec) {234free(exec);235}236237exit(1);238}239240241