If the font chosen for acme is retrieved via `getenv("font")` its
memory is leaked:
<snip>
if(fontnames[0] == nil)
fontnames[0] = getenv("font");
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> getenv(…) mallocs memory
if(fontnames[0] == nil)
fontnames[0] = "/lib/font/bit/vga/unicode.font";
if(access(fontnames[0], 0) < 0){
fprint(2, "acme: can't access %s: %r\n", fontnames[0]);
exits("font open");
}
if(fontnames[1] == nil)
fontnames[1] = fontnames[0];
fontnames[0] = estrdup(fontnames[0]);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> if the `getenv("font")` path was taken above, this assignment
> will leak its memory.
</snap>
The following leak/acid session demonstrates the issue:
<snip>
cpu% leak -s 212252
src(0x002000cb); // 1
cpu% acid 212252
/proc/212252/text:amd64 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/amd64
acid: src(0x002000cb)
/sys/src/cmd/acme/acme.c:107
102 fprint(2, "usage: acme [-aib] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n");
103 exits("usage");
104 }ARGEND
105
106 if(fontnames[0] == nil)
>107 fontnames[0] = getenv("font");
108 if(fontnames[0] == nil)
109 fontnames[0] = "/lib/font/bit/vga/unicode.font";
110 if(access(fontnames[0], 0) < 0){
111 fprint(2, "acme: can't access %s: %r\n", fontnames[0]);
112 exits("font open");
acid:
</snap>
The fix tries to first check if a font has been set via
command line options in which case the font string is
malloced via estrdup(…).
If no font has been selected on the command line getenv("font")
is used. If no getenv("font") var is found we malloc a default
font via estrdup(…).
<snip>
if(fontnames[0] != nil)
fontnames[0] = estrdup(fontnames[0]);
else
if((fontnames[0] = getenv("font")) == nil)
fontnames[0] = estrdup("/lib/font/bit/vga/unicode.font");
if(access(fontnames[0], 0) < 0){
fprint(2, "acme: can't access %s: %r\n", fontnames[0]);
exits("font open");
}
if(fontnames[1] == nil)
fontnames[1] = fontnames[0];
fontnames[1] = estrdup(fontnames[1]);
</snap>
This resolves the memory leak reported by leak(1).