|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <draw.h> | 
|  |  | 
|  | extern vlong _drawflength(int); | 
|  | int _fontpipe(char*); | 
|  |  | 
|  | Font* | 
|  | openfont(Display *d, char *name) | 
|  | { | 
|  | Font *fnt; | 
|  | int fd, i, n; | 
|  | char *buf, *nambuf; | 
|  |  | 
|  | nambuf = 0; | 
|  | fd = open(name, OREAD); | 
|  |  | 
|  | if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){ | 
|  | nambuf = smprint("#9/font/%s", name+14); | 
|  | if(nambuf == nil) | 
|  | return 0; | 
|  | nambuf = unsharp(nambuf); | 
|  | if(nambuf == nil) | 
|  | return 0; | 
|  | if((fd = open(nambuf, OREAD)) < 0){ | 
|  | free(nambuf); | 
|  | return 0; | 
|  | } | 
|  | name = nambuf; | 
|  | } | 
|  | if(fd >= 0) | 
|  | n = _drawflength(fd); | 
|  | if(fd < 0 && strncmp(name, "/mnt/font/", 10) == 0) { | 
|  | fd = _fontpipe(name+10); | 
|  | n = 8192; | 
|  | } | 
|  | if(fd < 0) | 
|  | return 0; | 
|  |  | 
|  | buf = malloc(n+1); | 
|  | if(buf == 0){ | 
|  | close(fd); | 
|  | free(nambuf); | 
|  | return 0; | 
|  | } | 
|  | i = readn(fd, buf, n); | 
|  | close(fd); | 
|  | if(i <= 0){ | 
|  | free(buf); | 
|  | free(nambuf); | 
|  | return 0; | 
|  | } | 
|  | buf[i] = 0; | 
|  | fnt = buildfont(d, buf, name); | 
|  | free(buf); | 
|  | free(nambuf); | 
|  | return fnt; | 
|  | } | 
|  |  | 
|  | int | 
|  | _fontpipe(char *name) | 
|  | { | 
|  | int p[2]; | 
|  | char c; | 
|  | char buf[1024], *argv[10]; | 
|  | int nbuf, pid; | 
|  |  | 
|  | if(pipe(p) < 0) | 
|  | return -1; | 
|  | pid = rfork(RFNOWAIT|RFFDG|RFPROC); | 
|  | if(pid < 0) { | 
|  | close(p[0]); | 
|  | close(p[1]); | 
|  | return -1; | 
|  | } | 
|  | if(pid == 0) { | 
|  | close(p[0]); | 
|  | dup(p[1], 1); | 
|  | dup(p[1], 2); | 
|  | if(p[1] > 2) | 
|  | close(p[1]); | 
|  | argv[0] = "fontsrv"; | 
|  | argv[1] = "-pp"; | 
|  | argv[2] = name; | 
|  | argv[3] = nil; | 
|  | execvp("fontsrv", argv); | 
|  | print("exec fontsrv: %r\n"); | 
|  | _exit(0); | 
|  | } | 
|  | close(p[1]); | 
|  |  | 
|  | // success marked with leading \001. | 
|  | // otherwise an error happened. | 
|  | for(nbuf=0; nbuf<sizeof buf-1; nbuf++) { | 
|  | if(read(p[0], &c, 1) < 1 || c == '\n') { | 
|  | buf[nbuf] = '\0'; | 
|  | werrstr(buf); | 
|  | close(p[0]); | 
|  | return -1; | 
|  | } | 
|  | if(c == '\001') | 
|  | break; | 
|  | } | 
|  | return p[0]; | 
|  | } |