diff --git a/sys/include/bio.h b/sys/include/bio.h index 776f7b0f5..157e525c4 100644 --- a/sys/include/bio.h +++ b/sys/include/bio.h @@ -59,6 +59,7 @@ int Binits(Biobufhdr*, int, int, uchar*, int); int Blinelen(Biobufhdr*); vlong Boffset(Biobufhdr*); Biobuf* Bopen(char*, int); +Biobuf* Bfdopen(int, int); int Bprint(Biobufhdr*, char*, ...); int Bvprint(Biobufhdr*, char*, va_list); int Bputc(Biobufhdr*, int); diff --git a/sys/man/2/bio b/sys/man/2/bio index a059f1cf4..1aae56005 100644 --- a/sys/man/2/bio +++ b/sys/man/2/bio @@ -1,6 +1,6 @@ .TH BIO 2 .SH NAME -Bopen, Binit, Binits, Brdline, Brdstr, Bgetc, Bgetrune, Bgetd, Bungetc, Bungetrune, Bread, Bseek, Boffset, Bfildes, Blinelen, Bputc, Bputrune, Bprint, Bvprint, Bwrite, Bflush, Bterm, Bbuffered, Blethal \- buffered input/output +Bopen, Bfdopen, Binit, Binits, Brdline, Brdstr, Bgetc, Bgetrune, Bgetd, Bungetc, Bungetrune, Bread, Bseek, Boffset, Bfildes, Blinelen, Bputc, Bputrune, Bprint, Bvprint, Bwrite, Bflush, Bterm, Bbuffered, Blethal \- buffered input/output .SH SYNOPSIS .ta \w'Biobuf* 'u .B #include @@ -13,6 +13,9 @@ Bopen, Binit, Binits, Brdline, Brdstr, Bgetc, Bgetrune, Bgetd, Bungetc, Bungetru Biobuf* Bopen(char *file, int mode) .PP .B +Biobuf* Bfdopen(int fd, int mode) +.PP +.B int Binit(Biobuf *bp, int fd, int mode) .PP .B @@ -96,6 +99,17 @@ It calls .IR malloc (2) to allocate a buffer. .PP +.I Bfdopen +allocates a buffer for the already-open file descriptor +.I fd +for mode +.B OREAD +or +.BR OWRITE . +It calls +.IR malloc (2) +to allocate a buffer. +.PP .I Binit initializes a standard size buffer, type .IR Biobuf , diff --git a/sys/src/libbio/binit.c b/sys/src/libbio/binit.c index 36ed50ace..9afae5b34 100644 --- a/sys/src/libbio/binit.c +++ b/sys/src/libbio/binit.c @@ -53,7 +53,6 @@ install(Biobufhdr *bp) int Binits(Biobufhdr *bp, int f, int mode, uchar *p, int size) { - p += Bungetsize; /* make room for Bungets */ size -= Bungetsize; @@ -94,29 +93,48 @@ Binit(Biobuf *bp, int f, int mode) return Binits(bp, f, mode, bp->b, sizeof(bp->b)); } +Biobuf* +Bfdopen(int fd, int mode) +{ + Biobuf *bp; + + bp = malloc(sizeof(Biobuf)); + if(bp == nil) + return nil; + if(Binits(bp, fd, mode, bp->b, sizeof(bp->b)) != 0){ + free(bp); + return nil; + } + bp->flag = Bmagic; /* mark bp open & malloced */ + setmalloctag(bp, getcallerpc(&fd)); + return bp; +} + Biobuf* Bopen(char *name, int mode) { Biobuf *bp; - int f; + int fd; switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) { default: fprint(2, "Bopen: unknown mode %#x\n", mode); - return 0; + return nil; case OREAD: - f = open(name, mode); + fd = open(name, mode); break; case OWRITE: - f = create(name, mode, 0666); + fd = create(name, mode, 0666); break; } - if(f < 0) - return 0; - bp = malloc(sizeof(Biobuf)); + if(fd < 0) + return nil; + bp = Bfdopen(fd, mode); + if(bp == nil){ + close(fd); + return nil; + } setmalloctag(bp, getcallerpc(&name)); - Binits(bp, f, mode, bp->b, sizeof(bp->b)); - bp->flag = Bmagic; /* mark bp open & malloced */ return bp; }