bio: add support for custom I/O handler via Biofn
This commit is contained in:
parent
414d29e98f
commit
f681cf835a
9 changed files with 49 additions and 6 deletions
|
@ -33,6 +33,7 @@ struct Biobufhdr
|
||||||
uchar* ebuf; /* pointer to end of buffer */
|
uchar* ebuf; /* pointer to end of buffer */
|
||||||
uchar* gbuf; /* pointer to good data in buf */
|
uchar* gbuf; /* pointer to good data in buf */
|
||||||
void (*errorf)(char *); /* called on error if not nil */
|
void (*errorf)(char *); /* called on error if not nil */
|
||||||
|
int (*iof)(Biobufhdr*, void *, long); /* called to do i/o */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Biobuf
|
struct Biobuf
|
||||||
|
@ -74,6 +75,7 @@ int Bungetrune(Biobufhdr*);
|
||||||
long Bwrite(Biobufhdr*, void*, long);
|
long Bwrite(Biobufhdr*, void*, long);
|
||||||
void Blethal(Biobufhdr*, void(*)(char*));
|
void Blethal(Biobufhdr*, void(*)(char*));
|
||||||
void Berror(Biobufhdr*, char*, ...);
|
void Berror(Biobufhdr*, char*, ...);
|
||||||
|
void Biofn(Biobufhdr*, int(*)(Biobufhdr*, void*, long));
|
||||||
|
|
||||||
#pragma varargck argpos Bprint 2
|
#pragma varargck argpos Bprint 2
|
||||||
#pragma varargck argpos Berror 2
|
#pragma varargck argpos Berror 2
|
||||||
|
|
|
@ -84,6 +84,9 @@ int Bbuffered(Biobufhdr *bp)
|
||||||
.B
|
.B
|
||||||
void Blethal(Biobufhdr *bp, void (*errorf)(char *))
|
void Blethal(Biobufhdr *bp, void (*errorf)(char *))
|
||||||
.PP
|
.PP
|
||||||
|
.B
|
||||||
|
void Biofn(Biobufhdr *bp, int (*iof)(Biohdr *, void *, long))
|
||||||
|
.PP
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
These routines implement fast buffered I/O.
|
These routines implement fast buffered I/O.
|
||||||
I/O on different file descriptors is independent.
|
I/O on different file descriptors is independent.
|
||||||
|
@ -338,6 +341,18 @@ to be called in case of an error happening on read/write.
|
||||||
An argument of
|
An argument of
|
||||||
.B nil
|
.B nil
|
||||||
will have the program terminated in case of error.
|
will have the program terminated in case of error.
|
||||||
|
.PP
|
||||||
|
If
|
||||||
|
.I Biofn
|
||||||
|
is called with a non-nil
|
||||||
|
.I iof
|
||||||
|
function, then that function is called for I/O in lieu of
|
||||||
|
.IR read (2)
|
||||||
|
and
|
||||||
|
.IR write (2).
|
||||||
|
A nil argument for
|
||||||
|
.I iof
|
||||||
|
restores normal behaviour.
|
||||||
.SH SOURCE
|
.SH SOURCE
|
||||||
.B /sys/src/libbio
|
.B /sys/src/libbio
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
|
|
|
@ -12,7 +12,7 @@ Bflush(Biobufhdr *bp)
|
||||||
n = bp->bsize+bp->ocount;
|
n = bp->bsize+bp->ocount;
|
||||||
if(n == 0)
|
if(n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
c = write(bp->fid, bp->bbuf, n);
|
c = bp->iof(bp, bp->bbuf, n);
|
||||||
if(n == c) {
|
if(n == c) {
|
||||||
bp->offset += n;
|
bp->offset += n;
|
||||||
bp->ocount = -bp->bsize;
|
bp->ocount = -bp->bsize;
|
||||||
|
|
|
@ -24,7 +24,7 @@ loop:
|
||||||
* buffer to allow that many ungets.
|
* buffer to allow that many ungets.
|
||||||
*/
|
*/
|
||||||
memmove(bp->bbuf-Bungetsize, bp->ebuf-Bungetsize, Bungetsize);
|
memmove(bp->bbuf-Bungetsize, bp->ebuf-Bungetsize, Bungetsize);
|
||||||
i = read(bp->fid, bp->bbuf, bp->bsize);
|
i = bp->iof(bp, bp->bbuf, bp->bsize);
|
||||||
bp->gbuf = bp->bbuf;
|
bp->gbuf = bp->bbuf;
|
||||||
if(i <= 0) {
|
if(i <= 0) {
|
||||||
bp->state = Bracteof;
|
bp->state = Bracteof;
|
||||||
|
|
|
@ -50,6 +50,18 @@ install(Biobufhdr *bp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bioread(Biobufhdr *bp, void *v, long n)
|
||||||
|
{
|
||||||
|
return read(bp->fid, v, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
biowrite(Biobufhdr *bp, void *v, long n)
|
||||||
|
{
|
||||||
|
return write(bp->fid, v, n);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Binits(Biobufhdr *bp, int f, int mode, uchar *p, int size)
|
Binits(Biobufhdr *bp, int f, int mode, uchar *p, int size)
|
||||||
{
|
{
|
||||||
|
@ -64,12 +76,14 @@ Binits(Biobufhdr *bp, int f, int mode, uchar *p, int size)
|
||||||
case OREAD:
|
case OREAD:
|
||||||
bp->state = Bractive;
|
bp->state = Bractive;
|
||||||
bp->ocount = 0;
|
bp->ocount = 0;
|
||||||
|
bp->iof = bioread;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OWRITE:
|
case OWRITE:
|
||||||
install(bp);
|
install(bp);
|
||||||
bp->state = Bwactive;
|
bp->state = Bwactive;
|
||||||
bp->ocount = -size;
|
bp->ocount = -size;
|
||||||
|
bp->iof = biowrite;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bp->bbuf = p;
|
bp->bbuf = p;
|
||||||
|
@ -154,3 +168,15 @@ Bterm(Biobufhdr *bp)
|
||||||
/* otherwise opened with Binit(s) */
|
/* otherwise opened with Binit(s) */
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Biofn(Biobufhdr *bp, int (*f)(Biobufhdr *, void *, long))
|
||||||
|
{
|
||||||
|
if(f == nil)
|
||||||
|
if(bp->state == Bwactive)
|
||||||
|
bp->iof = biowrite;
|
||||||
|
else
|
||||||
|
bp->iof = bioread;
|
||||||
|
else
|
||||||
|
bp->iof = f;
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ Brdline(Biobufhdr *bp, int delim)
|
||||||
*/
|
*/
|
||||||
ip = (char*)bp->bbuf + i;
|
ip = (char*)bp->bbuf + i;
|
||||||
while(i < bp->bsize) {
|
while(i < bp->bsize) {
|
||||||
j = read(bp->fid, ip, bp->bsize-i);
|
j = bp->iof(bp, ip, bp->bsize-i);
|
||||||
if(j < 0)
|
if(j < 0)
|
||||||
Berror(bp, "read error: %r");
|
Berror(bp, "read error: %r");
|
||||||
if(j <= 0) {
|
if(j <= 0) {
|
||||||
|
|
|
@ -69,7 +69,7 @@ Brdstr(Biobufhdr *bp, int delim, int nulldelim)
|
||||||
for(;;){
|
for(;;){
|
||||||
ip = (char*)bp->bbuf + i;
|
ip = (char*)bp->bbuf + i;
|
||||||
while(i < bp->bsize) {
|
while(i < bp->bsize) {
|
||||||
j = read(bp->fid, ip, bp->bsize-i);
|
j = bp->iof(bp, ip, bp->bsize-i);
|
||||||
if(j < 0)
|
if(j < 0)
|
||||||
Berror(bp, "read error: %r");
|
Berror(bp, "read error: %r");
|
||||||
if(j <= 0 && i == 0)
|
if(j <= 0 && i == 0)
|
||||||
|
|
|
@ -20,7 +20,7 @@ Bread(Biobufhdr *bp, void *ap, long count)
|
||||||
if(n == 0) {
|
if(n == 0) {
|
||||||
if(bp->state != Bractive)
|
if(bp->state != Bractive)
|
||||||
break;
|
break;
|
||||||
i = read(bp->fid, bp->bbuf, bp->bsize);
|
i = bp->iof(bp, bp->bbuf, bp->bsize);
|
||||||
if(i <= 0) {
|
if(i <= 0) {
|
||||||
bp->state = Bracteof;
|
bp->state = Bracteof;
|
||||||
if(i < 0) {
|
if(i < 0) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ Bwrite(Biobufhdr *bp, void *ap, long count)
|
||||||
if(n == 0) {
|
if(n == 0) {
|
||||||
if(bp->state != Bwactive)
|
if(bp->state != Bwactive)
|
||||||
return Beof;
|
return Beof;
|
||||||
i = write(bp->fid, bp->bbuf, bp->bsize);
|
i = bp->iof(bp, bp->bbuf, bp->bsize);
|
||||||
if(i != bp->bsize) {
|
if(i != bp->bsize) {
|
||||||
errstr(errbuf, sizeof errbuf);
|
errstr(errbuf, sizeof errbuf);
|
||||||
if(strstr(errbuf, "interrupt") == nil) {
|
if(strstr(errbuf, "interrupt") == nil) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue