This patch supersedes my acme-fontnames patch. It: • Establishes the invariant that fontnames[i] is either nil or allocated with malloc. The current code sometimes does free(static_string) as described in the acme-fontnames patch. That patch leaked memory. This patch should not. • With the old code for rfget, it seems possible that fontnames[fix] could get set to a pointer that had been freed. For example, calling rfget with save true and name nil would do something like "name = fontnames[fix]; ⋯; free(fontnames[fix]); fontnames[fix] = name;". I do not know if this ever happened in practice, but this patch avoids the possibility. • Establishes the convention for rfget that the caller owns rfget's name parameter; in particular, rfget now does estrdup(name) when appropriate and the use of rfget around /sys/src/cmd/acme/rows.c:518 no longer does estrdup. Note that the other uses of rfget are compatible with this convention and if you decide the other convention is better (ie, that rfget should own name and callers should do estrdup), then you need to change the use of rfget around /sys/src/cmd/acme/exec.c:965 to not free(aa). • Changes rfget to erealloc (rather than realloc) fontcache. Reference: /n/sources/patch/applied/acme-fontnames2 Date: Mon Dec 20 18:57:27 CET 2004 --- /sys/src/cmd/acme/acme.c Mon Dec 20 18:57:27 2004 +++ /sys/src/cmd/acme/acme.c Mon Dec 20 18:57:26 2004 @@ -35,11 +35,7 @@ }; Rune snarfrune[NSnarf+1]; -char *fontnames[2] = -{ - "/lib/font/bit/lucidasans/euro.8.font", - "/lib/font/bit/lucm/unicode.9.font", -}; +char *fontnames[2]; Command *command; @@ -69,6 +65,8 @@ ncol = -1; loadfile = nil; + fontnames[0] = estrdup("/lib/font/bit/lucidasans/euro.8.font"); + fontnames[1] = estrdup("/lib/font/bit/lucm/unicode.9.font"); ARGBEGIN{ case 'a': globalautoindent = TRUE; @@ -85,14 +83,18 @@ goto Usage; break; case 'f': - fontnames[0] = ARGF(); - if(fontnames[0] == nil) + p = ARGF(); + if(p == nil) goto Usage; + free(fontnames[0]); + fontnames[0] = estrdup(p); break; case 'F': - fontnames[1] = ARGF(); - if(fontnames[1] == nil) + p = ARGF(); + if(p == nil) goto Usage; + free(fontnames[1]); + fontnames[1] = estrdup(p); break; case 'l': loadfile = ARGF(); @@ -789,7 +791,7 @@ } r = emalloc(sizeof(Reffont)); r->f = f; - fontcache = realloc(fontcache, (nfontcache+1)*sizeof(Reffont*)); + fontcache = erealloc(fontcache, (nfontcache+1)*sizeof(Reffont*)); fontcache[nfontcache++] = r; } Found: @@ -798,8 +800,10 @@ if(reffonts[fix]) rfclose(reffonts[fix]); reffonts[fix] = r; - free(fontnames[fix]); - fontnames[fix] = name; + if(name != fontnames[fix]){ + free(fontnames[fix]); + fontnames[fix] = estrdup(name); + } } if(setfont){ reffont.f = r->f; --- /sys/src/cmd/acme/rows.c Mon Dec 20 18:57:27 2004 +++ /sys/src/cmd/acme/rows.c Mon Dec 20 18:57:27 2004 @@ -465,8 +465,10 @@ if(l == nil) goto Return; l[Blinelen(b)-1] = 0; - if(*l && strcmp(l, fontnames[i])!=0) + if(*l && strcmp(l, fontnames[i])!=0){ + free(fontnames[i]); fontnames[i] = estrdup(l); + } } Return: Bterm(b); @@ -515,7 +517,7 @@ goto Rescue2; l[Blinelen(b)-1] = 0; if(*l && strcmp(l, fontnames[i])!=0) - rfget(i, TRUE, i==0 && initing, estrdup(l)); + rfget(i, TRUE, i==0 && initing, l); } if(initing && row->ncol==0) rowinit(row, screen->clipr);