dj(1): statistics now track hard seeks

This commit is contained in:
dtb 2024-07-04 21:32:05 -06:00
parent 571796fe0d
commit 6ed7089b25
Signed by: trinity
GPG Key ID: 34C0543BBB6AF81B
2 changed files with 18 additions and 29 deletions

View File

@ -41,10 +41,6 @@ with a skip offset of 1 skips one byte into the input and reads from the second
byte onwards. A programmer may think of a file as a zero-indexed array of byte onwards. A programmer may think of a file as a zero-indexed array of
bytes; in this analogy, the offset given is the index of the byte at which to bytes; in this analogy, the offset given is the index of the byte at which to
start reading or writing. start reading or writing.
Seeks aren\(cqt counted in the output statistics because they\(cqre guaranteed
to succeed (or the utility will exit unsuccessfully, before it has written any
data).
.\" .\"
.SH OPTIONS .SH OPTIONS
@ -195,9 +191,10 @@ and
.BR -S . .BR -S .
The lowercase option affects input and the capitalized option affects output. The lowercase option affects input and the capitalized option affects output.
The discarded but read bytes skipped while processing irregular files, such as The skipped or sought bytes while processing irregular files, such as streams,
streams, are reported in the diagnostic output. Bytes skipped while processing are reported in the diagnostic output, because they were actually read or
regular files are not reported, as the bytes weren\(cqt read. written. This is as opposed to bytes skipped while processing regular files,
which are not reported.
.\" .\"
.SH RATIONALE .SH RATIONALE

View File

@ -56,7 +56,6 @@ static char *fmt_human = "%d+%d > %d+%d; %d > %d\n";
static char *stdin_name = "<stdin>"; static char *stdin_name = "<stdin>";
static char *stdout_name = "<stdout>"; static char *stdout_name = "<stdout>";
static int creat_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH static int creat_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
| S_IWOTH; /* Consistent with touch(1p). */ | S_IWOTH; /* Consistent with touch(1p). */
static int read_flags = O_RDONLY; /* Consistent with Busybox dd(1). */ static int read_flags = O_RDONLY; /* Consistent with Busybox dd(1). */
@ -239,37 +238,29 @@ int main(int argc, char *argv[]){
/* hard seeking */ /* hard seeking */
if(io[1].seek > 0){ if(io[1].seek > 0){
memset(io[1].buf, '\0', io[1].bs); size_t t;
/* We're going to cheat and use bufuse as the retval for write(2),
* which is fine because it'll be zeroed as this function returns
* anyway. */
do{ do{
if((io[1].bufuse = write( memset(io[1].buf, '\0',
io[1].fd, io[1].buf, MIN(io[1].bs, io[1].seek))) (t = io[1].bufuse = MIN(io[1].bs, io[1].seek)));
== 0) if(Io_write(&io[1])->bufuse == t && !noerror)
/* second chance */ Io_write(&io[1]); /* second chance */
io[1].bufuse = write( }while((io[1].seek -= (t - io[1].bufuse)) > 0 && io[1].bufuse != t);
io[1].fd, io[1].buf, MIN(io[1].bs, io[1].seek));
}while((io[1].seek -= io[1].bufuse) > 0 && io[1].bufuse != 0);
io[1].bufuse = 0; io[1].bufuse = 0;
} }
/* Sought bytes aren't counted in the statistics because successful seeking if(io[1].seek > 0){
* is guaranteed here. */ fprintio(stderr, fmt, io);
if(io[1].seek > 0)
return oserr(io[1].fn); return oserr(io[1].fn);
}
do{ do{
assert(io[0].bufuse == 0); assert(io[0].bufuse == 0);
{ /* read */ { /* read */
static char skipping = 0; char skipping;
int t; int t;
if(io[0].seek > 0) if((skipping = (io[0].seek > 0)) && io[0].seek < io[0].bs)
skipping = 1;
if(skipping && io[0].seek < io[0].bs)
io[0].bufuse = io[0].bs - io[0].seek; io[0].bufuse = io[0].bs - io[0].seek;
t = io[0].bufuse; t = io[0].bufuse;
@ -279,11 +270,13 @@ int main(int argc, char *argv[]){
break; break;
if(/* t < io[0].bufuse && */ io[0].bufuse < io[0].bs){ if(/* t < io[0].bufuse && */ io[0].bufuse < io[0].bs){
assert(!skipping);
fprintf(stderr, "%s: Partial read:\n\t", program_name); fprintf(stderr, "%s: Partial read:\n\t", program_name);
fprintio(stderr, fmt, io); fprintio(stderr, fmt, io);
if(!noerror) if(!noerror)
count = 1; count = 1;
if(!skipping && align >= 0){ if(align >= 0){
/* fill the rest of the ibuf with padding */ /* fill the rest of the ibuf with padding */
memset(&(io[0].buf)[io[0].bufuse], align, memset(&(io[0].buf)[io[0].bufuse], align,
io[0].bs - io[0].bufuse); io[0].bs - io[0].bufuse);
@ -292,7 +285,6 @@ int main(int argc, char *argv[]){
} }
if(skipping){ if(skipping){
skipping = (io[0].seek -= io[0].bufuse - t) > 0;
io[0].bufuse = 0; io[0].bufuse = 0;
count += (count != 0); count += (count != 0);
continue; continue;