add memory fixes from upstream: fixes crashes from plumbing
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmDGbY8ACgkQO3+8IhRO Y5iREw//QCPW5UVlSVp3jChxlYCvlmag3BLfYsvRBfL0ZJhZPtEc4OFlIq9pr3U4 glRX+BhwPmY4f3vFXJBS85YbIiCdBGEKE/lQDx3GMIVKYrXTqGHKQxlqDea5GD6d w9f3Cbn66PwUn4oZi0s94imwDA3NTxgdHZU/UbNxsiaxSiqKilIWZFPJ/dZph2K5 Tnfl6dAU/kqbfSzI5ZdxCkFQtXCPy+Tyi3rZ+0PJfeka03uhDHpVup7BGc9dhCx6 gImXmzgEanB2QXo01L3/W/J1zdZytKa2mz+cXV1SGAEor35qwSBq5lLgcuLvx5Bj SVw0sZcPhV7SYervFcqYZFVUo+QjsQN4i7M1z4Oys9Xa7O9I5N/ONYLsTOo3VqMK 9vW1T+hYgKyFw72hQK7ypf8eXbCIEwdKL4Ck71fwZ+aEqjB6S4gvqd5QduulvXlj VVmMjjQhbYOB3VEDAa5XRGLIOHCabQ2HHl6QTspbGd+mYH1/EiTy/mNqswFvWgFH u+ucAQTVYdvbuQo24/mlCt5hg9eQoRL5GSeQVKjicOBT/YW4/mc627kMPdko/cgp IM3ejr8wa/LoQEznBW5uaDhMYsOk5Rk7mFbHWuIkSXWEGvjOXxIBKj2DvBqaeu3z 5FHQEwAr4eWy40Na1aYNCyBpuzR3pO5gH2I+ONf1bLEMRhWUvYQ= =w0Qd -----END PGP SIGNATURE-----
M
acme.c
→
acme.c
@@ -368,7 +368,7 @@ static int errorfd;
int erroutfd; void acmeerrorproc(void* v) { - char *buf, *s; + char* buf; int n; USED(v);@@ -376,9 +376,7 @@ threadsetname("acmeerrorproc");
buf = emalloc(8192 + 1); while ((n = read(errorfd, buf, 8192)) >= 0) { buf[n] = '\0'; - s = estrdup(buf); - sendp(cerr, s); - free(s); + sendp(cerr, estrdup(buf)); } free(buf); }
M
ecmd.c
→
ecmd.c
@@ -28,7 +28,7 @@ int append(File*, Cmd*, long);
int pdisplay(File*); void pfilename(File*); void looper(File*, Cmd*, int); -void filelooper(Cmd*, int); +void filelooper(Text*, Cmd*, int); void linelooper(File*, Cmd*); Address lineaddr(long, Address, int); int filematch(File*, String*);@@ -529,7 +529,7 @@
int X_cmd(Text* t, Cmd* cp) { USED(t); - filelooper(cp, cp->cmdc == 'X'); + filelooper(t, cp, cp->cmdc == 'X'); return TRUE; }@@ -902,8 +902,9 @@ else
winclose(w); } -void filelooper(Cmd* cp, int XY) { +void filelooper(Text* t, Cmd* cp, int XY) { int i; + Text* targ; if (Glooping++) editerror("can't nest %c command", "YX"[XY]);@@ -924,8 +925,25 @@ * newly created windows start with an extra reference.
*/ allwindows(alllocker, (void*)1); globalincref = 1; - for (i = 0; i < loopstruct.nw; i++) - cmdexec(&loopstruct.w[i]->body, cp->u.cmd); + + /* + * Unlock the window running the X command. + * We'll need to lock and unlock each target window in turn. + */ + if (t && t->w) + winunlock(t->w); + + for (i = 0; i < loopstruct.nw; i++) { + targ = &loopstruct.w[i]->body; + if (targ && targ->w) + winlock(targ->w, cp->cmdc); + cmdexec(targ, cp->u.cmd); + if (targ && targ->w) + winunlock(targ->w); + } + + if (t && t->w) + winlock(t->w, cp->cmdc); allwindows(alllocker, (void*)0); globalincref = 0; free(loopstruct.w);
M
wind.c
→
wind.c
@@ -106,18 +106,15 @@ draw(screen, br, b, nil, b->r.min);
} int delrunepos(Window* w) { - int n; - Rune rune; + Rune* r; + int i; - for (n = 0; n < w->tag.file->b.nc; n++) { - bufread(&w->tag.file->b, n, &rune, 1); - if (rune == ' ') - break; - } - n += 2; - if (n >= w->tag.file->b.nc) + r = parsetag(w, 0, &i); + free(r); + i += 2; + if (i >= w->tag.file->b.nc) return -1; - return n; + return i; } void movetodel(Window* w) {@@ -390,7 +387,7 @@ Rune* r;
/* w must be committed */ n = w->tag.file->b.nc; - r = parsetag(w, &i); + r = parsetag(w, 0, &i); for (; i < n; i++) if (r[i] == '|') break;@@ -407,15 +404,15 @@ w->tag.q1 = i;
textsetselect(&w->tag, w->tag.q0, w->tag.q1); } -Rune* parsetag(Window* w, int* len) { +Rune* parsetag(Window* w, int extra, int* len) { static Rune Ldelsnarf[] = {' ', 'D', 'e', 'l', ' ', 'S', 'n', 'a', 'r', 'f', 0}; static Rune Lspacepipe[] = {' ', '|', 0}; - static Rune Ltabpipe[] = {' ', '|', 0}; + static Rune Ltabpipe[] = {'\t', '|', 0}; int i; Rune *r, *p, *pipe; - r = runemalloc(w->tag.file->b.nc + 1); + r = runemalloc(w->tag.file->b.nc + extra + 1); bufread(&w->tag.file->b, 0, r, w->tag.file->b.nc); r[w->tag.file->b.nc] = '\0';@@ -460,7 +457,7 @@ * extra care to sync it */
if (w->tag.ncache != 0 || w->tag.file->mod) wincommit(w, &w->tag); /* check file name; also guarantees we can modify tag contents */ - old = parsetag(w, &i); + old = parsetag(w, 0, &i); if (runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE) { textdelete(&w->tag, 0, i, TRUE); textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, TRUE);@@ -473,7 +470,8 @@
/* compute the text for the whole tag, replacing current only if it differs */ new = runemalloc(w->body.file->nname + 100); i = 0; - runemove(new + i, w->body.file->name, w->body.file->nname); + if (w->body.file->nname != 0) + runemove(new, w->body.file->name, w->body.file->nname); i += w->body.file->nname; runemove(new + i, Ldelsnarf, 10); i += 10;@@ -577,7 +575,7 @@ for (i = 0; i < f->ntext; i++)
textcommit(f->text[i], FALSE); /* no-op for t */ if (t->what == Body) return; - r = parsetag(w, &i); + r = parsetag(w, 0, &i); if (runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE) { seq++; filemark(w->body.file);