]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/pread.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / io / pread.c
1 /*
2 * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved.
3 *
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.
7 *
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.
11 *
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.
18 *
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.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <libxfs.h>
34 #include <ctype.h>
35 #include "command.h"
36 #include "input.h"
37 #include "init.h"
38
39 static cmdinfo_t pread_cmd;
40
41 static void
42 pread_help(void)
43 {
44 printf(_(
45 "\n"
46 " reads a range of bytes in a specified block size from the given offset\n"
47 "\n"
48 " Example:\n"
49 " 'read -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n"
50 "\n"
51 " Reads a segment of the currently open file, optionally dumping it to the\n"
52 " standard output stream (with -v option) for subsequent inspection.\n"
53 " The reads are performed in sequential blocks starting at offset, with the\n"
54 " blocksize tunable using the -b option (default blocksize is 4096 bytes).\n"
55 "\n"));
56 }
57
58 void *buffer;
59 ssize_t buffersize;
60
61 int
62 alloc_buffer(
63 ssize_t bsize,
64 unsigned int seed)
65 {
66 if (bsize > buffersize) {
67 if (buffer)
68 free(buffer);
69 buffer = memalign(getpagesize(), buffersize = bsize);
70 if (!buffer) {
71 perror("memalign");
72 buffersize = 0;
73 return 0;
74 }
75 }
76 memset(buffer, seed, buffersize);
77 return 1;
78 }
79
80 static void
81 dump_buffer(
82 off64_t offset,
83 ssize_t len)
84 {
85 int i, j;
86 char *p;
87
88 for (i = 0, p = (char *)buffer; i < len; i += 16) {
89 char *s = p;
90
91 printf("%08llx: ", (off64_t)i + offset);
92 for (j = 0; j < 16 && i + j < len; j++, p++)
93 printf("%02x ", *p);
94 printf(" ");
95 for (j = 0; j < 16 && i + j < len; j++, s++) {
96 if (isalnum((int)*s))
97 printf("%c", *s);
98 else
99 printf(".");
100 }
101 printf("\n");
102 }
103 }
104
105 int
106 read_buffer(
107 int fd,
108 off64_t offset,
109 ssize_t count,
110 ssize_t *total,
111 int verbose,
112 int onlyone)
113 {
114 ssize_t bytes;
115
116 *total = 0;
117 while (count > 0) {
118 bytes = pread64(fd, buffer, min(count,buffersize), offset);
119 if (bytes == 0)
120 break;
121 if (bytes < 0) {
122 perror("pread64");
123 return 0;
124 }
125 if (verbose)
126 dump_buffer(offset, bytes);
127 *total += bytes;
128 if (onlyone || bytes < count)
129 break;
130 offset += bytes;
131 count -= bytes;
132 }
133 return 1;
134 }
135
136 static int
137 pread_f(
138 int argc,
139 char **argv)
140 {
141 off64_t offset;
142 ssize_t count, total;
143 unsigned int bsize = 4096;
144 char *sp;
145 int vflag = 0;
146 int c;
147
148 while ((c = getopt(argc, argv, "b:v")) != EOF) {
149 switch (c) {
150 case 'b':
151 bsize = strtoul(optarg, &sp, 0);
152 if (!sp || sp == optarg) {
153 printf(_("non-numeric bsize -- %s\n"), optarg);
154 return 0;
155 }
156 break;
157 case 'v':
158 vflag = 1;
159 break;
160 default:
161 printf("%s %s\n", pread_cmd.name, pread_cmd.oneline);
162 return 0;
163 }
164 }
165 if (optind != argc - 2) {
166 printf("%s %s\n", pread_cmd.name, pread_cmd.oneline);
167 return 0;
168 }
169 offset = strtoul(argv[optind], &sp, 0);
170 if (!sp || sp == argv[optind]) {
171 printf(_("non-numeric offset argument -- %s\n"), argv[optind]);
172 return 0;
173 }
174 optind++;
175 count = strtoul(argv[optind], &sp, 0);
176 if (!sp || sp == argv[optind]) {
177 printf(_("non-numeric length argument -- %s\n"), argv[optind]);
178 return 0;
179 }
180
181 if (!alloc_buffer(bsize, 0xabababab))
182 return 0;
183
184 if (!read_buffer(fdesc, offset, count, &total, vflag, 0))
185 return 0;
186
187 printf(_("read %u/%u bytes at offset %llu\n"), total, count, offset);
188 return 0;
189 }
190
191 void
192 pread_init(void)
193 {
194 pread_cmd.name = _("pread");
195 pread_cmd.altname = _("r");
196 pread_cmd.cfunc = pread_f;
197 pread_cmd.argmin = 2;
198 pread_cmd.argmax = -1;
199 pread_cmd.args = _("[-b bs] [-v] off len");
200 pread_cmd.oneline = _("reads a number of bytes at a specified offset");
201 pread_cmd.help = pread_help;
202
203 add_command(&pread_cmd);
204 }