diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-03-01 05:45:22 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-03-01 05:45:22 +0100 |
commit | 0467b41972b62604c8a22b355569413890b9757c (patch) | |
tree | 5609464ed1653325495e53b612837f18d68a8b73 /sys/src/libdraw | |
parent | e725771b5d8a78fd8ade6062925894cfe3f1d4d1 (diff) |
libdraw: use multiple read() calls in openfont() to read .font file
font files might be bigger than the i/o unit, so do multiple reads
until eof to read it.
Diffstat (limited to 'sys/src/libdraw')
-rw-r--r-- | sys/src/libdraw/openfont.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/sys/src/libdraw/openfont.c b/sys/src/libdraw/openfont.c index 3d9fa3ee1..bc9a43831 100644 --- a/sys/src/libdraw/openfont.c +++ b/sys/src/libdraw/openfont.c @@ -2,36 +2,43 @@ #include <libc.h> #include <draw.h> +static char* +readfile(char *name) +{ + enum { HUNK = 8*1024, }; + int f, n, r; + char *s, *p; + + n = 0; + r = -1; + if((s = malloc(HUNK)) != nil){ + if((f = open(name, OREAD)) >= 0){ + while((r = read(f, s+n, HUNK)) > 0){ + n += r; + r = -1; + if((p = realloc(s, n+HUNK)) == nil) + break; + s = p; + } + close(f); + } + } + if(r < 0 || (p = realloc(s, n+1)) == nil){ + free(s); + return nil; + } + p[n] = 0; + return p; +} + Font* openfont(Display *d, char *name) { Font *fnt; - int fd, i, n; char *buf; - Dir *dir; - - fd = open(name, OREAD); - if(fd < 0) - return 0; - dir = dirfstat(fd); - if(dir == nil){ - Err0: - close(fd); - return 0; - } - n = dir->length; - free(dir); - buf = malloc(n+1); - if(buf == 0) - goto Err0; - buf[n] = 0; - i = read(fd, buf, n); - close(fd); - if(i != n){ - free(buf); - return 0; - } + if((buf = readfile(name)) == nil) + return nil; fnt = buildfont(d, buf, name); free(buf); return fnt; |