summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>1999-07-20 22:34:41 +0000
committerPaul Smith <psmith@gnu.org>1999-07-20 22:34:41 +0000
commit73846549f62b832ca6ff761ad3640a86d3b32c86 (patch)
tree040672d69082d86fe744ca7157bee5b72147f511
parent169e6b8c3de0145c61ff2127b7c191d12f069d2b (diff)
downloadgunmake-73846549f62b832ca6ff761ad3640a86d3b32c86.tar.gz
* Fix memory leaks, fd leaks, and some long-standing bugs recognizing when
targets need to have their modtimes rechecked (-n, etc.)
-rw-r--r--.purify7
-rw-r--r--ChangeLog29
-rw-r--r--commands.c1
-rw-r--r--getloadavg.c2
-rw-r--r--implicit.c9
-rw-r--r--job.c34
-rw-r--r--read.c4
-rw-r--r--rule.c13
8 files changed, 70 insertions, 29 deletions
diff --git a/.purify b/.purify
index 098e741..dc1b1d9 100644
--- a/.purify
+++ b/.purify
@@ -1,4 +1,11 @@
+# Solaris (2.5.1) has a couple if issues.
+#
suppress plk malloc; setvbuf "libc*"; main "main.c"
+suppress umr kstat_read; kstat_chain_update; kstat_open; getloadavg
+suppress umr kstat_chain_update; kstat_open; getloadavg
+
+# The command line options stuff leaks a little bit. No big deal.
+#
suppress mlk malloc; xmalloc "misc.c"; decode_env_switches "main.c"
suppress plk malloc; xmalloc "misc.c"; decode_env_switches "main.c"
suppress mlk malloc; xmalloc "misc.c"; concat "misc.c"; decode_env_switches "main.c"
diff --git a/ChangeLog b/ChangeLog
index 3895a85..6e22e4c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,13 +1,28 @@
-1999-07-16 Paul D. Smith <psmith@gnu.org>
+1999-07-20 Paul D. Smith <psmith@gnu.org>
+
+ * job.c (start_job_command): Ensure that the state of the target
+ is cs_running. It might not be if we skipped all the lines due to
+ -n (for example).
+
+ * commands.c (execute_file_commands): If we discover that the
+ command script is empty and succeed early, set cs_running so the
+ modtime of the target is still rechecked.
- * .purify: New file: suppress some known-OK Purify messages.
+ * rule.c (freerule): Free the dependency list for the rule.
+
+ * implicit.c (pattern_search): When turning an intermediate file
+ into a real target, keep the also_make list.
+ Free the dep->name if we didn't use it during enter_file().
+
+1999-07-16 Paul D. Smith <psmith@gnu.org>
- * read.c (read_makefile): Remember to free the commands buffer if
- we can't find a makefile.
+ * read.c (read_makefile): Don't allocate the commands buffer until
+ we're sure we found a makefile and won't return early (mem leak).
* job.c (start_job_command): Broken #ifdef test: look for F_SETFD,
not FD_SETFD. Close-on-exec isn't getting set on the bad_stdin
file descriptor and it's leaking :-/.
+ * getloadavg.c (getloadavg): Ditto.
1999-07-15 Paul D. Smith <psmith@gnu.org>
@@ -371,9 +386,9 @@
1998-10-13 Paul D. Smith <psmith@gnu.org>
- * job.c (new_job): If the command list resolves to empty (through
- variable expansion, for example), stop early rather than running
- start_waiting_job().
+ * job.c (start_job_command): If the command list resolves to no
+ chars at all (e.g.: "foo:;$(empty)") then command_ptr is NULL;
+ quit early.
1998-10-12 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
diff --git a/commands.c b/commands.c
index dd7b1be..9d7a5de 100644
--- a/commands.c
+++ b/commands.c
@@ -344,6 +344,7 @@ execute_file_commands (file)
/* We are all out of commands.
If we have gotten this far, all the previous commands
have run successfully, so we have winning update status. */
+ set_command_state (file, cs_running);
file->update_status = 0;
notice_finished_file (file);
return;
diff --git a/getloadavg.c b/getloadavg.c
index 36245ef..79eedfc 100644
--- a/getloadavg.c
+++ b/getloadavg.c
@@ -966,7 +966,7 @@ getloadavg (loadavg, nelem)
{
/* Set the channel to close on exec, so it does not
litter any child's descriptor table. */
-# ifdef FD_SETFD
+# ifdef F_SETFD
# ifndef FD_CLOEXEC
# define FD_CLOEXEC 1
# endif
diff --git a/implicit.c b/implicit.c
index dfe19da..3ed23a3 100644
--- a/implicit.c
+++ b/implicit.c
@@ -524,6 +524,7 @@ pattern_search (file, archive, depth, recursions)
f->deps = imf->deps;
f->cmds = imf->cmds;
f->stem = imf->stem;
+ f->also_make = imf->also_make;
imf = lookup_file (intermediate_patterns[deps_found]);
if (imf != 0 && imf->precious)
f->precious = 1;
@@ -532,6 +533,9 @@ pattern_search (file, archive, depth, recursions)
for (dep = f->deps; dep != 0; dep = dep->next)
{
dep->file = enter_file (dep->name);
+ /* enter_file uses dep->name _if_ we created a new file. */
+ if (dep->name != dep->file->name)
+ free (dep->name);
dep->name = 0;
dep->file->tried_implicit |= dep->changed;
}
@@ -591,10 +595,9 @@ pattern_search (file, archive, depth, recursions)
file->cmds = rule->cmds;
- /* Put the targets other than the one that
- matched into FILE's `also_make' member. */
+ /* If this rule builds other targets, too, put the others into FILE's
+ `also_make' member. */
- /* If there was only one target, there is nothing to do. */
if (rule->targets[1] != 0)
for (i = 0; rule->targets[i] != 0; ++i)
if (i != matches[foundrule])
diff --git a/job.c b/job.c
index e84897b..0ae2d74 100644
--- a/job.c
+++ b/job.c
@@ -744,6 +744,10 @@ start_job_command (child)
char **argv;
#endif
+ /* If we have a completely empty commandset, stop now. */
+ if (!child->command_ptr)
+ goto next_command;
+
/* Combine the flags parsed for the line itself with
the flags specified globally for this target. */
flags = (child->file->command_flags
@@ -812,14 +816,16 @@ start_job_command (child)
{
next_command:
#ifdef __MSDOS__
- execute_by_shell = 0; /* in case construct_command_argv sets it */
+ execute_by_shell = 0; /* in case construct_command_argv sets it */
#endif
/* This line has no commands. Go to the next. */
if (job_next_command (child))
start_job_command (child);
else
{
- /* No more commands. All done. */
+ /* No more commands. Make sure we're "running"; we might not be if
+ (e.g.) all commands were skipped due to -n. */
+ set_command_state (child->file, cs_running);
child->file->update_status = 0;
notice_finished_file (child->file);
}
@@ -843,11 +849,12 @@ start_job_command (child)
#else
(argv[0] && !strcmp(argv[0], "/bin/sh"))
#endif
- && (argv[1] && !strcmp(argv[1], "-c"))
- && (argv[2] && !strcmp(argv[2], ":"))
+ && (argv[1] && !strcmp(argv[1], "-c"))
+ && (argv[2] && !strcmp(argv[2], ":"))
&& argv[3] == NULL)
{
- set_command_state (child->file, cs_running);
+ free (argv[0]);
+ free ((char *) argv);
goto next_command;
}
#endif /* !VMS && !_AMIGA */
@@ -1144,7 +1151,7 @@ start_waiting_job (c)
/* Read a token. We set the non-blocking bit on this earlier,
so if there's no token to be read we'll fall through to the
- select. The select block until (a) there's data to read,
+ select. The select blocks until (a) there's data to read,
in which case we come back around and try to grab the token
before someone else does, or (b) a signal, such as SIGCHLD,
is caught (because we installed a handler for it). If the
@@ -1364,16 +1371,11 @@ new_job (file)
c->job_token = 0;
/* Fetch the first command line to be run. */
- if (job_next_command (c))
- /* The job is now primed. Start it running. */
- (void)start_waiting_job (c);
- else
- {
- /* There were no commands (variable expands to empty?). All done. */
- c->file->update_status = 0;
- notice_finished_file(c->file);
- free_child (c);
- }
+ job_next_command (c);
+
+ /* The job is now primed. Start it running.
+ (This will notice if there are in fact no commands.) */
+ (void)start_waiting_job (c);
if (job_slots == 1)
/* Since there is only one job slot, make things run linearly.
diff --git a/read.c b/read.c
index 0a39ef6..bfc247e 100644
--- a/read.c
+++ b/read.c
@@ -280,7 +280,7 @@ read_makefile (filename, flags)
register FILE *infile;
struct linebuffer lb;
unsigned int commands_len = 200;
- char *commands = (char *) xmalloc (200);
+ char *commands;
unsigned int commands_idx = 0;
unsigned int cmds_started;
char *p;
@@ -396,7 +396,6 @@ read_makefile (filename, flags)
attempt, rather from FILENAME itself. Restore it in case the
caller wants to use it in a message. */
errno = makefile_errno;
- free (commands);
return 0;
}
@@ -408,6 +407,7 @@ read_makefile (filename, flags)
when the start of the next rule (or eof) is encountered. */
initbuffer (&lb);
+ commands = xmalloc (200);
while (!feof (infile))
{
diff --git a/rule.c b/rule.c
index 08ab640..b813fa0 100644
--- a/rule.c
+++ b/rule.c
@@ -439,10 +439,23 @@ freerule (rule, lastrule)
{
struct rule *next = rule->next;
register unsigned int i;
+ register struct dep *dep;
for (i = 0; rule->targets[i] != 0; ++i)
free (rule->targets[i]);
+ dep = rule->deps;
+ while (dep)
+ {
+ struct dep *t;
+
+ t = dep->next;
+ /* We might leak dep->name here, but I'm not sure how to fix this: I
+ think that pointer might be shared (e.g., in the file hash?) */
+ free ((char *) dep);
+ dep = t;
+ }
+
free ((char *) rule->targets);
free ((char *) rule->suffixes);
free ((char *) rule->lens);