diff options
author | Russ Cox <rsc@swtch.com> | 2008-07-14 17:38:46 -0400 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2008-07-14 17:38:46 -0400 |
commit | c5f884244d35a2e571cdaec22ae345cc4e9f7900 (patch) | |
tree | c0cf29690a5f759056d96efb01cb04b4dae7996f /src/cmd/upas | |
parent | d35c1bb294f734a69813ecd305a0906025b7e9fa (diff) | |
download | plan9port-c5f884244d35a2e571cdaec22ae345cc4e9f7900.tar.gz plan9port-c5f884244d35a2e571cdaec22ae345cc4e9f7900.tar.bz2 plan9port-c5f884244d35a2e571cdaec22ae345cc4e9f7900.zip |
mailfs: correct use of tcs for large inputs
Diffstat (limited to 'src/cmd/upas')
-rw-r--r-- | src/cmd/upas/nfs/decode.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/cmd/upas/nfs/decode.c b/src/cmd/upas/nfs/decode.c index e653eeaa..aed01cf3 100644 --- a/src/cmd/upas/nfs/decode.c +++ b/src/cmd/upas/nfs/decode.c @@ -116,17 +116,37 @@ struct { "koi8-r", "koi8" }; +typedef struct Writeargs Writeargs; +struct Writeargs +{ + int fd; + char *s; +}; + +static void +twriter(void *v) +{ + Writeargs *w; + + w = v; + write(w->fd, w->s, strlen(w->s)); + close(w->fd); + free(w->s); + free(w); +} + char* tcs(char *charset, char *s) { - static char buf[4096]; - int i, n; + char *buf; + int i, n, nbuf; int fd[3], p[2], pp[2]; uchar *us; char *t, *u; char *argv[4]; Rune r; - + Writeargs *w; + if(s == nil || charset == nil || *s == 0) return s; @@ -173,15 +193,26 @@ tcs: } close(p[0]); close(pp[0]); - write(p[1], s, strlen(s)); - close(p[1]); - n = readn(pp[1], buf, sizeof buf-1); + + nbuf = UTFmax*strlen(s)+100; /* just a guess at worst case */ + buf = emalloc(nbuf); + + w = emalloc(sizeof *w); + w->fd = p[1]; + w->s = estrdup(s); + proccreate(twriter, w, STACK); + + n = readn(pp[1], buf, nbuf-1); close(pp[1]); - if(n <= 0) + if(n <= 0){ + free(buf); goto latin1; - free(s); + } buf[n] = 0; - return estrdup(buf); + free(s); + s = estrdup(buf); + free(buf); + return s; } char* |