Compare commits

..

50 Commits
3.71 ... 3.71.2

Author SHA1 Message Date
Roland McGrath
dc44a79020 Add HAVE_SYS_SIGLIST and HAVE__SYS_SIGLIST. 1994-09-09 07:16:54 +00:00
Roland McGrath
8ed6e13cfe (Archive Suffix Rules): Remove Next pointer. 1994-09-09 06:59:08 +00:00
Roland McGrath
b321e0f535 (decode_switches): The non-option return from getopt is 1, not 0.
(command_variables): New type and variable.
(decode_switches, decode_env_switches): After making a variable definition,
record the struct variable pointer in the command_variables chain.
(define_makeflags): If ALL, write variable definitions for
command_variables.
1994-09-09 06:45:51 +00:00
Roland McGrath
c1433e9495 (other_args): Variable removed.
(goals, lastgoal): New static variables (moved from auto in main).
(main): Don't process OTHER_ARGS at all.
Don't set variable MAKEOVERRIDES at all; define MAKE to just $(MAKE_COMMAND).
(init_switches): Prepend a - (return in order) instead of a + (require order).
(decode_switches): Don't set OTHER_ARGS at all.
Grok '\0' return from getopt_long as non-option argument; try variable
definition and (if !ENV) enter goal targets here.
(decode_env_switches): Use allocated_variable_expand to store value.
Use find_next_token to simplify word-splitting loop.
Don't prepend a dash to uninterpreted value.
Instead, if split into only one word, try variable definition and failing
that prepend a dash to the word and pass it to decode_switches as a single arg.
1994-09-09 05:37:40 +00:00
Roland McGrath
e4a94e0210 (notice_finished_file): Only recheck modtimes if FILE->command_state was
cs_running on entry (meaning the commands actually just ran).
(update_file_1): Whenever we set FILE->update_status, call
notice_finished_file instead of just set_command_state.
1994-09-07 07:06:46 +00:00
Roland McGrath
9e97330bcb (start_job_command): Whenever we set CHILD->file->update_status, call
notice_finished_file instead of just set_command_state.
1994-09-07 07:02:23 +00:00
Roland McGrath
4969b416b8 (set_command_state): Actually set FILE->command_state. 1994-09-07 00:31:13 +00:00
Roland McGrath
0bd0301ae3 (set_command_state): Fix typo. 1994-09-07 00:24:10 +00:00
Roland McGrath
ff6efbadf5 (set_command_state): Declare D. 1994-09-07 00:17:57 +00:00
Roland McGrath
0b3317d2e1 Add missing ". 1994-09-07 00:15:23 +00:00
Roland McGrath
ca5a872280 Changed all assignments of command_state members to calls to
set_command_state.
1994-09-07 00:04:49 +00:00
Roland McGrath
4244f182f2 (set_command_state): New function. 1994-09-07 00:02:25 +00:00
Roland McGrath
be6e6d74bb Declare set_command_state. 1994-09-06 23:48:36 +00:00
Roland McGrath
4c0fef3dd7 (init_switches): Put a + first in options. 1994-09-06 23:13:43 +00:00
Richard M. Stallman
d3b65c3cb7 entered into RCS 1994-08-21 17:29:57 +00:00
gnu
bc48185f8e Formerly make-stds.texi.~29~ 1994-08-10 05:41:00 +00:00
Roland McGrath
6fcf219fa7 Initial revision 1994-07-25 23:47:05 +00:00
Roland McGrath
d2e23eefd2 Added trailing CRs. 1994-07-25 23:46:16 +00:00
Roland McGrath
55162a6730 Changed all uses of ':' to PATH_SEPARATOR_CHAR. 1994-07-25 23:34:32 +00:00
Roland McGrath
021ea7e61c (directory_before_chdir): New variable, moved out of main (was local).
(main) [__MSDOS__]: Look for \ or : to delimit last component of PROGRAM.
Don't frob ARGV[0] before setting MAKE_COMMAND variable.
(die): Change back to `directory_before_chdir' before dying.

Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:33:26 +00:00
Roland McGrath
f663464925 (PATH_SEPARATOR_CHAR): Macro removed (now in make.h). 1994-07-25 23:28:08 +00:00
Roland McGrath
5d435e0859 (PATH_SEPARATOR_CHAR): New macro; differing defns for [__MSDOS__] and not. 1994-07-25 23:27:48 +00:00
Roland McGrath
a2ab31ba62 [__MSDOS__]: Include <process.h>.
(PATH_SEPARATOR_CHAR): New macro; differing defns for [__MSDOS__] and not.
[__MSDOS__] (dos_pid, dos_status, dos_bname, dos_bename, dos_batch_file):
New variables.
(reap_children) [__MSDOS__]: Don't call wait; just examine those vars.
(unblock_sigs) [__MSDOS__]: Do nothing.
(start_job_command) [__MSDOS__]: Use spawnvpe instead of vfork and exec.
(load_too_high) [__MSDOS__]: Always return true.
(search_path) [__MSDOS__]: Check for : or / in FILE to punt.
Use PATH_SEPARATOR_CHAR instead of ':'.
(construct_command_argv_internal) [__MSDOS__]: Wholly different values for
sh_chars and sh_cmds.  Wholly new code to handle shell scripts.

Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:23:03 +00:00
Roland McGrath
da2ea1ea7f (expand_function: `shell') [__MSDOS__]: Wholly new implementation. 1994-07-25 23:06:00 +00:00
Roland McGrath
21a1b3b255 [__MSDOS__] (dosify): New function.
(dir_contents_file_exists_p) [__MSDOS__]: Call it on FILENAME and process
the result instead of FILENAME itself.
(file_impossible_p) [__MSDOS__]: Likewise.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:01:19 +00:00
Roland McGrath
c8e76a708e [__MSDOS__]: Define GCC_IS_NATIVE.
(default_suffix_rules) [__MSDOS__]: Use `y_tab.c' instead of `y.tab.c'.
(default_variables) [GCC_IS_NATIVE]: Set CC and CXX to `gcc', YACC to
`bison -y', and LEX to `flex'.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 22:54:09 +00:00
Roland McGrath
461cffc4e9 Initial revision 1994-07-25 22:48:06 +00:00
Roland McGrath
cdd25d1fb3 (fatal_error_signal) [__MSDOS__]: Just remove intermediates and exit.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 22:47:14 +00:00
Roland McGrath
9a3666d550 (set_file_variables): Add parens in length computation in .SUFFIXES dep
loop to quiet compiler warning.  From Jim Meyering.
1994-07-25 22:09:25 +00:00
Roland McGrath
90dffad2cc (read_makefile): Free FILENAME if we allocated it. From Jim Meyering. 1994-07-25 22:07:41 +00:00
Roland McGrath
c1f2ef6d09 Update ISBN number to 1-882114-50-7 for edition 0.46.
Use new macro ISBN set at top of file.
1994-07-20 12:30:52 +00:00
Roland McGrath
51250a676d Split a shell command line in @example to avoid overfull hbox. 1994-07-08 18:33:15 +00:00
Roland McGrath
d2461a2409 (Goals): Say that only first target in first rule is default goal.
(Archive Pitfalls): New node.
1994-07-05 21:27:09 +00:00
Roland McGrath
fdea69c5fa (selective_vpath_search): Use safe_stat in place of stat. 1994-07-04 21:56:24 +00:00
Roland McGrath
7c7552336d (construct_include_path): Use safe_stat in place of stat. 1994-07-04 21:55:13 +00:00
Roland McGrath
535dcf6a22 (search_path): Use safe_stat in place of stat. 1994-07-04 21:54:18 +00:00
Roland McGrath
84091971f9 (find_directory): Use safe_stat in place of stat. 1994-07-04 21:53:25 +00:00
Roland McGrath
61da194af9 (delete_target): Use safe_stat in place of stat. 1994-07-04 21:52:28 +00:00
Roland McGrath
30c1465265 (ar_member_touch) [EINTR]: Do EINTR looping around fstat. 1994-07-04 21:51:49 +00:00
Roland McGrath
b574b8ea5a (name_mtime): Use safe_stat in place of stat.
(touch_file) [EINTR]: Do EINTR looping around fstat.
1994-07-04 21:50:03 +00:00
Roland McGrath
710e8e6f6f (safe_stat): New function, EINTR-safe wrapper around stat. 1994-07-04 21:46:58 +00:00
Roland McGrath
4a8a7637f3 (read_makefile): Check for a shell command first, and then strip leading
tabs before further checking if it's not a shell command line.
1994-06-24 10:34:03 +00:00
Roland McGrath
6348923799 Fix typo in last change. 1994-06-24 10:22:37 +00:00
Roland McGrath
660a23d649 [__arm]: Undefine POSIX.
[!__GNU_LIBRARY__ && !POSIX && !_POSIX_VERSION]: Don't declare system
functions that return int.
1994-06-24 09:45:35 +00:00
Roland McGrath
5bd9836fba (construct_command_argv_internal): After swallowing a backslash-newline
combination, if INSTRING is set goto string_char (new label) for normal
INSTRING handling code.
1994-06-24 09:40:13 +00:00
Roland McGrath
0cb47363e1 Put #include of errno.h and decl of errno before #ifndef HAVE_GETLOADAVG. 1994-06-04 05:24:48 +00:00
Roland McGrath
fff5a9ece0 Don't check for sys_siglist and _sys_siglist with AC_HAVE_FUNCS.
Instead use two AC_COMPILE_CHECKs.
1994-06-04 05:11:12 +00:00
Richard M. Stallman
e3a24fc596 [emacs]: Block input around the garbage reclamation.
Include blockinput.h.
1994-06-02 17:45:40 +00:00
Roland McGrath
bb38b0c253 [!__GNU_LIBRARY__ && !POSIX]: Also test #ifndef _POSIX_VERSION for these
declarations.
1994-05-23 22:25:30 +00:00
Roland McGrath
d2ed03e72a [GETLOADAVG_PRIVILEGED] [POSIX]: Remove bogus #ifndefs around #undefs of
HAVE_SETREUID and HAVE_SETREGID.
1994-05-23 22:20:30 +00:00
22 changed files with 1043 additions and 370 deletions

View File

@@ -3,3 +3,9 @@
/* Define this if the SCCS `get' command understands the `-G<file>' option. */
#undef SCCS_GET_MINUS_G
/* Define this if the C library defines the variable `sys_siglist'. */
#undef HAVE_SYS_SIGLIST
/* Define this if the C library defines the variable `_sys_siglist'. */
#undef HAVE__SYS_SIGLIST

View File

@@ -29,6 +29,10 @@
#endif
#endif
#ifdef emacs
#include "blockinput.h"
#endif
/* If compiling with GCC 2, this file's not needed. */
#if !defined (__GNUC__) || __GNUC__ < 2
@@ -176,6 +180,10 @@ alloca (size)
{
register header *hp; /* Traverses linked list. */
#ifdef emacs
BLOCK_INPUT;
#endif
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
@@ -190,6 +198,10 @@ alloca (size)
break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */
#ifdef emacs
UNBLOCK_INPUT;
#endif
}
if (size == 0)

View File

@@ -495,7 +495,11 @@ ar_member_touch (arname, memname)
if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
goto lose;
/* The file's mtime is the time we we want. */
#ifdef EINTR
while (fstat (fd, &statbuf) < 0 && errno == EINTR);
#else
fstat (fd, &statbuf);
#endif
#if defined(ARFMAG) || defined(AIAMAG)
/* Advance member's time to that time */
for (i = 0; i < sizeof ar_hdr.ar_date; i++)

View File

@@ -87,7 +87,7 @@ set_file_variables (file)
for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
{
unsigned int slen = strlen (dep_name (d));
if (len > slen && !strncmp (dep_name (d), name + len - slen, slen))
if (len > slen && !strncmp (dep_name (d), name + (len - slen), slen))
{
file->stem = savestring (name, len - slen);
break;
@@ -329,6 +329,10 @@ RETSIGTYPE
fatal_error_signal (sig)
int sig;
{
#ifdef __MSDOS__
remove_intermediates (1);
exit (1);
#else /* Not MSDOS. */
handling_fatal_signal = 1;
/* Set the handling for this signal to the default.
@@ -385,6 +389,7 @@ fatal_error_signal (sig)
will be unblocked when we return and arrive then to kill us. */
if (kill (getpid (), sig) < 0)
pfatal_with_name ("kill");
#endif /* MSDOS. */
}
/* Delete FILE unless it's precious or not actually a file (phony),
@@ -416,7 +421,7 @@ delete_target (file, on_behalf_of)
}
#endif
if (stat (file->name, &st) == 0
if (safe_stat (file->name, &st) == 0
&& S_ISREG (st.st_mode)
&& (time_t) st.st_mtime != file->last_mtime)
{

65
configh.dos.template Normal file
View File

@@ -0,0 +1,65 @@
/* Generated automatically from configure.in by autoheader. DO NOT EDIT! */
#define INCLUDEDIR "c:/djgpp/include"
#define LIBDIR "c:/djgpp/lib"
/* Define if you have dirent.h. */
#define DIRENT
/* Define if you have the strcoll function and it is properly defined. */
#define HAVE_STRCOLL
/* Define if you have unistd.h. */
#define HAVE_UNISTD_H
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS
/* Define if `sys_siglist' is declared by <signal.h>. */
#define SYS_SIGLIST_DECLARED
/* Define if you have getdtablesize. */
#define HAVE_GETDTABLESIZE
/* Define if you have dup2. */
#define HAVE_DUP2
/* Define if you have sys_siglist. */
#undef HAVE_SYS_SIGLIST
/* Define if you have _sys_siglist. */
#undef HAVE__SYS_SIGLIST
/* Define if you have psignal. */
#define HAVE_PSIGNAL
/* Define if you have getcwd. */
#define HAVE_GETCWD
/* Define if you have sigsetmask. */
#define HAVE_SIGSETMASK
/* Define if you have setlinebuf. */
#define HAVE_SETLINEBUF
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H
/* Define if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H
#define INCLUDEDIR "c:/djgpp/include"
#define LIBDIR "c:/djgpp/lib"
#define SCCS_GET "get"

43
configure.bat Normal file
View File

@@ -0,0 +1,43 @@
@echo off
echo Configuring MAKE for go32
rem This batch file assumes a unix-type "sed" program
update configh.dos config.h
echo # Makefile generated by "configure.bat"> Makefile
if exist config.sed del config.sed
echo ": try_sl ">> config.sed
echo "/\\$/ { ">> config.sed
echo " N ">> config.sed
echo " s/[ ]*\\\n[ ]*/ / ">> config.sed
echo " b try_sl ">> config.sed
echo "} ">> config.sed
echo "s/@srcdir@/./ ">> config.sed
echo "s/@CC@/gcc/ ">> config.sed
echo "s/@CFLAGS@/-O2 -g -DHAVE_CONFIG_H/ ">> config.sed
echo "s/@LDFLAGS@// ">> config.sed
echo "s/@RANLIB@/ranlib/ ">> config.sed
echo "s/@DEFS@// ">> config.sed
echo "s/@REMOTE@/stub/ ">> config.sed
echo "s/@ALLOCA@// ">> config.sed
echo "s/@LIBS@// ">> config.sed
echo "s/@LIBOBJS@// ">> config.sed
echo "s/@SET_MAKE@// ">> config.sed
echo "s/^Makefile *:/_Makefile:/ ">> config.sed
echo "s/^config.h *:/_config.h:/ ">> config.sed
echo "s/^defines *=.*$/defines =/ ">> config.sed
echo "/mv -f make.new make/d ">> config.sed
echo "s/cd glob; $(MAKE)/$(MAKE) -C glob/ ">> config.sed
sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
sed -f config2.sed Makefile.in >> Makefile
del config.sed
del config2.sed
cd glob
call configure
cd ..

View File

@@ -29,9 +29,15 @@ AC_STAT_MACROS_BROKEN
AC_SUBST(LIBOBJS)
AC_HAVE_FUNCS(getdtablesize sys_siglist _sys_siglist psignal \
AC_HAVE_FUNCS(getdtablesize psignal \
dup2 getcwd sigsetmask getgroups setlinebuf \
seteuid setegid setreuid setregid strerror)
AC_COMPILE_CHECK(sys_siglist, ,
[extern char *sys_siglist[]; puts(*sys_siglist);],
AC_DEFINE(HAVE_SYS_SIGLIST))
AC_COMPILE_CHECK(_sys_siglist, ,
[extern char *_sys_siglist[]; puts(*_sys_siglist);],
AC_DEFINE(HAVE__SYS_SIGLIST))
AC_ALLOCA
AC_VFORK
AC_SETVBUF_REVERSED

View File

@@ -23,6 +23,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "commands.h"
#include "variable.h"
/* Define GCC_IS_NATIVE if gcc is the native development environment on
your system (gcc/bison/flex vs cc/yacc/lex). */
#ifdef __MSDOS__
#define GCC_IS_NATIVE
#endif
/* This is the default list of suffixes for suffix rules.
`.s' must come last, so that a `.o' file will be made from
@@ -133,12 +139,20 @@ static char *default_suffix_rules[] =
".c.ln",
"$(LINT.c) -C$* $<",
".y.ln",
#ifndef __MSDOS__
"$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c",
#else
"$(YACC.y) $< \n $(LINT.c) -C$* y_tab.c \n $(RM) y_tab.c",
#endif
".l.ln",
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
".y.c",
#ifndef __MSDOS__
"$(YACC.y) $< \n mv -f y.tab.c $@",
#else
"$(YACC.y) $< \n mv -f y_tab.c $@",
#endif
".l.c",
"@$(RM) $@ \n $(LEX.l) $< > $@",
@@ -203,8 +217,13 @@ static char *default_variables[] =
"ARFLAGS", "rfv",
#endif
"AS", "as",
#ifdef GCC_IS_NATIVE
"CC", "gcc",
"CXX", "gcc",
#else
"CC", "cc",
"CXX", "g++",
#endif
/* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist,
and to the empty string if $@ does exist. */
@@ -237,7 +256,11 @@ static char *default_variables[] =
#endif /* Cray. */
"GET", SCCS_GET,
"LD", "ld",
#ifdef GCC_IS_NATIVE
"LEX", "flex",
#else
"LEX", "lex",
#endif
"LINT", "lint",
"M2C", "m2c",
#ifdef pyr
@@ -250,7 +273,11 @@ static char *default_variables[] =
"PC", "pc",
#endif /* CRAY. */
#endif /* pyr. */
#ifdef GCC_IS_NATIVE
"YACC", "bison -y",
#else
"YACC", "yacc", /* Or "bison -y" */
#endif
"MAKEINFO", "makeinfo",
"TEX", "tex",
"TEXI2DVI", "texi2dvi",

55
dir.c
View File

@@ -1,5 +1,5 @@
/* Directory hashing for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify
@@ -47,6 +47,49 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#endif /* POSIX */
#ifdef __MSDOS__
#inlcude <ctype.h>
static char *
dosify (filename)
char *filename;
{
static char dos_filename[14];
char *df;
int i;
if (filename == 0)
return 0;
if (strpbrk (filename, "\"*+,;<=>?[\\]|") != 0)
return filename;
df = dos_filename;
/* First, transform the name part. */
for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i)
*df++ = tolower (*filename++);
/* Now skip to the next dot. */
while (*filename != '\0' && *filename != '.')
++filename;
if (*filename != '\0')
{
*df++ = *filename++;
for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
*df++ = tolower (*filename++);
}
/* Look for more dots. */
while (*filename != '\0' && *filename != '.')
++filename;
if (*filename == '.')
return filename;
*df = 0;
return dos_filename;
}
#endif
/* Hash table of directories. */
#ifndef DIRECTORY_BUCKETS
@@ -136,7 +179,7 @@ find_directory (name)
/* The directory is not in the name hash table.
Find its device and inode numbers, and look it up by them. */
if (stat (name, &st) < 0)
if (safe_stat (name, &st) < 0)
/* Couldn't stat the directory. Mark this by
setting the `contents' member to a nil pointer. */
dir->contents = 0;
@@ -213,6 +256,10 @@ dir_contents_file_exists_p (dir, filename)
/* The directory could not be stat'd or opened. */
return 0;
#ifdef __MSDOS__
filename = dosify (filename);
#endif
hash = 0;
if (filename != 0)
{
@@ -404,6 +451,10 @@ file_impossible_p (filename)
/* There are no files entered for this directory. */
return 0;
#ifdef __MSDOS__
p = filename = dosify (p);
#endif
for (hash = 0; *p != '\0'; ++p)
HASH (hash, *p);
hash %= DIRFILE_BUCKETS;

15
file.c
View File

@@ -385,6 +385,21 @@ snap_deps ()
export_all_variables = 1;
}
/* Set the `command_state' member of FILE and all its `also_make's. */
void
set_command_state (file, state)
struct file *file;
int state;
{
struct dep *d;
file->command_state = state;
for (d = file->also_make; d != 0; d = d->next)
d->file->command_state = state;
}
/* Print the data base of files. */
static void

1
file.h
View File

@@ -85,6 +85,7 @@ extern struct file *default_goal_file, *suffix_file, *default_file;
extern struct file *lookup_file (), *enter_file ();
extern void remove_intermediates (), snap_deps ();
extern void rename_file (), file_hash_enter ();
extern void set_command_state ();
extern time_t f_mtime ();

View File

@@ -22,6 +22,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "commands.h"
#include "job.h"
#ifdef __MSDOS__
#include <process.h>
#endif
static char *string_glob ();
/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
@@ -371,6 +375,7 @@ expand_function (o, function, text, end)
else
error_prefix = "";
#ifndef __MSDOS__
if (pipe (pipedes) < 0)
{
perror_with_name (error_prefix, "pipe");
@@ -475,6 +480,69 @@ expand_function (o, function, text, end)
free (buffer);
}
#else /* MSDOS. */
{
/* MS-DOS can't do fork, but it can do spawn. However, this
means that we don't have an opportunity to reopen stdout to
trap it. Thus, we save our own stdout onto a new descriptor
and dup a temp file's descriptor onto our stdout temporarily.
After we spawn the shell program, we dup our own stdout back
to the stdout descriptor. The buffer reading is the same as
above, except that we're now reading from a file. */
int save_stdout;
int child_stdout;
char tmp_output[FILENAME_MAX];
FILE *child_stream;
unsigned int maxlen = 200;
int cc;
char *buffer;
strcpy (tmp_output, "shXXXXXX");
mktemp (tmp_output);
child_stdout = open (tmp_output,
O_WRONLY|O_CREAT|O_TRUNC|O_TEXT, 0644);
save_stdout = dup (1);
dup2 (child_stdout, 1);
spawnvp (P_WAIT, argv[0], argv);
dup2 (save_stdout, 1);
close (child_stdout);
close (save_stdout);
child_stdout = open (tmp_output, O_RDONLY|O_TEXT, 0644);
buffer = xmalloc (maxlen);
i = 0;
do
{
if (i == maxlen)
{
maxlen += 512;
buffer = (char *) xrealloc (buffer, maxlen + 1);
}
cc = read (child_stdout, &buffer[i], maxlen - i);
if (cc > 0)
i += cc;
} while (cc > 0);
close (child_stdout);
unlink (tmp_output);
if (i > 0)
{
if (buffer[i - 1] == '\n')
buffer[--i] = '\0';
else
buffer[i] = '\0';
p = buffer;
while ((p = index (p, '\n')) != 0)
*p++ = ' ';
o = variable_buffer_output (o, buffer, i);
}
free (buffer);
}
#endif /* Not MSDOS. */
free (text);
break;

View File

@@ -1,5 +1,5 @@
/* Get the system load averages.
Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93
Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -80,9 +80,17 @@
#endif
#endif
/* Exclude all the code except the test program at the end
if the system has its own `getloadavg' function. */
if the system has its own `getloadavg' function.
The declaration of `errno' is needed by the test program
as well as the function itself, so it comes first. */
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#ifndef HAVE_GETLOADAVG
@@ -331,11 +339,6 @@
#endif
#include <stdio.h>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
/* LOAD_AVE_TYPE should only get defined if we're going to use the
nlist method. */

113
job.c
View File

@@ -28,6 +28,16 @@ static char default_path[] = ":/bin:/usr/bin";
/* Default shell to use. */
char default_shell[] = "/bin/sh";
#ifdef __MSDOS__
#include <process.h>
static int dos_pid = 123;
static int dos_status;
static char *dos_bname;
static char *dos_bename;
static int dos_batch_file;
#endif /* MSDOS. */
/* If NGROUPS_MAX == 0 then try other methods for finding a real value. */
#if defined (NGROUPS_MAX) && NGROUPS_MAX == 0
#undef NGROUPS_MAX
@@ -260,6 +270,7 @@ reap_children (block, err)
}
else if (pid == 0)
{
#ifndef __MSDOS__
/* No remote children. Check for local children. */
if (any_local)
@@ -308,6 +319,14 @@ reap_children (block, err)
exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0;
coredump = WCOREDUMP (status);
}
#else /* MSDOS. */
/* Life is very different on MSDOS. */
pid = dos_pid - 1;
status = dos_status;
exit_code = dos_status;
exit_sig = 0;
coredump = 0;
#endif /* Not MSDOS. */
}
else
/* We got a remote child. */
@@ -419,7 +438,9 @@ reap_children (block, err)
}
if (! handling_fatal_signal)
/* Notice if the target of the commands has been changed. */
/* Notice if the target of the commands has been changed.
This also propagates its values for command_state and
update_status to its also_make files. */
notice_finished_file (c->file);
if (debug_flag)
@@ -475,6 +496,13 @@ free_child (child)
}
#ifdef POSIX
#ifdef __MSDOS__
void
unblock_sigs ()
{
return;
}
#else
extern sigset_t fatal_signal_set;
void
@@ -485,6 +513,7 @@ unblock_sigs ()
sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0);
}
#endif
#endif
/* Start a job to run the commands specified in CHILD.
CHILD is updated to reflect the commands and ID of the child process. */
@@ -519,7 +548,7 @@ start_job_command (child)
if (question_flag && !(flags & COMMANDS_RECURSE))
{
child->file->update_status = 1;
child->file->command_state = cs_finished;
notice_finished_file (child->file);
return;
}
@@ -618,6 +647,8 @@ start_job_command (child)
if (child->environment == 0)
child->environment = target_environment (child->file);
#ifndef __MSDOS__
/* start_waiting_job has set CHILD->remote if we can start a remote job. */
if (child->remote)
{
@@ -667,10 +698,26 @@ start_job_command (child)
}
}
#else /* MSDOS. */
dos_status = spawnvpe (P_WAIT, argv[0], argv, child->environment);
++dead_children;
child->pid = dos_pid++;
if (dos_batch_file)
{
dos_batch_file = 0;
remove (dos_bname); /* Ignore errors. */
if (access (dos_bename, 0))
dos_status = 1;
else
dos_status = 0;
remove (dos_bename);
}
#endif /* Not MSDOS. */
/* We are the parent side. Set the state to
say the commands are running and return. */
child->file->command_state = cs_running;
set_command_state (child->file, cs_running);
/* Free the storage used by the child's argument list. */
@@ -681,7 +728,7 @@ start_job_command (child)
error:
child->file->update_status = 2;
child->file->command_state = cs_finished;
notice_finished_file (child->file);
}
/* Try to start a child running.
@@ -924,6 +971,9 @@ job_next_command (child)
static int
load_too_high ()
{
#ifdef __MSDOS__
return 1;
#else
extern int getloadavg ();
double load;
@@ -949,6 +999,7 @@ load_too_high ()
user_access ();
return load >= max_load_average;
#endif
}
/* Start jobs that are waiting for the load to be lower. */
@@ -1012,7 +1063,13 @@ search_path (file, path, program)
if (path == 0 || path[0] == '\0')
path = default_path;
if (index (file, '/') != 0)
if (
#ifdef __MSDOS__
strpbrk (file, "/\\:")
#else
index (file, '/')
#endif
!= 0)
{
strcpy (program, file);
return 1;
@@ -1049,7 +1106,7 @@ search_path (file, path, program)
int perm;
char *p;
p = index (path, ':');
p = index (path, PATH_SEPARATOR_CHAR);
if (p == 0)
p = path + strlen (path);
@@ -1062,7 +1119,7 @@ search_path (file, path, program)
bcopy (file, program + (p - path) + 1, len);
}
if (stat (program, &st) == 0
if (safe_stat (program, &st) == 0
&& S_ISREG (st.st_mode))
{
if (st.st_uid == geteuid ())
@@ -1189,12 +1246,22 @@ construct_command_argv_internal (line, restp, shell, ifs)
char *line, **restp;
char *shell, *ifs;
{
#ifdef __MSDOS__
static char sh_chars[] = "\"|<>";
static char *sh_cmds[] = { "break", "call", "cd", "chcp", "chdir", "cls",
"copy", "ctty", "date", "del", "dir", "echo",
"erase", "exit", "for", "goto", "if", "if", "md",
"mkdir", "path", "pause", "prompt", "rem", "ren",
"rename", "set", "shift", "time", "type",
"ver", "verify", "vol", ":", 0 };
#else
static char sh_chars[] = "#;\"*?[]&|<>(){}$`^";
static char *sh_cmds[] = { "cd", "eval", "exec", "exit", "login",
"logout", "set", "umask", "wait", "while", "for",
"case", "if", ":", ".", "break", "continue",
"export", "read", "readonly", "shift", "times",
"trap", "switch", 0 };
#endif
register int i;
register char *p;
register char *ap;
@@ -1241,6 +1308,7 @@ construct_command_argv_internal (line, restp, shell, ifs)
if (instring)
{
string_char:
/* Inside a string, just copy any char except a closing quote
or a backslash-newline combination. */
if (*p == '\'')
@@ -1292,7 +1360,7 @@ construct_command_argv_internal (line, restp, shell, ifs)
strcpy (p, p + 1);
if (instring)
*ap++ = *p;
goto string_char;
else
{
if (ap != new_argv[i])
@@ -1401,6 +1469,34 @@ construct_command_argv_internal (line, restp, shell, ifs)
free (new_argv);
}
#ifdef __MSDOS__
{
FILE *batch;
dos_batch_file = 1;
if (dos_bname == 0)
{
dos_bname = tempnam (".", "mk");
for (i = 0; dos_bname[i] != '\0'; ++i)
if (dos_bname[i] == '/')
dos_bname[i] = '\\';
dos_bename = (char *) xmalloc (strlen (dos_bname) + 5);
strcpy (dos_bename, dos_bname);
strcat (dos_bname, ".bat");
strcat (dos_bename, ".err");
}
batch = fopen(bename, "w"); /* Create a file. */
if (batch != NULL)
fclose (batch);
batch = fopen (dos_bname, "w");
fputs ("@echo off\n", batch);
fputs (line, batch);
fprintf (batch, "\nif errorlevel 1 del %s\n", dos_bename);
fclose (batch);
new_argv = (char **) xmalloc(2 * sizeof(char *));
new_argv[0] = strdup (bname);
new_argv[1] = 0;
}
#else /* Not MSDOS. */
{
/* SHELL may be a multi-word command. Construct a command line
"SHELL -c LINE", with all special chars in LINE escaped.
@@ -1458,6 +1554,7 @@ construct_command_argv_internal (line, restp, shell, ifs)
new_argv = construct_command_argv_internal (new_line, (char **) NULL,
(char *) 0, (char *) 0);
}
#endif /* MSDOS. */
return new_argv;
}

412
main.c
View File

@@ -304,14 +304,28 @@ static struct option long_option_aliases[] =
#define DESCRIPTION_COLUMN 30
/* List of non-switch arguments. */
/* List of goal targets. */
struct stringlist *other_args = 0;
static struct dep *goals, *lastgoal;
/* List of variables which were defined on the command line
(or, equivalently, in MAKEFLAGS). */
struct command_variable
{
struct command_variable *next;
struct variable *variable;
};
static struct command_variable *command_variables;
/* The name we were invoked with. */
char *program;
/* Our current directory before processing any -C options. */
char *directory_before_chdir;
/* Our current directory after processing all -C options. */
char *starting_directory;
@@ -387,14 +401,9 @@ main (argc, argv, envp)
extern RETSIGTYPE fatal_error_signal (), child_handler ();
register struct file *f;
register unsigned int i;
register char *cmd_defs;
register unsigned int cmd_defs_len, cmd_defs_idx;
char **p;
struct dep *goals = 0;
register struct dep *lastgoal;
struct dep *read_makefiles;
PATH_VAR (current_directory);
char *directory_before_chdir;
default_goal_file = 0;
reading_filename = 0;
@@ -464,6 +473,12 @@ main (argc, argv, envp)
else
{
program = rindex (argv[0], '/');
#ifdef __MSDOS__
if (program == 0)
program = rindex (argv[0], '\\');
if (program == 0)
program = rindex (argv[0], ':');
#endif
if (program == 0)
program = argv[0];
else
@@ -490,8 +505,8 @@ main (argc, argv, envp)
strlen (current_directory));
/* Read in variables from the environment. It is important that this be
done before `MAKE' and `MAKEOVERRIDES' are figured out so their
definitions will not be ones from the environment. */
done before $(MAKE) is are figured out so its definitions will not be
one from the environment. */
for (i = 0; envp[i] != 0; ++i)
{
@@ -531,76 +546,7 @@ main (argc, argv, envp)
if (print_version_flag)
die (0);
/* Search for command line arguments that define variables,
and do the definitions. Also save up the text of these
arguments in CMD_DEFS so we can put them into the values
of $(MAKEOVERRIDES) and $(MAKE). */
cmd_defs_len = 200;
cmd_defs = (char *) xmalloc (cmd_defs_len);
cmd_defs_idx = 0;
for (i = 1; other_args->list[i] != 0; ++i)
{
if (other_args->list[i][0] == '\0')
/* Ignore empty arguments, so they can't kill enter_file. */
continue;
/* Try a variable definition. */
if (try_variable_definition ((char *) 0, 0,
other_args->list[i], o_command))
{
/* It succeeded. The variable is already defined.
Backslash-quotify it and append it to CMD_DEFS, then clobber it
to 0 in the list so that it won't be taken for a goal target. */
register char *p = other_args->list[i];
unsigned int l = strlen (p);
if (cmd_defs_idx + (l * 2) + 1 > cmd_defs_len)
{
if (l * 2 > cmd_defs_len)
cmd_defs_len += l * 2;
else
cmd_defs_len *= 2;
cmd_defs = (char *) xrealloc (cmd_defs, cmd_defs_len);
}
while (*p != '\0')
{
if (index ("^;'\"*?[]$<>(){}|&~`\\ \t\r\n\f\v", *p) != 0)
cmd_defs[cmd_defs_idx++] = '\\';
cmd_defs[cmd_defs_idx++] = *p++;
}
cmd_defs[cmd_defs_idx++] = ' ';
}
else
{
/* It was not a variable definition, so it is a target to be made.
Enter it as a file and add it to the dep chain of goals. */
f = enter_command_line_file (other_args->list[i]);
f->cmd_target = 1;
if (goals == 0)
{
goals = (struct dep *) xmalloc (sizeof (struct dep));
lastgoal = goals;
}
else
{
lastgoal->next = (struct dep *) xmalloc (sizeof (struct dep));
lastgoal = lastgoal->next;
}
lastgoal->name = 0;
lastgoal->file = f;
}
}
if (cmd_defs_idx > 0)
{
cmd_defs[cmd_defs_idx - 1] = '\0';
(void) define_variable ("MAKEOVERRIDES", 13, cmd_defs, o_default, 0);
}
free (cmd_defs);
#ifndef __MSDOS__
/* Set the "MAKE_COMMAND" variable to the name we were invoked with.
(If it is a relative pathname with a slash, prepend our directory name
so the result will run the same program regardless of the current dir.
@@ -610,17 +556,15 @@ main (argc, argv, envp)
if (current_directory[0] != '\0'
&& argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0)
argv[0] = concat (current_directory, "/", argv[0]);
#endif
/* The extra indirection through $(MAKE_COMMAND) is done
for hysterical raisins. */
(void) define_variable ("MAKE_COMMAND", 12, argv[0], o_default, 0);
(void) define_variable ("MAKE", 4, "$(MAKE_COMMAND)", o_default, 1);
/* Append the command-line variable definitions gathered above
so sub-makes will get them as command-line definitions. */
(void) define_variable ("MAKE", 4,
"$(MAKE_COMMAND) $(MAKEOVERRIDES)", o_default, 1);
/* If there were -C flags, move ourselves about. */
if (directories != 0)
for (i = 0; directories->list[i] != 0; ++i)
{
@@ -1123,7 +1067,7 @@ main (argc, argv, envp)
/* Parsing of arguments, decoding of switches. */
static char options[sizeof (switches) / sizeof (switches[0]) * 3];
static char options[1 + sizeof (switches) / sizeof (switches[0]) * 3];
static struct option long_options[(sizeof (switches) / sizeof (switches[0])) +
(sizeof (long_option_aliases) /
sizeof (long_option_aliases[0]))];
@@ -1141,6 +1085,11 @@ init_switches ()
return;
p = options;
/* Return switch and non-switch args in order, regardless of
POSIXLY_CORRECT. Non-switch args are returned as option 1. */
*p++ = '-';
for (i = 0; switches[i].c != '\0'; ++i)
{
long_options[i].name = (switches[i].long_name == 0 ? "" :
@@ -1195,15 +1144,6 @@ decode_switches (argc, argv, env)
register struct stringlist *sl;
register int c;
if (!env)
{
other_args = (struct stringlist *) xmalloc (sizeof (struct stringlist));
other_args->max = argc + 1;
other_args->list = (char **) xmalloc ((argc + 1) * sizeof (char *));
other_args->idx = 1;
other_args->list[0] = argv[0];
}
/* getopt does most of the parsing for us.
First, get its vectors set up. */
@@ -1218,7 +1158,45 @@ decode_switches (argc, argv, env)
while ((c = getopt_long (argc, argv,
options, long_options, (int *) 0)) != EOF)
{
if (c == '?')
if (c == 1)
{
/* Non-option argument. It might be a variable definition. */
struct variable *v;
v = try_variable_definition ((char *) 0, 0, optarg, o_command);
if (v != 0)
{
/* It is indeed a variable definition. Record a pointer to
the variable for later use in define_makeflags. */
struct command_variable *cv
= (struct command_variable *) xmalloc (sizeof (*cv));
cv->variable = v;
cv->next = command_variables;
command_variables = cv;
}
else if (! env)
{
/* Not an option or variable definition; it must be a goal
target! Enter it as a file and add it to the dep chain of
goals. */
struct file *f = enter_command_line_file (optarg);
f->cmd_target = 1;
if (goals == 0)
{
goals = (struct dep *) xmalloc (sizeof (struct dep));
lastgoal = goals;
}
else
{
lastgoal->next
= (struct dep *) xmalloc (sizeof (struct dep));
lastgoal = lastgoal->next;
}
lastgoal->name = 0;
lastgoal->file = f;
}
}
else if (c == '?')
/* Bad option. We will print a usage message and die later.
But continue to parse the other options so the user can
see all he did wrong. */
@@ -1320,19 +1298,6 @@ positive integral argument",
}
}
if (!env)
{
/* Collect the remaining args in the `other_args' string list. */
while (optind < argc)
{
char *arg = argv[optind++];
if (arg[0] != '-' || arg[1] != '\0')
other_args->list[other_args->idx++] = arg;
}
other_args->list[other_args->idx] = 0;
}
if (!env && (bad || print_usage_flag))
{
/* Print a nice usage message. */
@@ -1437,7 +1402,7 @@ decode_env_switches (envar, len)
unsigned int len;
{
char *varref = (char *) alloca (2 + len + 2);
char *value, *args;
char *value;
int argc;
char **argv;
@@ -1447,7 +1412,7 @@ decode_env_switches (envar, len)
bcopy (envar, &varref[2], len);
varref[2 + len] = ')';
varref[2 + len + 1] = '\0';
value = variable_expand (varref);
value = allocated_variable_expand (varref);
/* Skip whitespace, and check for an empty value. */
value = next_token (value);
@@ -1455,18 +1420,6 @@ decode_env_switches (envar, len)
if (len == 0)
return;
/* Make a copy of the value in ARGS, where we will munge it.
If it does not begin with a dash, prepend one.
We must allocate lasting storage for this (and we never free it) because
decode_switches may save pointers into it for string-valued switches. */
args = (char *) xmalloc (1 + len + 2);
if (value[0] != '-')
args[0] = '-';
bcopy (value, value[0] == '-' ? args : &args[1], len + 1);
/* Write an extra null terminator so our loop below will
never be in danger of looking past the end of the string. */
args[(value[0] == '-' ? 0 : 1) + len + 1] = '\0';
/* Allocate a vector that is definitely big enough. */
argv = (char **) alloca ((1 + len + 1) * sizeof (char *));
@@ -1474,13 +1427,37 @@ decode_env_switches (envar, len)
Prepend a spacer word. */
argv[0] = 0;
argc = 1;
do
while ((argv[argc] = find_next_token (&value, (unsigned int *) 0)) != 0)
++argc;
if (argc == 2 && argv[1][0] != '-')
{
argv[argc++] = args;
args = end_of_token (args);
*args++ = '\0';
} while (*args != '\0');
argv[argc] = 0;
/* There is just one word in the value, and it is not a switch.
Either this is the single-word form and we should prepend a dash
before calling decode_switches, or this is the multi-word form and
there is no dash because it is a variable definition. */
struct variable *v;
v = try_variable_definition ((char *) 0, 0, argv[1], o_command);
if (v != 0)
{
/* It was indeed a variable definition, and now it has been
processed. There is nothing for decode_switches to do.
Record a pointer to the variable for later use in
define_makeflags. */
struct command_variable *cv
= (struct command_variable *) xmalloc (sizeof (*cv));
cv->variable = v;
cv->next = command_variables;
command_variables = cv;
return;
}
/* It wasn't a variable definition, so it's some switches without a
leading dash. Add one and pass it along to decode_switches. We
need permanent storage for this in case decode_switches saves
pointers into the value. */
argv[1] = concat ("-", argv[1], "");
}
/* Parse those words. */
decode_switches (argc, argv, 1);
@@ -1496,7 +1473,10 @@ define_makeflags (all, makefile)
{
register const struct command_switch *cs;
char *flagstring;
register char *p;
unsigned int words;
struct variable *v;
struct command_variable *cv;
/* We will construct a linked list of `struct flag's describing
all the flags which need to go in MAKEFLAGS. Then, once we
@@ -1609,70 +1589,119 @@ define_makeflags (all, makefile)
#undef ADD_FLAG
if (flags == 0)
/* No flags. Use a string of two nulls so [1] works below. */
flagstring = "\0";
else
if (all && command_variables != 0)
{
/* Construct the value in FLAGSTRING.
We allocate enough space for a preceding dash and trailing null. */
register char *p;
flagstring = (char *) alloca (1 + flagslen + 1);
p = flagstring;
*p++ = '-';
do
/* Now figure out how much space will be taken up
by the command-line variable definitions. */
flagslen += 4; /* For the possible " -- ". */
for (cv = command_variables; cv != 0; cv = cv->next)
{
/* Add the flag letter or name to the string. */
if (!isalnum (flags->cs->c))
{
*p++ = '-';
strcpy (p, flags->cs->long_name);
p += strlen (p);
}
else
*p++ = flags->cs->c;
if (flags->arg != 0)
{
/* A flag that takes an optional argument which in this case
is omitted is specified by ARG being "" and ARGLEN being 0.
We must distinguish because a following flag appended without
an intervening " -" is considered the arg for the first. */
if (flags->arglen > 0)
{
/* Add its argument too. */
*p++ = !isalnum (flags->cs->c) ? '=' : ' ';
bcopy (flags->arg, p, flags->arglen);
p += flags->arglen;
}
/* Write a following space and dash, for the next flag. */
*p++ = ' ';
*p++ = '-';
}
else if (!isalnum (flags->cs->c))
{
/* Long options must each go in their own word,
so we write the following space and dash. */
*p++ = ' ';
*p++ = '-';
}
flags = flags->next;
} while (flags != 0);
if (p[-1] == '-')
/* Kill the final space and dash. */
p -= 2;
/* Terminate the string. */
*p = '\0';
v = cv->variable;
flagslen += strlen (v->name);
if (! v->recursive)
++flagslen;
++flagslen;
flagslen += strlen (v->value);
}
}
/* Construct the value in FLAGSTRING.
We allocate enough space for a preceding dash and trailing null. */
flagstring = (char *) alloca (1 + flagslen + 1);
p = flagstring;
words = 1;
*p++ = '-';
while (flags != 0)
{
/* Add the flag letter or name to the string. */
if (!isalnum (flags->cs->c))
{
*p++ = '-';
strcpy (p, flags->cs->long_name);
p += strlen (p);
}
else
*p++ = flags->cs->c;
if (flags->arg != 0)
{
/* A flag that takes an optional argument which in this case
is omitted is specified by ARG being "" and ARGLEN being 0.
We must distinguish because a following flag appended without
an intervening " -" is considered the arg for the first. */
if (flags->arglen > 0)
{
/* Add its argument too. */
*p++ = !isalnum (flags->cs->c) ? '=' : ' ';
bcopy (flags->arg, p, flags->arglen);
p += flags->arglen;
}
++words;
/* Write a following space and dash, for the next flag. */
*p++ = ' ';
*p++ = '-';
}
else if (!isalnum (flags->cs->c))
{
++words;
/* Long options must each go in their own word,
so we write the following space and dash. */
*p++ = ' ';
*p++ = '-';
}
flags = flags->next;
}
if (all && command_variables != 0)
{
/* Now write all the command-line variable definitions. */
if (p == &flagstring[1])
/* No flags written, so elide the leading dash already written. */
p = flagstring;
else
{
/* Separate the variables from the switches with a "--" arg. */
if (p[-1] != '-')
{
/* We did not already write a trailing " -". */
*p++ = ' ';
*p++ = '-';
}
/* There is a trailing " -"; fill it out to " -- ". */
*p++ = '-';
*p++ = ' ';
}
for (cv = command_variables; cv != 0; cv = cv->next)
{
/* XXX Quoting? */
unsigned int len;
v = cv->variable;
len = strlen (v->name);
bcopy (v->name, p, len);
p += len;
if (! v->recursive)
*p++ = ':';
len = strlen (v->value);
bcopy (v->value, p, len);
p += len;
*p++ = ' ';
++words;
}
--p; /* Kill the final space. */
}
else if (p[-1] == '-')
/* Kill the final space and dash. */
p -= 2;
/* Terminate the string. */
*p = '\0';
v = define_variable ("MAKEFLAGS", 9,
/* On Sun, the value of MFLAGS starts with a `-' but
the value of MAKEFLAGS lacks the `-'.
Be compatible with this unless FLAGSTRING starts
with a long option `--foo', since removing the
first dash would result in the bogus `-foo'. */
flagstring[1] == '-' ? flagstring : &flagstring[1],
/* If there is just a single word of switches,
omit the leading dash unless it is a single
long option with two leading dashes. */
&flagstring[(words == 1 && command_variables == 0
&& flagstring[1] != '-')
? 1 : 0],
/* This used to use o_env, but that lost when a
makefile defined MAKEFLAGS. Makefiles set
MAKEFLAGS to add switches, but we still want
@@ -1755,6 +1784,13 @@ die (status)
dying = 1;
/* Try to move back to the original directory. This is essential on
MS-DOS (where there is really only one process), and on Unix it
puts core files in the original directory instead of the -C
directory. */
if (directory_before_chdir != 0)
chdir (directory_before_chdir);
if (print_version_flag)
print_version ();

View File

@@ -32,6 +32,20 @@ to avoid trouble on systems where the @code{SHELL} variable might be
inherited from the environment. (This is never a problem with GNU
@code{make}.)
Different @code{make} programs have incompatible suffix lists and
implicit rules, and this sometimes creates confusion or misbehavior. So
it is a good idea to set the suffix list explicitly using only the
suffixes you need in the particular Makefile, like this:
@example
.SUFFIXES:
.SUFFIXES: .c .o
@end example
@noindent
The first line clears out the suffix list, the second introduces all
suffixes which may be subject to implicit rules in this Makefile.
Don't assume that @file{.} is in the path for command execution. When
you need to run programs that are a part of your package during the
make, please make sure that it uses @file{./} if the program is built as
@@ -43,33 +57,34 @@ The distinction between @file{./} and @file{$(srcdir)/} is important
when using the @samp{--srcdir} option to @file{configure}. A rule of
the form:
@example
@smallexample
foo.1 : foo.man sedscript
sed -e sedscript foo.man > foo.1
@end example
@end smallexample
@noindent
will fail when the current directory is not the source directory,
because @file{foo.man} and @file{sedscript} are not in the current
directory.
Relying on @samp{VPATH} to find the source file will work in the case
where there is a single dependency file, since the @file{make} automatic
variable @samp{$<} will represent the source file wherever it is. A
makefile target like
When using GNU @code{make}, relying on @samp{VPATH} to find the source
file will work in the case where there is a single dependency file,
since the @file{make} automatic variable @samp{$<} will represent the
source file wherever it is. (Many versions of @code{make} set @samp{$<}
only in implicit rules.) A makefile target like
@example
@smallexample
foo.o : bar.c
$(CC) $(CFLAGS) -I. -I$(srcdir) -c bar.c -o foo.o
@end example
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
@end smallexample
@noindent
should instead be written as
@example
@smallexample
foo.o : bar.c
$(CC) $(CFLAGS) $< -o $@@
@end example
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@@
@end smallexample
@noindent
in order to allow @samp{VPATH} to work correctly. When the target has
@@ -77,10 +92,10 @@ multiple dependencies, using an explicit @samp{$(srcdir)} is the easiest
way to make the rule work well. For example, the target above for
@file{foo.1} is best written as:
@example
@smallexample
foo.1 : foo.man sedscript
sed -s $(srcdir)/sedscript $(srcdir)/foo.man > foo.1
@end example
sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@@
@end smallexample
@node Utilities in Makefiles
@section Utilities in Makefiles
@@ -107,12 +122,21 @@ user can substitute alternatives. Here are some of the programs we
mean:
@example
ar bison cc flex install ld lex make ranlib yacc
ar bison cc flex install ld lex
make makeinfo ranlib texi2dvi yacc
@end example
When you use @code{ranlib}, you should test whether it exists, and run
it only if it exists, so that the distribution will work on systems that
don't have @code{ranlib}.
Use the following @code{make} variables:
@example
$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LEX)
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
@end example
When you use @code{ranlib}, you should make sure nothing bad happens if
the system does not have @code{ranlib}. Arrange to ignore an error
from that command, and print a message before the command to tell the
user that failure of the @code{ranlib} command does not mean a problem.
If you use symbolic links, you should implement a fallback for systems
that don't have symbolic links.
@@ -129,29 +153,62 @@ All GNU programs should have the following targets in their Makefiles:
@table @samp
@item all
Compile the entire program. This should be the default target. This
target need not rebuild any documentation files; info files should
target need not rebuild any documentation files; Info files should
normally be included in the distribution, and DVI files should be made
only when explicitly asked for.
@item install
Compile the program and copy the executables, libraries, and so on to
the file names where they should reside for actual use. If there is a
simple test to verify that a program is properly installed then run that
test.
simple test to verify that a program is properly installed, this target
should run that test.
The commands should create all the directories in which files are to be
installed, if they don't already exist. This includes the directories
specified as the values of the variables @code{prefix} and
@code{exec_prefix}, as well as all subdirectories that are needed.
One way to do this is by means of an @code{installdirs} target
as described below.
Use @samp{-} before any command for installing a man page, so that
@code{make} will ignore any errors. This is in case there are systems
that don't have the Unix man page documentation system installed.
In the future, when we have a standard way of installing info files,
@samp{install} targets will be the proper place to do so.
The way to install Info files is to copy them into @file{$(infodir)}
with @code{$(INSTALL_DATA)} (@pxref{Command Variables}), and then run
the @code{install-info} program if it is present. @code{install-info}
is a script that edits the Info @file{dir} file to add or update the
menu entry for the given Info file; it will be part of the Texinfo package.
Here is a sample rule to install an Info file:
@comment This example has been carefully formatted for the Make manual.
@comment Please do not reformat it without talking to roland@gnu.ai.mit.edu.
@smallexample
$(infodir)/foo.info: foo.info
# There may be a newer info file in . than in srcdir.
-if test -f foo.info; then d=.; \
else d=$(srcdir); fi; \
$(INSTALL_DATA) $$d/foo.info $@@; \
# Run install-info only if it exists.
# Use `if' instead of just prepending `-' to the
# line so we notice real errors from install-info.
# We use `$(SHELL) -c' because some shells do not
# fail gracefully when there is an unknown command.
if $(SHELL) -c 'install-info --version' \
>/dev/null 2>&1; then \
install-info --infodir=$(infodir) $$d/foo.info; \
else true; fi
@end smallexample
@item uninstall
Delete all the installed files that the @samp{install} target would
create (but not the noninstalled files such as @samp{make all} would
create).
@comment The gratuitous blank line here is to make the table look better
@comment in the printed Make manual. Please leave it in.
@item clean
Delete all files from the current directory that are normally created by
building the program. Don't delete the files that record the
configuration. Also preserve files that could be made by building, but
@@ -174,8 +231,8 @@ is rarely necessary and takes a lot of time.
@item realclean
Delete everything from the current directory that can be reconstructed
with this Makefile. This typically includes everything deleted by
distclean, plus more: C source files produced by Bison, tags tables,
info files, and so on.
@code{distclean}, plus more: C source files produced by Bison, tags tables,
Info files, and so on.
One exception, however: @samp{make realclean} should not delete
@file{configure} even if @file{configure} can be remade using a rule in
@@ -187,34 +244,35 @@ and then begin to build the program.
Update a tags table for this program.
@item info
Generate any info files needed. The best way to write the rules is as
Generate any Info files needed. The best way to write the rules is as
follows:
@example
info: foo.info
@smallexample
info: foo.info
foo.info: $(srcdir)/foo.texi $(srcdir)/chap1.texi $(srcdir)/chap2.texi
foo.info: foo.texi chap1.texi chap2.texi
$(MAKEINFO) $(srcdir)/foo.texi
@end example
@end smallexample
@noindent
You must define the variable @code{MAKEINFO} in the Makefile.
It should run the Makeinfo program, which is part of the Texinfo2 distribution.
You must define the variable @code{MAKEINFO} in the Makefile. It should
run the @code{makeinfo} program, which is part of the Texinfo
distribution.
@item dvi
Generate DVI files for all TeXinfo documentation.
For example:
@example
@smallexample
dvi: foo.dvi
foo.dvi: $(srcdir)/foo.texi $(srcdir)/chap1.texi $(srcdir)/chap2.texi
foo.dvi: foo.texi chap1.texi chap2.texi
$(TEXI2DVI) $(srcdir)/foo.texi
@end example
@end smallexample
@noindent
You must define the variable @code{TEXI2DVI} in the Makefile. It should
run the program @code{texi2dvi}, which is part of the Texinfo2
run the program @code{texi2dvi}, which is part of the Texinfo
distribution. Alternatively, write just the dependencies, and allow GNU
Make to provide the command.
@@ -243,6 +301,34 @@ the self-tests so that they work when the program is built but not
installed.
@end table
The following targets are suggested as conventional names, for programs
in which they are useful.
@table @code
@item installcheck
Perform installation tests (if any). The user must build and install
the program before running the tests. You should not assume that
@file{$(bindir)} is in the search path.
@item installdirs
It's useful to add a target named @samp{installdirs} to create the
directories where files are installed, and their parent directories.
There is a script called @file{mkinstalldirs} which is convenient for
this; find it in the Texinfo package.@c It's in /gd/gnu/lib/mkinstalldirs.
You can use a rule like this:
@comment This has been carefully formatted to look decent in the Make manual.
@comment Please be sure not to make it extend any further to the right.--roland
@smallexample
# Make sure all installation directories (e.g. $(bindir))
# actually exist by making them if necessary.
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(bindir) $(datadir) \
$(libdir) $(infodir) \
$(mandir)
@end smallexample
@end table
@node Command Variables
@section Variables for Specifying Commands
@@ -274,12 +360,12 @@ Instead, arrange to pass the necessary options to the C compiler
independently of @code{CFLAGS}, by writing them explicitly in the
compilation commands or by defining an implicit rule, like this:
@example
@smallexample
CFLAGS = -g
ALL_CFLAGS = $(CFLAGS) -I.
ALL_CFLAGS = -I. $(CFLAGS)
.c.o:
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $<
@end example
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
@end smallexample
Do include the @samp{-g} option in @code{CFLAGS}, because that is not
@emph{required} for proper compilation. You can consider it a default
@@ -287,11 +373,15 @@ that is only recommended. If the package is set up so that it is
compiled with GCC by default, then you might as well include @samp{-O}
in the default value of @code{CFLAGS} as well.
Put @code{CFLAGS} last in the compilation command, after other variables
containing compiler options, so the user can use @code{CFLAGS} to
override the others.
Every Makefile should define the variable @code{INSTALL}, which is the
basic command for installing a file into the system.
Every Makefile should also define variables @code{INSTALL_PROGRAM} and
@code{INSTALL_DATA}. (The default for each of these should be
Every Makefile should also define the variables @code{INSTALL_PROGRAM}
and @code{INSTALL_DATA}. (The default for each of these should be
@code{$(INSTALL)}.) Then it should use those variables as the commands
for actual installation, for executables and nonexecutables
respectively. Use these variables as follows:
@@ -311,7 +401,11 @@ installed.
Installation directories should always be named by variables, so it is
easy to install in a nonstandard place. The standard names for these
variables are:
variables are as follows.
These two variables set the root for the installation. All the other
installation directories should be subdirectories of one of these two,
and nothing should be directly installed into these two directories.
@table @samp
@item prefix
@@ -320,39 +414,107 @@ below. The default value of @code{prefix} should be @file{/usr/local}
(at least for now).
@item exec_prefix
A prefix used in constructing the default values of the some of the
A prefix used in constructing the default values of some of the
variables listed below. The default value of @code{exec_prefix} should
be @code{$(prefix)}.
Generally, @code{$(exec_prefix)} is used for directories that contain
machine-specific files (such as executables and subroutine libraries),
while @code{$(prefix)} is used directly for other directories.
@end table
Executable programs are installed in one of the following directories.
@table @samp
@item bindir
The directory for installing executable programs that users can run.
This should normally be @file{/usr/local/bin}, but write it as
@file{$(exec_prefix)/bin}.
@item sbindir
The directory for installing executable programs that can be run from
the shell, but are only generally useful to system administrators. This
should normally be @file{/usr/local/sbin}, but write it as
@file{$(exec_prefix)/sbin}.
@item libexecdir
@comment This paragraph adjusted to avoid overfull hbox --roland 5jul94
The directory for installing executable programs to be run by other
programs rather than by users. This directory should normally be
@file{/usr/local/libexec}, but write it as @file{$(exec_prefix)/libexec}.
@end table
Data files used by the program during its execution are divided into
categories in two ways.
@itemize @bullet
@item
Some files are normally modified by programs; others are never normally
modified (though users may edit some of these).
@item
Some files are architecture-independent and can be shared by all
machines at a site; some are architecture-dependent and can be shared
only by machines of the same kind and operating system; others may never
be shared between two machines.
@end itemize
This makes for six different possibilities. However, we want to
discourage the use of architecture-dependent files, aside from of object
files and libraries. It is much cleaner to make other data files
architecture-independent, and it is generally not hard.
Therefore, here are the variables makefiles should use to specify
directories:
@table @samp
@item datadir
The directory for installing read-only architecture independent data
files. This should normally be @file{/usr/local/share}, but write it as
@file{$(prefix)/share}. As a special exception, see @file{$(infodir)}
and @file{$(includedir)} below.
@item sysconfdir
The directory for installing read-only data files that pertain to a
single machine--that is to say, files for configuring a host. Mailer
and network configuration files, @file{/etc/passwd}, and so forth belong
here. All the files in this directory should be ordinary ASCII text
files. This directory should normally be @file{/usr/local/etc}, but
write it as @file{$(prefix)/etc}.
@c rewritten to avoid overfull hbox --tower
Do not install executables
@c here
in this directory (they probably
belong in @file{$(libexecdir)} or @file{$(sbindir))}. Also do not
install files that are modified in the normal course of their use
(programs whose purpose is to change the configuration of the system
excluded). Those probably belong in @file{$(localstatedir)}.
@item sharedstatedir
The directory for installing architecture-independent data files which
the programs modify while they run. This should normally be
@file{/usr/local/com}, but write it as @file{$(prefix)/com}.
@item localstatedir
The directory for installing data files which the programs modify while
they run, and that pertain to one specific machine. Users should never
need to modify files in this directory to configure the package's
operation; put such configuration information in separate files that go
in @file{datadir} or @file{$(sysconfdir)}. @file{$(localstatedir)}
should normally be @file{/usr/local/var}, but write it as
@file{$(prefix)/var}.
@item libdir
The directory for installing executable files to be run by the program
rather than by users. Object files and libraries of object code should
also go in this directory. The idea is that this directory is used for
files that pertain to a specific machine architecture, but need not be
in the path for commands. The value of @code{libdir} should normally be
The directory for object files and libraries of object code. Do not
install executables here, they probably belong in @file{$(libexecdir)}
instead. The value of @code{libdir} should normally be
@file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}.
@item datadir
The directory for installing read-only data files which the programs
refer to while they run. This directory is used for files which are
independent of the type of machine being used. This should normally be
@file{/usr/local/lib}, but write it as @file{$(prefix)/lib}.
@item statedir
The directory for installing data files which the programs modify while
they run. These files should be independent of the type of machine
being used, and it should be possible to share them among machines at a
network installation. This should normally be @file{/usr/local/lib},
but write it as @file{$(prefix)/lib}.
@item infodir
The directory for installing the Info files for this package. By
default, it should be @file{/usr/local/info}, but it should be written
as @file{$(prefix)/info}.
@item includedir
@c rewritten to avoid overfull hbox --roland
@@ -384,14 +546,19 @@ file in the @code{oldincludedir} directory if either (1) there is no
@file{foo.h} there or (2) the @file{foo.h} that exists came from the Foo
package.
The way to tell whether @file{foo.h} came from the Foo package is to put
a magic string in the file---part of a comment---and grep for that
string.
To tell whether @file{foo.h} came from the Foo package, put a magic
string in the file---part of a comment---and grep for that string.
@end table
Unix-style man pages are installed in one of the following:
@table @samp
@item mandir
The directory for installing the man pages (if any) for this package.
It should include the suffix for the proper section of the
manual---usually @samp{1} for a utility.
manual---usually @samp{1} for a utility. It will normally be
@file{/usr/local/man/man1}, but you should write it as
@file{$(prefix)/man/man1}.
@item man1dir
The directory for installing section 1 man pages.
@@ -408,13 +575,20 @@ application only.}
@item manext
The file name extension for the installed man page. This should contain
a period followed by the appropriate digit.
a period followed by the appropriate digit; it should normally be @samp{.1}.
@item infodir
The directory for installing the info files for this package. By
default, it should be @file{/usr/local/info}, but it should be written
as @file{$(prefix)/info}.
@item man1ext
The file name extension for installed section 1 man pages.
@item man2ext
The file name extension for installed section 2 man pages.
@item @dots{}
Use these names instead of @samp{manext} if the package needs to install man
pages in more than one section of the manual.
@end table
And finally, you should set the following variable:
@table @samp
@item srcdir
The directory for the sources being compiled. The value of this
variable is normally inserted by the @code{configure} shell script.
@@ -422,7 +596,7 @@ variable is normally inserted by the @code{configure} shell script.
For example:
@example
@smallexample
@c I have changed some of the comments here slightly to fix an overfull
@c hbox, so the make manual can format correctly. --roland
# Common prefix for installation directories.
@@ -432,10 +606,10 @@ exec_prefix = $(prefix)
# Where to put the executable for the command `gcc'.
bindir = $(exec_prefix)/bin
# Where to put the directories used by the compiler.
libdir = $(exec_prefix)/lib
libexecdir = $(exec_prefix)/libexec
# Where to put the Info files.
infodir = $(prefix)/info
@end example
@end smallexample
If your program installs a large number of files into one of the
standard user-specified directories, it might be useful to group them

21
make.h
View File

@@ -67,7 +67,7 @@ extern int errno;
#endif
/* Some systems define _POSIX_VERSION but are not really POSIX.1. */
#if (defined (butterfly) || \
#if (defined (butterfly) || defined (__arm) || \
(defined (__mips) && defined (_SYSTYPE_SVR3)) || \
(defined (sequent) && defined (i386)))
#undef POSIX
@@ -252,6 +252,12 @@ extern char *alloca ();
#define ENUM_BITFIELD(bits)
#endif
#ifdef __MSDOS__
#define PATH_SEPARATOR_CHAR ';'
#else
#define PATH_SEPARATOR_CHAR ':'
#endif
extern void die ();
extern void message (), fatal (), error ();
extern void makefile_error (), makefile_fatal ();
@@ -299,17 +305,12 @@ extern void user_access (), make_access (), child_access ();
#include <vfork.h>
#endif
#if !defined (__GNU_LIBRARY__) && !defined (POSIX)
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
because such systems often declare the in header files anyway. */
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION)
#ifdef HAVE_SIGSETMASK
extern int sigsetmask ();
extern int sigblock ();
#endif
extern int kill ();
extern int atoi ();
extern long int atol ();
extern int unlink (), stat (), fstat ();
extern int pipe (), close (), read (), write (), open ();
extern long int lseek ();
#endif /* Not GNU C library or POSIX. */

View File

@@ -8,10 +8,11 @@
@c FSF publishers: format makebook.texi instead of using this file directly.
@set RCSID $Id$
@set EDITION 0.45
@set VERSION 3.71 Beta
@set UPDATED 11 May 1994
@set UPDATE-MONTH May 1994
@set EDITION 0.46
@set VERSION 3.72 Beta
@set UPDATED 5 July 1994
@set UPDATE-MONTH July 1994
@set ISBN 1-882114-50-7
@c finalout
@@ -71,7 +72,7 @@ Published by the Free Software Foundation @*
675 Massachusetts Avenue, @*
Cambridge, MA 02139 USA @*
Printed copies are available for $20 each. @*
ISBN 1-882114-16-7 @*
ISBN @value{ISBN} @*
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -2581,7 +2582,8 @@ called @file{@var{name}.d} from a C source file called @file{@var{name}.c}:
@example
@group
%.d: %.c
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< | sed '\''s/$*.o/& $@@/g'\'' > $@@'
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \
| sed '\''s/$*.o/& $@@/g'\'' > $@@'
@end group
@end example
@@ -5581,7 +5583,9 @@ dependencies of goals, or dependencies of dependencies of goals, etc.
By default, the goal is the first target in the makefile (not counting
targets that start with a period). Therefore, makefiles are usually
written so that the first target is for compiling the entire program or
programs they describe.
programs they describe. If the first rule in the makefile has several
targets, only the first target in the rule becomes the default goal, not
the whole list.
You can specify a different goal or goals with arguments to @code{make}.
Use the name of the goal as an argument. If you specify several goals,
@@ -7620,6 +7624,7 @@ main use is as subroutine libraries for linking.
@menu
* Archive Members:: Archive members as targets.
* Archive Update:: The implicit rule for archive member targets.
* Archive Pitfalls:: Dangers to watch out for when using archives.
* Archive Suffix Rules:: You can write a special kind of suffix rule
for updating archives.
@end menu
@@ -7676,7 +7681,7 @@ example, @w{@samp{foolib(*.o)}} expands to all existing members of the
@file{foolib} archive whose names end in @samp{.o}; perhaps
@samp{@w{foolib(hack.o)} @w{foolib(kludge.o)}}.
@node Archive Update, Archive Suffix Rules, Archive Members, Archives
@node Archive Update
@section Implicit Rule for Archive Member Targets
Recall that a target that looks like @file{@var{a}(@var{m})} stands for the
@@ -7766,7 +7771,24 @@ files into the archive, as described in the preceding section.
This is not necessary when using the GNU @code{ar} program, which
updates the @file{__.SYMDEF} member automatically.
@node Archive Suffix Rules, , Archive Update, Archives
@node Archive Pitfalls
@section Dangers When Using Archives
@cindex archive, and parallel execution
@cindex parallel execution, and archive update
@cindex archive, and @code{-j}
@cindex @code{-j}, and archive update
It is important to be careful when using parallel execution (the
@code{-j} switch; @pxref{Parallel, ,Parallel Execution}) and archives.
If multiple @code{ar} commands run at the same time on the same archive
file, they will not know about each other and can corrupt the file.
Possibly a future version of @code{make} will provide a mechanism to
circumvent this problem by serializing all commands that operate on the
same archive file. But for the time being, you must either write your
makefiles to avoid this problem in some other way, or not use @code{-j}.
@node Archive Suffix Rules, , Archive Pitfalls, Archives
@section Suffix Rules for Archive Files
@cindex suffix rule, for archive
@cindex archive, suffix rule for

24
misc.c
View File

@@ -461,12 +461,8 @@ dep_name (dep)
setregid functions, but they don't work as in BSD and only the POSIX.1
way works. */
#ifndef HAVE_SETREUID
#undef HAVE_SETREUID
#endif
#ifndef HAVE_SETREGID
#undef HAVE_SETREGID
#endif
#else /* Not POSIX. */
@@ -720,3 +716,23 @@ get_path_max ()
return value;
}
#endif
/* On some systems, stat can return EINTR. */
int
safe_stat (name, buf)
char *name;
struct stat *buf;
{
int ret;
#ifdef EINTR
do
#endif
ret = stat (name, buf);
#ifdef EINTR
while (ret < 0 && errno == EINTR);
#endif
return ret;
}

103
read.c
View File

@@ -240,6 +240,7 @@ read_makefile (filename, flags)
char *p2;
int ignoring = 0, in_ignored_define = 0;
int no_targets = 0; /* Set when reading a rule without targets. */
char *passed_filename = filename;
struct nameseq *filenames = 0;
struct dep *deps;
@@ -288,7 +289,6 @@ read_makefile (filename, flags)
if (!(flags & RM_NO_TILDE) && filename[0] == '~')
{
char *expanded = tilde_expand (filename);
/* This is a possible memory leak, but I don't care. */
if (expanded != 0)
filename = expanded;
}
@@ -330,6 +330,8 @@ read_makefile (filename, flags)
if (flags & RM_DONTCARE)
deps->file->dontcare = 1;
}
if (filename != passed_filename)
free (filename);
filename = deps->file->name;
deps->changed = flags;
deps = 0;
@@ -360,6 +362,47 @@ read_makefile (filename, flags)
lineno += nlines;
nlines = readline (&lb, infile, filename, lineno);
/* Check for a shell command line first.
If it is not one, we can stop treating tab specially. */
if (lb.buffer[0] == '\t')
{
/* This line is a probably shell command. */
unsigned int len;
if (no_targets)
/* Ignore the commands in a rule with no targets. */
continue;
/* If there is no preceding rule line, don't treat this line
as a command, even though it begins with a tab character.
SunOS 4 make appears to behave this way. */
if (filenames != 0)
{
if (ignoring)
/* Yep, this is a shell command, and we don't care. */
continue;
/* Append this command line to the line being accumulated. */
p = lb.buffer;
if (commands_idx == 0)
commands_started = lineno;
len = strlen (p);
if (len + 1 + commands_idx > commands_len)
{
commands_len = (len + 1 + commands_idx) * 2;
commands = (char *) xrealloc (commands, commands_len);
}
bcopy (p, &commands[commands_idx], len);
commands_idx += len;
commands[commands_idx++] = '\n';
continue;
}
}
/* This line is not a shell command line. Don't worry about tabs. */
if (collapsed_length < lb.size)
{
collapsed_length = lb.size;
@@ -372,17 +415,20 @@ read_makefile (filename, flags)
collapse_continuations (collapsed);
remove_comments (collapsed);
p = collapsed;
while (isspace (*p) && *p != '\t')
++p;
/* We cannot consider a line containing just a tab to be empty
because it might constitute an empty command for a target. */
if (*p == '\0' && lb.buffer[0] != '\t')
continue;
/* strncmp is first to avoid dereferencing out into space. */
#define word1eq(s, l) (!strncmp (s, p, l) \
&& (p[l] == '\0' || isblank (p[l])))
p = collapsed;
while (isspace (*p))
++p;
if (*p == '\0')
/* This line is completely empty. */
continue;
/* We must first check for conditional and `define' directives before
ignoring anything, since they control what we will do with
following lines. */
if (!in_ignored_define
&& (word1eq ("ifdef", 5) || word1eq ("ifndef", 6)
|| word1eq ("ifeq", 4) || word1eq ("ifneq", 5)
@@ -458,40 +504,7 @@ read_makefile (filename, flags)
/* Ignore the line. We continue here so conditionals
can appear in the middle of a rule. */
continue;
else if (lb.buffer[0] == '\t')
{
/* This line is a shell command. */
unsigned int len;
if (no_targets)
/* Ignore the commands in a rule with no targets. */
continue;
/* If there is no preceding rule line, don't treat this line
as a command, even though it begins with a tab character.
SunOS 4 make appears to behave this way. */
if (filenames != 0)
{
/* Append this command line to the line being accumulated. */
p = lb.buffer;
if (commands_idx == 0)
commands_started = lineno;
len = strlen (p);
if (len + 1 + commands_idx > commands_len)
{
commands_len = (len + 1 + commands_idx) * 2;
commands = (char *) xrealloc (commands, commands_len);
}
bcopy (p, &commands[commands_idx], len);
commands_idx += len;
commands[commands_idx++] = '\n';
continue;
}
}
if (word1eq ("export", 6))
else if (word1eq ("export", 6))
{
struct variable *v;
p2 = next_token (p + 6);
@@ -1788,7 +1801,7 @@ construct_include_path (arg_dirs)
dir = expanded;
}
if (stat (dir, &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
if (safe_stat (dir, &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
{
if (idx == max - 1)
{
@@ -1805,7 +1818,7 @@ construct_include_path (arg_dirs)
/* Now add at the end the standard default dirs. */
for (i = 0; default_include_directories[i] != 0; ++i)
if (stat (default_include_directories[i], &stbuf) == 0
if (safe_stat (default_include_directories[i], &stbuf) == 0
&& S_ISDIR (stbuf.st_mode))
dirs[idx++] = default_include_directories[i];

View File

@@ -468,7 +468,7 @@ update_file_1 (file, depth)
if (running)
{
file->command_state = cs_deps_running;
set_command_state (file, cs_deps_running);
--depth;
DEBUGPR ("The dependencies of `%s' are being made.\n");
return 0;
@@ -478,9 +478,8 @@ update_file_1 (file, depth)
if (dep_status != 0)
{
file->command_state = cs_finished;
file->update_status = dep_status;
file->updated = 1;
notice_finished_file (file);
depth--;
@@ -493,7 +492,7 @@ update_file_1 (file, depth)
return dep_status;
}
file->command_state = cs_not_started;
set_command_state (file, cs_not_started);
/* Now record which dependencies are more
recent than this file, so we can define $?. */
@@ -549,9 +548,8 @@ update_file_1 (file, depth)
if (!must_make)
{
DEBUGPR ("No need to remake target `%s'.\n");
file->command_state = cs_finished;
file->update_status = 0;
file->updated = 1;
notice_finished_file (file);
return 0;
}
@@ -596,6 +594,7 @@ notice_finished_file (file)
register struct file *file;
{
struct dep *d;
int ran = file->command_state == cs_running;
file->command_state = cs_finished;
file->updated = 1;
@@ -629,7 +628,7 @@ notice_finished_file (file)
}
}
if (!file->phony)
if (ran && !file->phony)
{
struct file *f;
@@ -656,7 +655,7 @@ notice_finished_file (file)
d->file->updated = 1;
d->file->update_status = file->update_status;
if (!d->file->phony)
if (ran && !d->file->phony)
/* Fetch the new modification time.
We do this instead of just invalidating the cached time
so that a vpath_search can happen. Otherwise, it would
@@ -738,7 +737,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
/* Record that some of FILE's dependencies are still being made.
This tells the upper levels to wait on processing it until
the commands are finished. */
file->command_state = cs_deps_running;
set_command_state (file, cs_deps_running);
lastd = d;
d = d->next;
@@ -777,8 +776,16 @@ touch_file (file)
{
struct stat statbuf;
char buf;
int status;
if (fstat (fd, &statbuf) < 0)
#ifdef EINTR
do
#endif
status = fstat (fd, &statbuf);
#ifdef EINTR
while (status < 0 && errno == EINTR);
#endif
if (status < 0)
TOUCH_ERROR ("touch: fstat: ");
/* Rewrite character 0 same as it already is. */
if (read (fd, &buf, 1) < 0)
@@ -971,7 +978,7 @@ name_mtime (name)
{
struct stat st;
if (stat (name, &st) < 0)
if (safe_stat (name, &st) < 0)
return (time_t) -1;
return (time_t) st.st_mtime;

17
vpath.c
View File

@@ -1,5 +1,5 @@
/* Implementation of pattern-matching file search paths for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify
@@ -177,7 +177,7 @@ construct_vpath_list (pattern, dirpath)
maxelem = 2;
p = dirpath;
while (*p != '\0')
if (*p++ == ':' || isblank (*p))
if (*p++ == PATH_SEPARATOR_CHAR || isblank (*p))
++maxelem;
vpath = (char **) xmalloc (maxelem * sizeof (char *));
@@ -185,7 +185,7 @@ construct_vpath_list (pattern, dirpath)
/* Skip over any initial colons and blanks. */
p = dirpath;
while (*p == ':' || isblank (*p))
while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
++p;
elem = 0;
@@ -196,7 +196,7 @@ construct_vpath_list (pattern, dirpath)
/* Find the end of this entry. */
v = p;
while (*p != '\0' && *p != ':' && !isblank (*p))
while (*p != '\0' && *p != PATH_SEPARATOR_CHAR && !isblank (*p))
++p;
len = p - v;
@@ -225,7 +225,7 @@ construct_vpath_list (pattern, dirpath)
}
/* Skip over colons and blanks between entries. */
while (*p == ':' || isblank (*p))
while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
++p;
}
@@ -419,7 +419,7 @@ selective_vpath_search (path, file, mtime_ptr)
*n = '/';
if (!exists_in_cache /* Makefile-mentioned file need not exist. */
|| stat (name, &st) == 0) /* Does it really exist? */
|| safe_stat (name, &st) == 0) /* Does it really exist? */
{
/* We have found a file.
Store the name we found into *FILE for the caller. */
@@ -461,7 +461,7 @@ print_vpath_data_base ()
for (i = 0; v->searchpath[i] != 0; ++i)
printf ("%s%c", v->searchpath[i],
v->searchpath[i + 1] == 0 ? '\n' : ':');
v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
}
if (vpaths == 0)
@@ -479,6 +479,7 @@ print_vpath_data_base ()
fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout);
for (i = 0; path[i] != 0; ++i)
printf ("%s%c", path[i], path[i + 1] == 0 ? '\n' : ':');
printf ("%s%c", path[i],
path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
}
}