ref: 13cf1422a66f525c4fe665f5958222908d1384cb
parent: 975997635c4f2f1a4f503680a9cb05e25b462872
author: 9ferno <[email protected]>
date: Tue Feb 8 08:14:38 EST 2022
compiling buffered input reader
--- a/os/pc64/forth.h
+++ b/os/pc64/forth.h
@@ -2168,7 +2168,7 @@
{.type FromH0, {.p M_sysclose}, .src = "dd M_sysclose"}, /* dd M_sysclose 17688 */
{.type FromH0, {.p C_0eq}, .src = "dd C_0eq"}, /* dd C_0eq 17696 */
{.type FromH0, {.p M_exitcolon}, .src = "dd M_exitcolon"}, /* dd M_exitcolon 17704 */
- {.type Header, {.hdr { 9, "read-file", /* C_read_file = 17728 */ colon }}}, /* CENTRY "read-file" read_file 9 ; ( a n fd -- n2 ioresult ) h 17736 */
+ {.type Header, {.hdr { 9, "read-file", /* C_read_file = 17728 */ colon }}}, /* CENTRY "read-file" read_file 9 ; ( 'text count fd -- count2 ioresult ) h 17736 */
{.type FromH0, {.p C_rot}, .src = "dd C_rot ; ( n fd a )"}, /* dd C_rot ; ( n fd a ) 17744 */
{.type FromH0, {.p C_rot}, .src = "dd C_rot ; ( fd a n )"}, /* dd C_rot ; ( fd a n ) 17752 */
{.type FromH0, {.p M_sysread}, .src = "dd M_sysread"}, /* dd M_sysread 17760 */
@@ -2177,7 +2177,7 @@
{.type Absolute, {.p -1}}, /* dd -1 17784 */
{.type FromH0, {.p C_neq}, .src = "dd C_neq"}, /* dd C_neq 17792 */
{.type FromH0, {.p M_exitcolon}, .src = "dd M_exitcolon"}, /* dd M_exitcolon 17800 */
- {.type Header, {.hdr { 10, "write-file", /* C_write_file = 17824 */ colon }}}, /* CENTRY "write-file" write_file 10 ; ( a n fd -- ioresult ) h 17832 */
+ {.type Header, {.hdr { 10, "write-file", /* C_write_file = 17824 */ colon }}}, /* CENTRY "write-file" write_file 10 ; ( 'text count fd -- ioresult ) h 17832 */
{.type FromH0, {.p C_rot}, .src = "dd C_rot ; ( n fd a )"}, /* dd C_rot ; ( n fd a ) 17840 */
{.type FromH0, {.p C_rot}, .src = "dd C_rot ; ( fd a n )"}, /* dd C_rot ; ( fd a n ) 17848 */
{.type FromH0, {.p M_syswrite}, .src = "dd M_syswrite"}, /* dd M_syswrite 17856 */
--- a/os/pc64/words-nasm.s
+++ b/os/pc64/words-nasm.s
@@ -1789,7 +1789,7 @@
dd M_sysclose
dd C_0eq
dd M_exitcolon
-CENTRY "read-file" C_read_file 9 ; ( a n fd -- n2 ioresult )
+CENTRY "read-file" C_read_file 9 ; ( 'text count fd -- count2 ioresult )
dd C_rot ; ( n fd a )
dd C_rot ; ( fd a n )
dd M_sysread
@@ -1798,7 +1798,7 @@
dd -1
dd C_neq
dd M_exitcolon
-CENTRY "write-file" C_write_file 10 ; ( a n fd -- ioresult )
+CENTRY "write-file" C_write_file 10 ; ( 'text count fd -- ioresult )
dd C_rot ; ( n fd a )
dd C_rot ; ( fd a n )
dd M_syswrite
--- a/os/port/devbin.c
+++ b/os/port/devbin.c
@@ -9,6 +9,10 @@
#define SOURCEFD(q) ((q).vers)
/*
+ An fd created here might be used by different processes at the same time
+ if the processes are sharing the Fgrp. Hence, the need for locks.
+ */
+/*
len is the space available in the reader's buffer
For now, assuming that the delimiter is 1 char.
*/
@@ -17,7 +21,7 @@
{
u32 qidpath;
char name[KNAMELEN];
- u8 *(*searchfn)(u8 *startp, u8 *endp, u32 len); /* function pointer that returns the number of bytes to send */
+ u8 *(*endfn)(u8 *startp, u8 *endp); /* function pointer that returns the number of bytes to send */
};
QLock lexlock;
@@ -29,6 +33,7 @@
u32 sourcefd;
Chan *sourcechan; /* for reading more data, instead of using fd2chan() for each read() */
u8 *buf, *readp, *writep;
+ s8 eof;
u32 bufsize;
u64 off;
};
@@ -48,20 +53,23 @@
Qline,
Qdoublequote,
Qcloseparen,
+ Qbuffer,
};
-static u8 *findword(u8 *startp, u8 *endp, u32 len);
-static u8 *findnewline(u8 *startp, u8 *endp, u32 len);
-static u8 *finddoublequote(u8 *startp, u8 *endp, u32 len);
-static u8 *findcloseparen(u8 *startp, u8 *endp, u32 len);
+static u8 *endofword(u8 *startp, u8 *endp);
+static u8 *endofnewline(u8 *startp, u8 *endp);
+static u8 *endofdoublequote(u8 *startp, u8 *endp);
+static u8 *endofcloseparen(u8 *startp, u8 *endp);
+static u8 *readuntil(u8 *startp, u8 *endp);
u16 bintype = 0;
Searcher searchers[] =
{
- Qword, "word", findword,
- Qline, "line", findnewline,
- Qdoublequote, "doublequote", finddoublequote,
- Qcloseparen, "closeparen", findcloseparen,
+ Qword, "word", endofword,
+ Qline, "line", endofnewline,
+ Qdoublequote, "doublequote", endofdoublequote,
+ Qcloseparen, "closeparen", endofcloseparen,
+ Qbuffer, "buffer", readuntil, /* to read contents without a delimiter, such as the last non-delimited content */
};
/*
@@ -86,10 +94,10 @@
Searcher *l;
/*
- * if I do .. from #o or #o/0
+ * if I do .. from #n or #n/0
*/
if(i == DEVDOTDOT){
- devdir(c, c->qid, "#o", 0, eve, 0555, dp);
+ devdir(c, c->qid, "#n", 0, eve, 0555, dp);
return 1;
}
if(SEARCHER(c->qid) == Qtopdir){
@@ -129,10 +137,12 @@
{
Walkqid *wq;
+print("binwalk chanpath(c) %s chanpath %s nname %d\n", chanpath(c), chanpath(nc), nname);
wq = devwalk(c, nc, name, nname, nil, 0, bingen);
if(wq != nil && wq->clone != nil && wq->clone != c){
wq->clone->aux = nil;
}
+print("binwalk chanpath(wq->clone) %s\n", chanpath(wq->clone));
return wq;
}
@@ -225,25 +235,58 @@
Bin *bin;
Binreader *l;
+print("binclose: c->path %s\n", chanpath(c));
l = c->aux;
- bin = l->bin;
- qlock(bin);
- decref(bin);
- if(bin->ref == 0){
- free(bin->buf);
- free(bin);
- }else
- qunlock(bin);
+ if(l != nil){
+ bin = l->bin;
+ if(bin != nil){
+ qlock(bin);
+ decref(bin);
+ if(bin->ref == 0){
+ free(bin->buf);
+ free(bin);
+ }else
+ qunlock(bin);
+ }
+ }
}
+s32
+refill(Bin *bin)
+{
+ s32 nr, n;
+
+ if(bin->eof == 1)
+ return 0;
+ if(bin->writep == nil)
+ bin->writep = bin->buf;
+ if(bin->readp == nil)
+ bin->readp = bin->buf;
+
+ if(bin->readp > bin->buf){
+ n = bin->writep-bin->readp;
+ memmove(bin->buf, bin->readp, n);
+ bin->writep -= n;
+ bin->readp = bin->buf;
+ }
+
+ nr = devtab[bin->sourcechan->type]->read(bin->sourcechan, bin->writep,
+ bin->bufsize-(bin->writep-bin->readp),
+ bin->sourcechan->offset);
+ if(nr == 0)
+ bin->eof = 1;
+
+ bin->writep += nr;
+ return nr;
+}
+
static s32
binread(Chan *c, void *va, s32 n, s64)
{
Bin *bin;
Searcher *s;
- u32 nr;
- u8 *p;
- u32 rv;
+ u8 *p, *ep, *nextreadp;
+ u32 rv, nremaining;
if(c->qid.type == QTDIR){
return devdirread(c, va, n, nil, 0, bingen);
@@ -254,41 +297,55 @@
if(bin->buf == nil)
panic("should no be happening");
+ /* do not allow arbitrarily high read buffer sizes */
+ if(n > bin->bufsize)
+ error(Ebadarg);
+
qlock(bin);
+ if(s->qidpath == Qbuffer && bin->eof == 1){
+ nremaining = bin->writep-bin->readp;
+ if(nremaining == 0)
+ rv = 0;
+ else if(nremaining > 0){
+ rv = nremaining > n ? n : nremaining;
+ memmove(va, bin->readp, n);
+ bin->readp += rv;
+ }
+ goto Exit;
+ }
if(bin->readp == bin->writep){
- nr = devtab[bin->sourcechan->type]->read(bin->sourcechan, bin->buf,
- bin->bufsize,
- bin->sourcechan->offset);
- bin->readp = bin->buf;
- bin->writep = bin->buf+nr;
+ if(bin->eof == 1){ /* nothing more to read */
+ rv = 0;
+ goto Exit;
+ }else
+ refill(bin);
}
Search: /* doing this while holding a lock, not sure if it is smart */
- p = s->searchfn(bin->readp, bin->writep, n);
- if(p > bin->readp){
- /* p+1 to skip the delimiter */
- rv = p+1-bin->readp;
- memmove(va, bin->readp, rv);
- bin->readp = p+1;
- }else{
- /* there is no delimiter between readp and writep */
- if(bin->writep -bin->readp > n){
- /* if there is no delimiter in the read buffer size, just send that much out */
+ if(bin->writep-bin->readp > n)
+ ep = bin->readp+n;
+ else
+ ep = bin->writep;
+ nextreadp = s->endfn(bin->readp, ep);
+ if(nextreadp == nil){
+ if(bin->writep-bin->readp > n){
+ /* delimiter not found, send n bytes */
memmove(va, bin->readp, n);
bin->readp += n;
rv = n;
+ goto Exit;
}else{
- /* move the contents to the start of the buffer and read more */
- memmove(bin->buf, bin->readp, bin->writep-bin->readp);
- bin->writep -= bin->readp-bin->buf;
- bin->readp = bin->buf;
- nr = devtab[bin->sourcechan->type]->read(bin->sourcechan, bin->writep,
- bin->bufsize-(bin->writep-bin->buf),
- bin->sourcechan->offset);
- bin->writep += nr;
+ refill(bin);
goto Search;
- }
+ }
+ }else{
+ /* delimiter found within n bytes */
+ rv = nextreadp-bin->readp;
+ memmove(va, bin->readp, rv);
+ bin->readp = nextreadp;
+ goto Exit;
}
+Exit:
qunlock(bin);
return rv;
}
@@ -327,67 +384,58 @@
devwstat,
};
+/* to read contents without a delimiter, such as the last non-delimited content */
static u8 *
-findword(u8 *startp, u8 *endp, u32 len)
+readuntil(u8 *startp, u8 *endp)
{
- u8 *p, *ep;
+ return endp;
+}
- if(endp - startp > len)
- ep = startp+len;
- else
- ep = endp;
- for(p = startp; p<ep; p++){
+static u8 *
+endofword(u8 *startp, u8 *endp)
+{
+ u8 *p;
+
+ for(p = startp; p<endp; p++){
if(*p == ' ' || *p == ' ' || *p == '\n')
- break;
+ return p+1;
}
- return p;
+ return nil;
}
static u8 *
-findnewline(u8 *startp, u8 *endp, u32 len)
+endofnewline(u8 *startp, u8 *endp)
{
- u8 *p, *ep;
+ u8 *p;
- if(endp - startp > len)
- ep = startp+len;
- else
- ep = endp;
- for(p = startp; p<ep; p++){
+ for(p = startp; p<endp; p++){
if(*p == '\n')
- break;
+ return p+1;
}
- return p;
+ return nil;
}
static u8 *
-finddoublequote(u8 *startp, u8 *endp, u32 len)
+endofdoublequote(u8 *startp, u8 *endp)
{
- u8 *p, *ep;
+ u8 *p;
- if(endp - startp > len)
- ep = startp+len;
- else
- ep = endp;
- for(p = startp; p<ep; p++){
+ for(p = startp; p<endp; p++){
if(*p == 0x22) /* " = 0x22 = 34 */
- break;
+ return p+1;
}
- return p;
+ return nil;
}
static u8 *
-findcloseparen(u8 *startp, u8 *endp, u32 len)
+endofcloseparen(u8 *startp, u8 *endp)
{
- u8 *p, *ep;
+ u8 *p;
- if(endp - startp > len)
- ep = startp+len;
- else
- ep = endp;
- for(p = startp; p<ep; p++){
+ for(p = startp; p<endp; p++){
if(*p == 0x29) /* ) = 0x29 = 41 */
- break;
+ return p+1;
}
- return p;
+ return nil;
}
--- a/os/port/devproc.c
+++ b/os/port/devproc.c
@@ -175,7 +175,7 @@
if(s == DEVDOTDOT){
mkqid(&qid, Qdir, 0, QTDIR);
- devdir(c, qid, "#o", 0, eve, 0555, dp);
+ devdir(c, qid, "#p", 0, eve, 0555, dp);
return 1;
}