2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright (c) 2018 by Delphix. All rights reserved.
16 #include <sys/types.h>
26 static char *ifile = NULL;
27 static char *ofile = NULL;
28 static int stride = 0;
30 static char *execname = "stride_dd";
32 static void usage(void);
33 static void parse_options(int argc, char *argv[]);
38 (void) fprintf(stderr,
39 "usage: %s -i inputfile -o outputfile -b blocksize -c count \n"
40 " -s stride [ -k seekblocks]\n"
42 "Simplified version of dd that supports the stride option.\n"
43 "A stride of n means that for each block written, n - 1 blocks\n"
44 "are skipped in both the input and output file. A stride of 1\n"
45 "means that blocks are read and written consecutively.\n"
46 "All numeric parameters must be integers.\n"
48 " inputfile: File to read from\n"
49 " outputfile: File to write to\n"
50 " blocksize: Size of each block to read/write\n"
51 " count: Number of blocks to read/write\n"
52 " stride: Read/write a block then skip (stride - 1) blocks\n"
53 " seekblocks: Number of blocks to skip at start of output\n",
59 parse_options(int argc, char *argv[])
67 extern int optind, optopt;
69 while ((c = getopt(argc, argv, ":b:c:i:o:s:k:")) != -1) {
88 stride = atoi(optarg);
96 (void) fprintf(stderr,
97 "Option -%c requires an operand\n", optopt);
103 (void) fprintf(stderr,
104 "Unrecognized option: -%c\n", optopt);
114 if (bsize <= 0 || count <= 0 || stride <= 0 || ifile == NULL ||
115 ofile == NULL || seek < 0) {
116 (void) fprintf(stderr,
117 "Required parameter(s) missing or invalid.\n");
123 main(int argc, char *argv[])
131 parse_options(argc, argv);
133 ifd = open(ifile, O_RDONLY);
135 (void) fprintf(stderr, "%s: %s: ", execname, ifile);
140 ofd = open(ofile, O_WRONLY | O_CREAT, 0666);
142 (void) fprintf(stderr, "%s: %s: ", execname, ofile);
148 * We use valloc because some character block devices expect a
149 * page-aligned buffer.
151 int err = posix_memalign(&buf, 4096, bsize);
153 (void) fprintf(stderr,
154 "%s: %s\n", execname, strerror(err));
159 if (lseek(ofd, seek * bsize, SEEK_CUR) == -1) {
160 perror("output lseek");
165 for (i = 0; i < count; i++) {
166 c = read(ifd, buf, bsize);
176 (void) fprintf(stderr,
177 "%s: unexpected short read, read %d "
178 "bytes, expected %d\n", execname,
184 c = write(ofd, buf, bsize);
189 (void) fprintf(stderr,
190 "%s: unexpected short write, wrote %d "
191 "bytes, expected %d\n", execname,
198 if (lseek(ifd, (stride - 1) * bsize, SEEK_CUR) == -1) {
199 perror("input lseek");
202 if (lseek(ofd, (stride - 1) * bsize, SEEK_CUR) == -1) {
203 perror("output lseek");