dj(1): statistics now track hard seeks
This commit is contained in:
parent
571796fe0d
commit
6ed7089b25
11
docs/dj.1
11
docs/dj.1
|
@ -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
|
||||||
|
|
||||||
|
|
36
src/dj.c
36
src/dj.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user