mirror of
https://salsa.debian.org/srivasta/make-dfsg.git
synced 2024-12-25 05:29:47 +00:00
* Fix memory leaks, fd leaks, and some long-standing bugs recognizing when
targets need to have their modtimes rechecked (-n, etc.)
This commit is contained in:
parent
169e6b8c3d
commit
73846549f6
8 changed files with 70 additions and 29 deletions
7
.purify
7
.purify
|
@ -1,4 +1,11 @@
|
||||||
|
# Solaris (2.5.1) has a couple if issues.
|
||||||
|
#
|
||||||
suppress plk malloc; setvbuf "libc*"; main "main.c"
|
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 mlk malloc; xmalloc "misc.c"; decode_env_switches "main.c"
|
||||||
suppress plk 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"
|
suppress mlk malloc; xmalloc "misc.c"; concat "misc.c"; decode_env_switches "main.c"
|
||||||
|
|
29
ChangeLog
29
ChangeLog
|
@ -1,13 +1,28 @@
|
||||||
|
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.
|
||||||
|
|
||||||
|
* 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>
|
1999-07-16 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
* .purify: New file: suppress some known-OK Purify messages.
|
* 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).
|
||||||
* read.c (read_makefile): Remember to free the commands buffer if
|
|
||||||
we can't find a makefile.
|
|
||||||
|
|
||||||
* job.c (start_job_command): Broken #ifdef test: look for F_SETFD,
|
* 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
|
not FD_SETFD. Close-on-exec isn't getting set on the bad_stdin
|
||||||
file descriptor and it's leaking :-/.
|
file descriptor and it's leaking :-/.
|
||||||
|
* getloadavg.c (getloadavg): Ditto.
|
||||||
|
|
||||||
1999-07-15 Paul D. Smith <psmith@gnu.org>
|
1999-07-15 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
@ -371,9 +386,9 @@
|
||||||
|
|
||||||
1998-10-13 Paul D. Smith <psmith@gnu.org>
|
1998-10-13 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
* job.c (new_job): If the command list resolves to empty (through
|
* job.c (start_job_command): If the command list resolves to no
|
||||||
variable expansion, for example), stop early rather than running
|
chars at all (e.g.: "foo:;$(empty)") then command_ptr is NULL;
|
||||||
start_waiting_job().
|
quit early.
|
||||||
|
|
||||||
1998-10-12 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
|
1998-10-12 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,7 @@ execute_file_commands (file)
|
||||||
/* We are all out of commands.
|
/* We are all out of commands.
|
||||||
If we have gotten this far, all the previous commands
|
If we have gotten this far, all the previous commands
|
||||||
have run successfully, so we have winning update status. */
|
have run successfully, so we have winning update status. */
|
||||||
|
set_command_state (file, cs_running);
|
||||||
file->update_status = 0;
|
file->update_status = 0;
|
||||||
notice_finished_file (file);
|
notice_finished_file (file);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -966,7 +966,7 @@ getloadavg (loadavg, nelem)
|
||||||
{
|
{
|
||||||
/* Set the channel to close on exec, so it does not
|
/* Set the channel to close on exec, so it does not
|
||||||
litter any child's descriptor table. */
|
litter any child's descriptor table. */
|
||||||
# ifdef FD_SETFD
|
# ifdef F_SETFD
|
||||||
# ifndef FD_CLOEXEC
|
# ifndef FD_CLOEXEC
|
||||||
# define FD_CLOEXEC 1
|
# define FD_CLOEXEC 1
|
||||||
# endif
|
# endif
|
||||||
|
|
|
@ -524,6 +524,7 @@ pattern_search (file, archive, depth, recursions)
|
||||||
f->deps = imf->deps;
|
f->deps = imf->deps;
|
||||||
f->cmds = imf->cmds;
|
f->cmds = imf->cmds;
|
||||||
f->stem = imf->stem;
|
f->stem = imf->stem;
|
||||||
|
f->also_make = imf->also_make;
|
||||||
imf = lookup_file (intermediate_patterns[deps_found]);
|
imf = lookup_file (intermediate_patterns[deps_found]);
|
||||||
if (imf != 0 && imf->precious)
|
if (imf != 0 && imf->precious)
|
||||||
f->precious = 1;
|
f->precious = 1;
|
||||||
|
@ -532,6 +533,9 @@ pattern_search (file, archive, depth, recursions)
|
||||||
for (dep = f->deps; dep != 0; dep = dep->next)
|
for (dep = f->deps; dep != 0; dep = dep->next)
|
||||||
{
|
{
|
||||||
dep->file = enter_file (dep->name);
|
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->name = 0;
|
||||||
dep->file->tried_implicit |= dep->changed;
|
dep->file->tried_implicit |= dep->changed;
|
||||||
}
|
}
|
||||||
|
@ -591,10 +595,9 @@ pattern_search (file, archive, depth, recursions)
|
||||||
|
|
||||||
file->cmds = rule->cmds;
|
file->cmds = rule->cmds;
|
||||||
|
|
||||||
/* Put the targets other than the one that
|
/* If this rule builds other targets, too, put the others into FILE's
|
||||||
matched into FILE's `also_make' member. */
|
`also_make' member. */
|
||||||
|
|
||||||
/* If there was only one target, there is nothing to do. */
|
|
||||||
if (rule->targets[1] != 0)
|
if (rule->targets[1] != 0)
|
||||||
for (i = 0; rule->targets[i] != 0; ++i)
|
for (i = 0; rule->targets[i] != 0; ++i)
|
||||||
if (i != matches[foundrule])
|
if (i != matches[foundrule])
|
||||||
|
|
34
job.c
34
job.c
|
@ -744,6 +744,10 @@ start_job_command (child)
|
||||||
char **argv;
|
char **argv;
|
||||||
#endif
|
#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
|
/* Combine the flags parsed for the line itself with
|
||||||
the flags specified globally for this target. */
|
the flags specified globally for this target. */
|
||||||
flags = (child->file->command_flags
|
flags = (child->file->command_flags
|
||||||
|
@ -812,14 +816,16 @@ start_job_command (child)
|
||||||
{
|
{
|
||||||
next_command:
|
next_command:
|
||||||
#ifdef __MSDOS__
|
#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
|
#endif
|
||||||
/* This line has no commands. Go to the next. */
|
/* This line has no commands. Go to the next. */
|
||||||
if (job_next_command (child))
|
if (job_next_command (child))
|
||||||
start_job_command (child);
|
start_job_command (child);
|
||||||
else
|
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;
|
child->file->update_status = 0;
|
||||||
notice_finished_file (child->file);
|
notice_finished_file (child->file);
|
||||||
}
|
}
|
||||||
|
@ -843,11 +849,12 @@ start_job_command (child)
|
||||||
#else
|
#else
|
||||||
(argv[0] && !strcmp(argv[0], "/bin/sh"))
|
(argv[0] && !strcmp(argv[0], "/bin/sh"))
|
||||||
#endif
|
#endif
|
||||||
&& (argv[1] && !strcmp(argv[1], "-c"))
|
&& (argv[1] && !strcmp(argv[1], "-c"))
|
||||||
&& (argv[2] && !strcmp(argv[2], ":"))
|
&& (argv[2] && !strcmp(argv[2], ":"))
|
||||||
&& argv[3] == NULL)
|
&& argv[3] == NULL)
|
||||||
{
|
{
|
||||||
set_command_state (child->file, cs_running);
|
free (argv[0]);
|
||||||
|
free ((char *) argv);
|
||||||
goto next_command;
|
goto next_command;
|
||||||
}
|
}
|
||||||
#endif /* !VMS && !_AMIGA */
|
#endif /* !VMS && !_AMIGA */
|
||||||
|
@ -1144,7 +1151,7 @@ start_waiting_job (c)
|
||||||
|
|
||||||
/* Read a token. We set the non-blocking bit on this earlier,
|
/* 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
|
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
|
in which case we come back around and try to grab the token
|
||||||
before someone else does, or (b) a signal, such as SIGCHLD,
|
before someone else does, or (b) a signal, such as SIGCHLD,
|
||||||
is caught (because we installed a handler for it). If the
|
is caught (because we installed a handler for it). If the
|
||||||
|
@ -1364,16 +1371,11 @@ new_job (file)
|
||||||
c->job_token = 0;
|
c->job_token = 0;
|
||||||
|
|
||||||
/* Fetch the first command line to be run. */
|
/* Fetch the first command line to be run. */
|
||||||
if (job_next_command (c))
|
job_next_command (c);
|
||||||
/* The job is now primed. Start it running. */
|
|
||||||
(void)start_waiting_job (c);
|
/* The job is now primed. Start it running.
|
||||||
else
|
(This will notice if there are in fact no commands.) */
|
||||||
{
|
(void)start_waiting_job (c);
|
||||||
/* There were no commands (variable expands to empty?). All done. */
|
|
||||||
c->file->update_status = 0;
|
|
||||||
notice_finished_file(c->file);
|
|
||||||
free_child (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (job_slots == 1)
|
if (job_slots == 1)
|
||||||
/* Since there is only one job slot, make things run linearly.
|
/* Since there is only one job slot, make things run linearly.
|
||||||
|
|
4
read.c
4
read.c
|
@ -280,7 +280,7 @@ read_makefile (filename, flags)
|
||||||
register FILE *infile;
|
register FILE *infile;
|
||||||
struct linebuffer lb;
|
struct linebuffer lb;
|
||||||
unsigned int commands_len = 200;
|
unsigned int commands_len = 200;
|
||||||
char *commands = (char *) xmalloc (200);
|
char *commands;
|
||||||
unsigned int commands_idx = 0;
|
unsigned int commands_idx = 0;
|
||||||
unsigned int cmds_started;
|
unsigned int cmds_started;
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -396,7 +396,6 @@ read_makefile (filename, flags)
|
||||||
attempt, rather from FILENAME itself. Restore it in case the
|
attempt, rather from FILENAME itself. Restore it in case the
|
||||||
caller wants to use it in a message. */
|
caller wants to use it in a message. */
|
||||||
errno = makefile_errno;
|
errno = makefile_errno;
|
||||||
free (commands);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,6 +407,7 @@ read_makefile (filename, flags)
|
||||||
when the start of the next rule (or eof) is encountered. */
|
when the start of the next rule (or eof) is encountered. */
|
||||||
|
|
||||||
initbuffer (&lb);
|
initbuffer (&lb);
|
||||||
|
commands = xmalloc (200);
|
||||||
|
|
||||||
while (!feof (infile))
|
while (!feof (infile))
|
||||||
{
|
{
|
||||||
|
|
13
rule.c
13
rule.c
|
@ -439,10 +439,23 @@ freerule (rule, lastrule)
|
||||||
{
|
{
|
||||||
struct rule *next = rule->next;
|
struct rule *next = rule->next;
|
||||||
register unsigned int i;
|
register unsigned int i;
|
||||||
|
register struct dep *dep;
|
||||||
|
|
||||||
for (i = 0; rule->targets[i] != 0; ++i)
|
for (i = 0; rule->targets[i] != 0; ++i)
|
||||||
free (rule->targets[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->targets);
|
||||||
free ((char *) rule->suffixes);
|
free ((char *) rule->suffixes);
|
||||||
free ((char *) rule->lens);
|
free ((char *) rule->lens);
|
||||||
|
|
Loading…
Reference in a new issue