Remove many valgrind-detected memory leaks. - sam - An updated version of the s… | |
git clone git://vernunftzentrum.de/sam.git | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit 3a8f45f007849613466d20ed16760917bdb2bf9d | |
parent 569a1de5d7884bad2b30e9a2b5280a941ed228cf | |
Author: Rob King <[email protected]> | |
Date: Thu, 20 Oct 2016 15:55:35 -0500 | |
Remove many valgrind-detected memory leaks. | |
Diffstat: | |
sam/buffer.c | 3 ++- | |
sam/cmd.c | 46 +++++++++++++++++++++++++------ | |
sam/error.c | 2 ++ | |
sam/file.c | 16 +++++++++++++++- | |
sam/mesg.c | 3 ++- | |
sam/multi.c | 3 ++- | |
sam/sam.c | 50 ++++++++++++++++++++++++++----- | |
sam/sam.h | 5 ++++- | |
sam/unix.c | 13 ++++--------- | |
9 files changed, 110 insertions(+), 31 deletions(-) | |
--- | |
diff --git a/sam/buffer.c b/sam/buffer.c | |
@@ -124,13 +124,14 @@ Bterm(Buffer *b) | |
} | |
} | |
+/* XXX - modify at call sites to use the internal functions */ | |
int | |
Bread(Buffer *b, wchar_t *c, int l, Posn p) | |
{ | |
if (p + l > b->nrunes) | |
l = b->nrunes - p; | |
- if (l == 0) | |
+ if (l <= 0) | |
return 0; | |
size_t r = readbuffer(b->gb, p, l, c); | |
diff --git a/sam/cmd.c b/sam/cmd.c | |
@@ -59,6 +59,22 @@ List stringlist; | |
bool eof; | |
void | |
+freecmdlists(void) | |
+{ | |
+ if (cmdlist.listptr) | |
+ free(cmdlist.listptr); | |
+ | |
+ if (addrlist.listptr) | |
+ free(addrlist.listptr); | |
+ | |
+ if (relist.listptr) | |
+ free(relist.listptr); | |
+ | |
+ if (stringlist.listptr) | |
+ free(stringlist.listptr); | |
+} | |
+ | |
+void | |
resetcmd(void) | |
{ | |
linep = line; | |
@@ -71,8 +87,8 @@ int | |
inputc(void) | |
{ | |
int n, nbuf; | |
- char buf[3]; | |
- wchar_t r; | |
+ char buf[3] = {0}; | |
+ wchar_t r = 0; | |
Again: | |
nbuf = 0; | |
@@ -203,7 +219,7 @@ cmdloop(void) | |
for(;;){ | |
if(!downloaded && curfile && curfile->state==Unread) | |
load(curfile); | |
- if((cmdp = parsecmd(0))==0){ | |
+ if((cmdp = parsecmd(0)) == NULL){ | |
if(downloaded){ | |
rescue(); | |
exit(EXIT_FAILURE); | |
@@ -212,8 +228,10 @@ cmdloop(void) | |
} | |
ocurfile = curfile; | |
loaded = curfile && curfile->state!=Unread; | |
- if(cmdexec(curfile, cmdp) == 0) | |
+ if(cmdexec(curfile, cmdp) == 0){ | |
+ freecmd(); | |
break; | |
+ } | |
freecmd(); | |
cmdupdate(); | |
update(); | |
@@ -274,8 +292,12 @@ freecmd(void) | |
{ | |
int i; | |
- while(cmdlist.nused > 0) | |
- free(cmdlist.uint8_tpptr[--cmdlist.nused]); | |
+ while(cmdlist.nused > 0){ | |
+ Cmd *c = (Cmd *)cmdlist.uint8_tpptr[--cmdlist.nused]; | |
+ /* XXX if (c->ctext) | |
+ free(c->ctext); */ | |
+ free(c); | |
+ } | |
while(addrlist.nused > 0) | |
free(addrlist.uint8_tpptr[--addrlist.nused]); | |
while(relist.nused > 0){ | |
@@ -426,6 +448,8 @@ parsecmd(int nest) | |
okdelim(c); | |
cmd.re = getregexp(c); | |
if(ct->cmdc == 's'){ | |
+ if (cmd.ctext) | |
+ free(cmd.ctext); | |
cmd.ctext = newstring(); | |
getrhs(cmd.ctext, c, 's'); | |
if(nextc() == c){ | |
@@ -446,11 +470,15 @@ parsecmd(int nest) | |
cmd.ccmd->cmdc = ct->defcmd; | |
}else if((cmd.ccmd = parsecmd(nest))==0) | |
panic("defcmd"); | |
- }else if(ct->text) | |
+ } else if(ct->text){ | |
+ if (cmd.ctext) | |
+ free(cmd.ctext); | |
cmd.ctext = collecttext(); | |
- else if(ct->token) | |
+ } else if(ct->token){ | |
+ if (cmd.ctext) | |
+ free(cmd.ctext); | |
cmd.ctext = collecttoken(ct->token); | |
- else | |
+ } else | |
atnl(); | |
}else | |
switch(cmd.cmdc){ | |
diff --git a/sam/error.c b/sam/error.c | |
@@ -128,6 +128,8 @@ termwrite(char *s) | |
else | |
Strinsert(&cmdstr, p, cmdstr.n); | |
cmdptadv += p->n; | |
+ Strclose(p); | |
+ free(p); | |
}else | |
Write(STDERR_FILENO, s, strlen(s)); | |
} | |
diff --git a/sam/file.c b/sam/file.c | |
@@ -1,5 +1,6 @@ | |
/* Copyright (c) 1998 Lucent Technologies - All rights reserved. */ | |
#include "sam.h" | |
+ | |
/* | |
* Files are splayed out a factor of NDISC to reduce indirect block access | |
*/ | |
@@ -19,12 +20,22 @@ enum{ | |
MAXCACHE=STRSIZE /* max length of cache. must be < 32K-BLOCKSIZE */ | |
}; | |
+static void | |
+freebufs(void) | |
+{ | |
+ Bterm(undobuf); | |
+ Bterm(snarfbuf); | |
+ Bterm(plan9buf); | |
+} | |
+ | |
void | |
Fstart(void) | |
{ | |
undobuf = Bopen(); | |
snarfbuf = Bopen(); | |
plan9buf = Bopen(); | |
+ | |
+ atexit(freebufs); | |
} | |
void | |
@@ -75,8 +86,11 @@ Fopen(void) | |
void | |
Fclose(File *f) | |
{ | |
+ if (!f) | |
+ return; | |
+ | |
if(f == lastfile) | |
- lastfile = 0; | |
+ lastfile = NULL; | |
Bterm(f->buf); | |
Bterm(f->transcript); | |
Strclose(&f->name); | |
diff --git a/sam/mesg.c b/sam/mesg.c | |
@@ -465,7 +465,7 @@ inmesg(Tmesg type) | |
Write(1, c, i); | |
free(c); | |
} else | |
- dprint("snarf buffer too int64_t\n"); | |
+ dprint("snarf buffer too long\n"); | |
break; | |
case Tsetsnarf: | |
@@ -491,6 +491,7 @@ inmesg(Tmesg type) | |
break; | |
case Texit: | |
+ shutdown(); | |
exit(EXIT_SUCCESS); | |
} | |
return true; | |
diff --git a/sam/multi.c b/sam/multi.c | |
@@ -95,7 +95,7 @@ lookfile(String *s, bool fuzzy) | |
if (fuzzy){ | |
char *ac = Strtoc(&file.filepptr[i]->name); | |
if (strcmp(basename(sc), ac) == 0) | |
- return free(ac), file.filepptr[i]; | |
+ return free(sc), free(ac), file.filepptr[i]; | |
if (!b && strstr(ac, sc)) | |
b = file.filepptr[i]; | |
@@ -103,5 +103,6 @@ lookfile(String *s, bool fuzzy) | |
} | |
} | |
+ free(sc); | |
return b; | |
} | |
diff --git a/sam/sam.c b/sam/sam.c | |
@@ -106,8 +106,9 @@ main(int argc, char *argv[]) | |
Strinit0(&genstr); | |
Strinit0(&rhs); | |
Strinit0(&wd); | |
- tempfile.listptr = emalloc(0); | |
Strinit0(&plan9cmd); | |
+ | |
+ tempfile.listptr = emalloc(0); | |
home = getenv("HOME") ? getenv("HOME") : "/"; | |
shpath = getenv("SHELL") ? getenv("SHELL") : shpath; | |
sh = basename(shpath); | |
@@ -133,16 +134,50 @@ main(int argc, char *argv[]) | |
modnum++; | |
if(file.nused) | |
current(file.filepptr[0]); | |
+ | |
setjmp(mainloop); | |
cmdloop(); | |
+ | |
trytoquit(); /* if we already q'ed, quitok will be true */ | |
+ | |
+ shutdown(); | |
exit(EXIT_SUCCESS); | |
} | |
void | |
+shutdown(void) | |
+{ | |
+ freecmd(); | |
+ for (int i = 0; i < file.nused; i++) | |
+ Fclose(file.filepptr[i]); | |
+ | |
+ if (!downloaded) | |
+ Fclose(cmd); | |
+ | |
+ if (genc) | |
+ free(genc); | |
+ | |
+ Strclose(&cmdstr); | |
+ Strclose(&lastpat); | |
+ Strclose(&lastregexp); | |
+ Strclose(&genstr); | |
+ Strclose(&rhs); | |
+ Strclose(&wd); | |
+ Strclose(&plan9cmd); | |
+ | |
+ if (file.listptr) | |
+ free(file.listptr); | |
+ | |
+ if (tempfile.listptr) | |
+ free(tempfile.listptr); | |
+ | |
+ freecmdlists(); | |
+} | |
+ | |
+void | |
usage(void) | |
{ | |
- dprint("usage: sam [-r machine] [-d] [-f] [-e] [-t samterm] [-s samname] F… | |
+ fprintf(stderr, "usage: sam [-r machine] [-d] [-f] [-e] [-t samterm] [-s s… | |
exit(EXIT_FAILURE); | |
} | |
@@ -270,17 +305,16 @@ trytoquit(void) | |
int c; | |
File *f; | |
- if(!quitok) | |
-{ | |
- for(c = 0; c<file.nused; c++){ | |
+ if (!quitok){ | |
+ for(c = 0; c < file.nused; c++){ | |
f = file.filepptr[c]; | |
- if(f!=cmd && f->state==Dirty){ | |
+ if(f != cmd && f->state == Dirty){ | |
quitok = true; | |
eof = false; | |
error(Echanges); | |
} | |
} | |
-} | |
+ } | |
} | |
void | |
@@ -720,7 +754,7 @@ settempfile(void) | |
{ | |
if(tempfile.nalloc < file.nused){ | |
free(tempfile.listptr); | |
- tempfile.listptr = emalloc(sizeof(*tempfile.filepptr)*file.nused); | |
+ tempfile.listptr = emalloc(sizeof(*tempfile.filepptr) * file.nused); | |
tempfile.nalloc = file.nused; | |
} | |
tempfile.nused = file.nused; | |
diff --git a/sam/sam.h b/sam/sam.h | |
@@ -207,6 +207,8 @@ void error_s(Err, char*); | |
int execute(File*, Posn, Posn); | |
int filematch(File*, String*); | |
void filename(File*); | |
+void freecmd(void); | |
+void freecmdlists(void); | |
File *getfile(String*); | |
int getname(File*, String*, bool); | |
int64_t getnum(void); | |
@@ -237,7 +239,8 @@ void resetxec(void); | |
void rgrow(List*, Posn, Posn); | |
void samerr(char*); | |
void settempfile(void); | |
-int skipbl(void); | |
+void shutdown(void); | |
+int skipbl(void); | |
void snarf(File*, Posn, Posn, Buffer*, bool); | |
void sortname(File*); | |
void startup(char*, int, char**, char**); | |
diff --git a/sam/unix.c b/sam/unix.c | |
@@ -125,14 +125,9 @@ waitfor(int pid) | |
void* | |
emalloc(uint64_t n) | |
{ | |
- void *p; | |
- | |
- if (n < sizeof(int)) | |
- n = sizeof(int); | |
- p = malloc(n); | |
- if(p == 0) | |
- panic("malloc fails"); | |
- memset(p, 0, n); | |
+ void *p = calloc(1, n < sizeof(int)? sizeof(int) : n); | |
+ if (!p) | |
+ panic("malloc failed"); | |
return p; | |
} | |
@@ -140,7 +135,7 @@ void* | |
erealloc(void *p, uint64_t n) | |
{ | |
p = realloc(p, n); | |
- if(p == 0) | |
+ if(!p) | |
panic("realloc fails"); | |
return p; | |
} |