ref: f681cf835af1e5c9e016e5245c24165b029a5e38
parent: 414d29e98f8d5242cc68161e61b66b7171e96634
author: aiju <devnull@localhost>
date: Thu May 4 13:42:12 EDT 2017
bio: add support for custom I/O handler via Biofn
--- a/sys/include/bio.h
+++ b/sys/include/bio.h
@@ -33,6 +33,7 @@
uchar* ebuf; /* pointer to end of buffer */
uchar* gbuf; /* pointer to good data in buf */
void (*errorf)(char *); /* called on error if not nil */
+ int (*iof)(Biobufhdr*, void *, long); /* called to do i/o */
};
struct Biobuf
@@ -74,6 +75,7 @@
long Bwrite(Biobufhdr*, void*, long);
void Blethal(Biobufhdr*, void(*)(char*));
void Berror(Biobufhdr*, char*, ...);
+void Biofn(Biobufhdr*, int(*)(Biobufhdr*, void*, long));
#pragma varargck argpos Bprint 2
#pragma varargck argpos Berror 2
--- a/sys/man/2/bio
+++ b/sys/man/2/bio
@@ -84,6 +84,9 @@
.B
void Blethal(Biobufhdr *bp, void (*errorf)(char *))
.PP
+.B
+void Biofn(Biobufhdr *bp, int (*iof)(Biohdr *, void *, long))
+.PP
.SH DESCRIPTION
These routines implement fast buffered I/O.
I/O on different file descriptors is independent.
@@ -338,6 +341,18 @@
An argument of
.B nil
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
.B /sys/src/libbio
.SH SEE ALSO
--- a/sys/src/libbio/bflush.c
+++ b/sys/src/libbio/bflush.c
@@ -12,7 +12,7 @@
n = bp->bsize+bp->ocount;
if(n == 0)
return 0;
- c = write(bp->fid, bp->bbuf, n);
+ c = bp->iof(bp, bp->bbuf, n);
if(n == c) {
bp->offset += n;
bp->ocount = -bp->bsize;
--- a/sys/src/libbio/bgetc.c
+++ b/sys/src/libbio/bgetc.c
@@ -24,7 +24,7 @@
* buffer to allow that many ungets.
*/
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;
if(i <= 0) {
bp->state = Bracteof;
--- a/sys/src/libbio/binit.c
+++ b/sys/src/libbio/binit.c
@@ -50,6 +50,18 @@
}
}
+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
Binits(Biobufhdr *bp, int f, int mode, uchar *p, int size)
{
@@ -64,6 +76,7 @@
case OREAD:
bp->state = Bractive;
bp->ocount = 0;
+ bp->iof = bioread;
break;
case OWRITE:
@@ -70,6 +83,7 @@
install(bp);
bp->state = Bwactive;
bp->ocount = -size;
+ bp->iof = biowrite;
break;
}
bp->bbuf = p;
@@ -153,4 +167,16 @@
}
/* otherwise opened with Binit(s) */
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;
}
--- a/sys/src/libbio/brdline.c
+++ b/sys/src/libbio/brdline.c
@@ -46,7 +46,7 @@
*/
ip = (char*)bp->bbuf + i;
while(i < bp->bsize) {
- j = read(bp->fid, ip, bp->bsize-i);
+ j = bp->iof(bp, ip, bp->bsize-i);
if(j < 0)
Berror(bp, "read error: %r");
if(j <= 0) {
--- a/sys/src/libbio/brdstr.c
+++ b/sys/src/libbio/brdstr.c
@@ -69,7 +69,7 @@
for(;;){
ip = (char*)bp->bbuf + i;
while(i < bp->bsize) {
- j = read(bp->fid, ip, bp->bsize-i);
+ j = bp->iof(bp, ip, bp->bsize-i);
if(j < 0)
Berror(bp, "read error: %r");
if(j <= 0 && i == 0)
--- a/sys/src/libbio/bread.c
+++ b/sys/src/libbio/bread.c
@@ -20,7 +20,7 @@
if(n == 0) {
if(bp->state != Bractive)
break;
- i = read(bp->fid, bp->bbuf, bp->bsize);
+ i = bp->iof(bp, bp->bbuf, bp->bsize);
if(i <= 0) {
bp->state = Bracteof;
if(i < 0) {
--- a/sys/src/libbio/bwrite.c
+++ b/sys/src/libbio/bwrite.c
@@ -21,7 +21,7 @@
if(n == 0) {
if(bp->state != Bwactive)
return Beof;
- i = write(bp->fid, bp->bbuf, bp->bsize);
+ i = bp->iof(bp, bp->bbuf, bp->bsize);
if(i != bp->bsize) {
errstr(errbuf, sizeof errbuf);
if(strstr(errbuf, "interrupt") == nil) {