]>
Commit | Line | Data |
---|---|---|
e246ba5f NS |
1 | /* |
2 | * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. | |
dfc130f3 | 3 | * |
e246ba5f NS |
4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of version 2 of the GNU General Public License as | |
6 | * published by the Free Software Foundation. | |
dfc130f3 | 7 | * |
e246ba5f NS |
8 | * This program is distributed in the hope that it would be useful, but |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
dfc130f3 | 11 | * |
e246ba5f NS |
12 | * Further, this software is distributed without any warranty that it is |
13 | * free of the rightful claim of any third person regarding infringement | |
14 | * or the like. Any license provided herein, whether implied or | |
15 | * otherwise, applies only to this software file. Patent licenses, if | |
16 | * any, provided herein do not apply to combinations of this program with | |
17 | * other software, or any other product whatsoever. | |
dfc130f3 | 18 | * |
e246ba5f NS |
19 | * You should have received a copy of the GNU General Public License along |
20 | * with this program; if not, write the Free Software Foundation, Inc., 59 | |
21 | * Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
dfc130f3 | 22 | * |
e246ba5f NS |
23 | * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, |
24 | * Mountain View, CA 94043, or: | |
dfc130f3 RC |
25 | * |
26 | * http://www.sgi.com | |
27 | * | |
28 | * For further information regarding this notice, see: | |
29 | * | |
e246ba5f NS |
30 | * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ |
31 | */ | |
32 | ||
33 | #include <libxfs.h> | |
34 | #include "command.h" | |
35 | #include "input.h" | |
36 | #include "init.h" | |
37 | ||
38 | static cmdinfo_t pwrite_cmd; | |
39 | ||
40 | static void | |
41 | pwrite_help(void) | |
42 | { | |
43 | printf(_( | |
44 | "\n" | |
45 | " writes a range of bytes (in block size increments) from the given offset\n" | |
46 | "\n" | |
47 | " Example:\n" | |
48 | " 'write 512 20' - writes 20 bytes at 512 bytes into the open file\n" | |
49 | "\n" | |
50 | " Writes into a segment of the currently open file, using either a buffer\n" | |
51 | " filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" | |
52 | " -S -- use an alternate seed number\n" | |
53 | " -i -- specifies an input file from which to source data to write\n" | |
54 | " -d -- open the input file for direct IO\n" | |
55 | " -s -- skip a number of bytes at the start of the input file\n" | |
56 | " The writes are performed in sequential blocks starting at offset, with the\n" | |
57 | " blocksize tunable using the -b option (default blocksize is 4096 bytes).\n" | |
58 | "\n")); | |
59 | } | |
60 | ||
61 | static int | |
62 | write_buffer( | |
63 | off64_t offset, | |
64 | ssize_t count, | |
65 | ssize_t bs, | |
66 | int fd, | |
67 | off64_t skip, | |
68 | ssize_t *total) | |
69 | { | |
70 | ssize_t bytes, itotal = min(bs,count); | |
71 | ||
72 | *total = 0; | |
73 | while (count > 0) { | |
74 | if (fd > 0) { /* input file given, read buffer first */ | |
75 | if (!read_buffer(fd, skip + *total, bs, &itotal, 0, 1)) | |
76 | break; | |
77 | } | |
78 | bytes = pwrite64(fdesc, buffer, min(itotal,count), offset); | |
79 | if (bytes == 0) | |
80 | break; | |
81 | if (bytes < 0) { | |
82 | perror("pwrite64"); | |
83 | return 0; | |
84 | } | |
85 | *total += bytes; | |
86 | if (bytes < count) | |
87 | break; | |
88 | offset += bytes; | |
89 | count -= bytes; | |
90 | } | |
91 | return 1; | |
92 | } | |
93 | ||
94 | static int | |
95 | pwrite_f( | |
96 | int argc, | |
97 | char **argv) | |
98 | { | |
99 | off64_t offset, skip = 0; | |
100 | ssize_t count, total; | |
101 | unsigned int seed = 0xcdcdcdcd; | |
102 | unsigned int bsize = 4096; | |
103 | char *sp, *infile = NULL; | |
104 | int c, fd = -1, dflag = 0; | |
105 | ||
106 | while ((c = getopt(argc, argv, "b:df:i:s:S:")) != EOF) { | |
107 | switch (c) { | |
108 | case 'b': | |
109 | bsize = strtoul(optarg, &sp, 0); | |
110 | if (!sp || sp == optarg) { | |
111 | printf(_("non-numeric bsize -- %s\n"), optarg); | |
112 | return 0; | |
113 | } | |
114 | break; | |
115 | case 'd': | |
116 | dflag = 1; | |
117 | break; | |
118 | case 'f': | |
119 | case 'i': | |
120 | infile = optarg; | |
121 | break; | |
122 | case 's': | |
123 | skip = strtoul(optarg, &sp, 0); | |
124 | if (!sp || sp == optarg) { | |
125 | printf(_("non-numeric skip -- %s\n"), optarg); | |
126 | return 0; | |
127 | } | |
128 | break; | |
129 | case 'S': | |
130 | seed = strtoul(optarg, &sp, 0); | |
131 | if (!sp || sp == optarg) { | |
132 | printf(_("non-numeric seed -- %s\n"), optarg); | |
133 | return 0; | |
134 | } | |
135 | break; | |
136 | default: | |
137 | printf("%s %s\n", pwrite_cmd.name, pwrite_cmd.oneline); | |
138 | return 0; | |
139 | } | |
140 | } | |
141 | if ( ((skip || dflag) && !infile) || (optind != argc - 2)) { | |
142 | printf("%s %s\n", pwrite_cmd.name, pwrite_cmd.oneline); | |
143 | return 0; | |
144 | } | |
145 | offset = strtoul(argv[optind], &sp, 0); | |
146 | if (!sp || sp == argv[optind]) { | |
147 | printf(_("non-numeric offset argument -- %s\n"), argv[optind]); | |
148 | return 0; | |
149 | } | |
150 | optind++; | |
151 | count = strtoul(argv[optind], &sp, 0); | |
152 | if (!sp || sp == argv[optind]) { | |
153 | printf(_("non-numeric length argument -- %s\n"), argv[optind]); | |
154 | return 0; | |
155 | } | |
156 | ||
157 | if (!alloc_buffer(bsize, seed)) | |
158 | return 0; | |
159 | ||
160 | if (infile && ((fd = openfile(infile, 0, 0, dflag, 1, 0, 0, 0)) < 0)) | |
161 | return 0; | |
162 | ||
163 | if (!write_buffer(offset, count, bsize, fd, skip, &total)) { | |
164 | close(fd); | |
165 | return 0; | |
166 | } | |
167 | printf(_("wrote %u/%u bytes at offset %llu\n"), count, total, offset); | |
168 | close(fd); | |
169 | return 0; | |
170 | } | |
171 | ||
172 | void | |
173 | pwrite_init(void) | |
174 | { | |
175 | pwrite_cmd.name = _("pwrite"); | |
176 | pwrite_cmd.altname = _("w"); | |
177 | pwrite_cmd.cfunc = pwrite_f; | |
178 | pwrite_cmd.argmin = 2; | |
179 | pwrite_cmd.argmax = -1; | |
180 | pwrite_cmd.args = | |
181 | _("[-i infile [-d] [-s skip]] [-b bs] [-S seed] off len"); | |
182 | pwrite_cmd.oneline = | |
183 | _("writes a number of bytes at a specified offset"); | |
184 | pwrite_cmd.help = pwrite_help; | |
185 | ||
186 | add_command(&pwrite_cmd); | |
187 | } |