mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2025-01-11 00:41:30 +01:00
Merge in NetBSD's changes to make(1). Changes include:
- Add the .PHONY, .PARALLEL, and .WAIT directives - Added the -B and -m commandline flags - misc. man page cleanups - numerous job-related enhancements - removed unused header file (bit.h) - add util.c for functions not found in other envs. - and a few coordinated whitespace changes Special thanks to Christos Zoulas <christos@netbsd.org> for help in the merge. A 'diff -ur' between Net and FreeBSD now only contains sccsid-related diffs. :) Obtained from: NetBSD, christos@netbsd.org, and me
This commit is contained in:
parent
81beb58a1a
commit
c0d06fe463
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=18730
@ -1,10 +1,10 @@
|
||||
# from: @(#)Makefile 5.2 (Berkeley) 12/28/90
|
||||
# $Id: Makefile,v 1.4 1995/06/16 22:46:38 ache Exp $
|
||||
# @(#)Makefile 5.2 (Berkeley) 12/28/90
|
||||
# $Id: Makefile,v 1.5 1995/09/22 14:14:28 phk Exp $
|
||||
|
||||
PROG= make
|
||||
CFLAGS+= -I${.CURDIR} -DPOSIX -DSYSVINCLUDE
|
||||
CFLAGS+= -I${.CURDIR}
|
||||
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
|
||||
make.c parse.c str.c suff.c targ.c var.c
|
||||
make.c parse.c str.c suff.c targ.c var.c util.c
|
||||
SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
|
||||
lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \
|
||||
lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \
|
||||
@ -12,4 +12,8 @@ SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
|
||||
lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c
|
||||
.PATH: ${.CURDIR}/lst.lib
|
||||
|
||||
.if make(install)
|
||||
SUBDIR+= PSD.doc
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -43,7 +43,7 @@
|
||||
.\" is numeric, it is taken as the depth for numbering (as for .NH), else
|
||||
.\" the default (1) is assumed.
|
||||
.\"
|
||||
.\" $Id: tutorial.ms,v 1.4 89/01/08 20:20:22 adam Exp Locker: adam $
|
||||
.\" $Id: tutorial.ms,v 1.1.1.1 1994/05/27 12:32:16 rgrimes Exp $
|
||||
.\"
|
||||
.\" @P The initial paragraph distance.
|
||||
.\" @Q The piece of section number to increment (or 0 if none given)
|
||||
@ -1272,6 +1272,15 @@ administrator. If locking is on,
|
||||
will turn it off, and vice versa. Note that this locking will not
|
||||
prevent \fIyou\fP from invoking PMake twice in the same place \*- if
|
||||
you own the lock file, PMake will warn you about it but continue to execute.
|
||||
.IP "\fB\-m\fP \fIdirectory\fP"
|
||||
.Ix 0 def flags -m
|
||||
Tells PMake another place to search for included makefiles via the <...>
|
||||
style. Several
|
||||
.B \-m
|
||||
options can be given to form a search path. If this construct is used the
|
||||
default system makefile search path is completely overridden.
|
||||
To be explained in chapter 3, section 3.2.
|
||||
.Rm 2 3.2
|
||||
.IP \fB\-n\fP
|
||||
.Ix 0 def flags -n
|
||||
This flag tells PMake not to execute the commands needed to update the
|
||||
@ -1912,11 +1921,15 @@ or this
|
||||
.DE
|
||||
The difference between the two is where PMake searches for the file:
|
||||
the first way, PMake will look for
|
||||
the file only in the system makefile directory (to find out what that
|
||||
directory is, give PMake the
|
||||
the file only in the system makefile directory (or directories)
|
||||
(to find out what that directory is, give PMake the
|
||||
.B \-h
|
||||
flag).
|
||||
.Ix 0 ref flags -h
|
||||
The system makefile directory search path can be overridden via the
|
||||
.B \-m
|
||||
option.
|
||||
.Ix 0 ref flags -m
|
||||
For files in double-quotes, the search is more complex:
|
||||
.RS
|
||||
.IP 1)
|
||||
|
@ -94,7 +94,7 @@ static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
|
||||
#include <sys/param.h>
|
||||
#include <ctype.h>
|
||||
#include <ar.h>
|
||||
#include <ranlib.h>
|
||||
#include <utime.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "make.h"
|
||||
@ -108,12 +108,18 @@ typedef struct Arch {
|
||||
char *name; /* Name of archive */
|
||||
Hash_Table members; /* All the members of the archive described
|
||||
* by <name, struct ar_hdr *> key/value pairs */
|
||||
char *fnametab; /* Extended name table strings */
|
||||
size_t fnamesize; /* Size of the string table */
|
||||
} Arch;
|
||||
|
||||
static int ArchFindArchive __P((ClientData, ClientData));
|
||||
static void ArchFree __P((ClientData));
|
||||
static struct ar_hdr *ArchStatMember __P((char *, char *, Boolean));
|
||||
static FILE *ArchFindMember __P((char *, char *, struct ar_hdr *, char *));
|
||||
#if defined(__svr4__) || defined(__SVR4)
|
||||
#define SVR4ARCHIVES
|
||||
static int ArchSVR4Entry __P((Arch *, char *, size_t, FILE *));
|
||||
#endif
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
@ -143,6 +149,8 @@ ArchFree(ap)
|
||||
free((Address) Hash_GetValue (entry));
|
||||
|
||||
free(a->name);
|
||||
if (a->fnametab)
|
||||
free(a->fnametab);
|
||||
Hash_DeleteTable(&a->members);
|
||||
free((Address) a);
|
||||
}
|
||||
@ -486,7 +494,7 @@ ArchStatMember (archive, member, hash)
|
||||
strncpy(copy, member, AR_MAX_NAME_LEN);
|
||||
copy[AR_MAX_NAME_LEN] = '\0';
|
||||
}
|
||||
if ( (he = Hash_FindEntry (&ar->members, copy)) )
|
||||
if ((he = Hash_FindEntry (&ar->members, copy)) != NULL)
|
||||
return ((struct ar_hdr *) Hash_GetValue (he));
|
||||
return ((struct ar_hdr *) NULL);
|
||||
}
|
||||
@ -532,27 +540,58 @@ ArchStatMember (archive, member, hash)
|
||||
}
|
||||
|
||||
ar = (Arch *)emalloc (sizeof (Arch));
|
||||
ar->name = strdup (archive);
|
||||
ar->name = estrdup (archive);
|
||||
ar->fnametab = NULL;
|
||||
ar->fnamesize = 0;
|
||||
Hash_InitTable (&ar->members, -1);
|
||||
memName[AR_MAX_NAME_LEN] = '\0';
|
||||
|
||||
while (fread ((char *)&arh, sizeof (struct ar_hdr), 1, arch) == 1) {
|
||||
if (strncmp ( arh.ar_fmag, ARFMAG, sizeof (arh.ar_fmag)) != 0) {
|
||||
/*
|
||||
* The header is bogus, so the archive is bad
|
||||
* and there's no way we can recover...
|
||||
*/
|
||||
fclose (arch);
|
||||
Hash_DeleteTable (&ar->members);
|
||||
free ((Address)ar);
|
||||
return ((struct ar_hdr *) NULL);
|
||||
/*
|
||||
* The header is bogus, so the archive is bad
|
||||
* and there's no way we can recover...
|
||||
*/
|
||||
goto badarch;
|
||||
} else {
|
||||
/*
|
||||
* We need to advance the stream's pointer to the start of the
|
||||
* next header. Files are padded with newlines to an even-byte
|
||||
* boundary, so we need to extract the size of the file from the
|
||||
* 'size' field of the header and round it up during the seek.
|
||||
*/
|
||||
arh.ar_size[sizeof(arh.ar_size)-1] = '\0';
|
||||
size = (int) strtol(arh.ar_size, NULL, 10);
|
||||
|
||||
(void) strncpy (memName, arh.ar_name, sizeof(arh.ar_name));
|
||||
for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
|
||||
continue;
|
||||
}
|
||||
cp[1] = '\0';
|
||||
|
||||
#ifdef SVR4ARCHIVES
|
||||
/*
|
||||
* svr4 names are slash terminated. Also svr4 extended AR format.
|
||||
*/
|
||||
if (memName[0] == '/') {
|
||||
/*
|
||||
* svr4 magic mode; handle it
|
||||
*/
|
||||
switch (ArchSVR4Entry(ar, memName, size, arch)) {
|
||||
case -1: /* Invalid data */
|
||||
goto badarch;
|
||||
case 0: /* List of files entry */
|
||||
continue;
|
||||
default: /* Got the entry */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (cp[0] == '/')
|
||||
cp[0] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef AR_EFMT1
|
||||
/*
|
||||
* BSD 4.4 extended AR format: #1/<namelen>, with name as the
|
||||
@ -563,18 +602,10 @@ ArchStatMember (archive, member, hash)
|
||||
|
||||
unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
|
||||
|
||||
if (elen > MAXPATHLEN) {
|
||||
fclose (arch);
|
||||
Hash_DeleteTable (&ar->members);
|
||||
free ((Address)ar);
|
||||
return ((struct ar_hdr *) NULL);
|
||||
}
|
||||
if (fread (memName, elen, 1, arch) != 1) {
|
||||
fclose (arch);
|
||||
Hash_DeleteTable (&ar->members);
|
||||
free ((Address)ar);
|
||||
return ((struct ar_hdr *) NULL);
|
||||
}
|
||||
if (elen > MAXPATHLEN)
|
||||
goto badarch;
|
||||
if (fread (memName, elen, 1, arch) != 1)
|
||||
goto badarch;
|
||||
memName[elen] = '\0';
|
||||
fseek (arch, -elen, 1);
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE)) {
|
||||
@ -588,14 +619,6 @@ ArchStatMember (archive, member, hash)
|
||||
memcpy ((Address)Hash_GetValue (he), (Address)&arh,
|
||||
sizeof (struct ar_hdr));
|
||||
}
|
||||
/*
|
||||
* We need to advance the stream's pointer to the start of the
|
||||
* next header. Files are padded with newlines to an even-byte
|
||||
* boundary, so we need to extract the size of the file from the
|
||||
* 'size' field of the header and round it up during the seek.
|
||||
*/
|
||||
arh.ar_size[sizeof(arh.ar_size)-1] = '\0';
|
||||
size = (int) strtol(arh.ar_size, NULL, 10);
|
||||
fseek (arch, (size + 1) & ~1, 1);
|
||||
}
|
||||
|
||||
@ -614,8 +637,121 @@ ArchStatMember (archive, member, hash)
|
||||
} else {
|
||||
return ((struct ar_hdr *) NULL);
|
||||
}
|
||||
|
||||
badarch:
|
||||
fclose (arch);
|
||||
Hash_DeleteTable (&ar->members);
|
||||
if (ar->fnametab)
|
||||
free(ar->fnametab);
|
||||
free ((Address)ar);
|
||||
return ((struct ar_hdr *) NULL);
|
||||
}
|
||||
|
||||
#ifdef SVR4ARCHIVES
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* ArchSVR4Entry --
|
||||
* Parse an SVR4 style entry that begins with a slash.
|
||||
* If it is "//", then load the table of filenames
|
||||
* If it is "/<offset>", then try to substitute the long file name
|
||||
* from offset of a table previously read.
|
||||
*
|
||||
* Results:
|
||||
* -1: Bad data in archive
|
||||
* 0: A table was loaded from the file
|
||||
* 1: Name was successfully substituted from table
|
||||
* 2: Name was not successfully substituted from table
|
||||
*
|
||||
* Side Effects:
|
||||
* If a table is read, the file pointer is moved to the next archive
|
||||
* member
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
ArchSVR4Entry(ar, name, size, arch)
|
||||
Arch *ar;
|
||||
char *name;
|
||||
size_t size;
|
||||
FILE *arch;
|
||||
{
|
||||
#define ARLONGNAMES1 "//"
|
||||
#define ARLONGNAMES2 "/ARFILENAMES"
|
||||
size_t entry;
|
||||
char *ptr, *eptr;
|
||||
|
||||
if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 ||
|
||||
strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) {
|
||||
|
||||
if (ar->fnametab != NULL) {
|
||||
if (DEBUG(ARCH)) {
|
||||
printf("Attempted to redefine an SVR4 name table\n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a table of archive names, so we build one for
|
||||
* ourselves
|
||||
*/
|
||||
ar->fnametab = emalloc(size);
|
||||
ar->fnamesize = size;
|
||||
|
||||
if (fread(ar->fnametab, size, 1, arch) != 1) {
|
||||
if (DEBUG(ARCH)) {
|
||||
printf("Reading an SVR4 name table failed\n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
eptr = ar->fnametab + size;
|
||||
for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++)
|
||||
switch (*ptr) {
|
||||
case '/':
|
||||
entry++;
|
||||
*ptr = '\0';
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (DEBUG(ARCH)) {
|
||||
printf("Found svr4 archive name table with %d entries\n", entry);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (name[1] == ' ' || name[1] == '\0')
|
||||
return 2;
|
||||
|
||||
entry = (size_t) strtol(&name[1], &eptr, 0);
|
||||
if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) {
|
||||
if (DEBUG(ARCH)) {
|
||||
printf("Could not parse SVR4 name %s\n", name);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if (entry >= ar->fnamesize) {
|
||||
if (DEBUG(ARCH)) {
|
||||
printf("SVR4 entry offset %s is greater than %d\n",
|
||||
name, ar->fnamesize);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (DEBUG(ARCH)) {
|
||||
printf("Replaced %s with %s\n", name, &ar->fnametab[entry]);
|
||||
}
|
||||
|
||||
(void) strncpy(name, &ar->fnametab[entry], MAXPATHLEN);
|
||||
name[MAXPATHLEN] = '\0';
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* ArchFindMember --
|
||||
@ -820,9 +956,10 @@ void
|
||||
Arch_TouchLib (gn)
|
||||
GNode *gn; /* The node of the library to touch */
|
||||
{
|
||||
#ifdef RANLIBMAG
|
||||
FILE * arch; /* Stream open to archive */
|
||||
struct ar_hdr arh; /* Header describing table of contents */
|
||||
struct timeval times[2]; /* Times for utimes() call */
|
||||
struct utimbuf times; /* Times for utime() call */
|
||||
|
||||
arch = ArchFindMember (gn->path, RANLIBMAG, &arh, "r+");
|
||||
sprintf(arh.ar_date, "%-12ld", (long) now);
|
||||
@ -831,10 +968,10 @@ Arch_TouchLib (gn)
|
||||
(void)fwrite ((char *)&arh, sizeof (struct ar_hdr), 1, arch);
|
||||
fclose (arch);
|
||||
|
||||
times[0].tv_sec = times[1].tv_sec = now;
|
||||
times[0].tv_usec = times[1].tv_usec = 0;
|
||||
utimes(gn->path, times);
|
||||
times.actime = times.modtime = now;
|
||||
utime(gn->path, ×);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -975,7 +1112,7 @@ Arch_FindLib (gn, path)
|
||||
Var_Set (TARGET, gn->name, gn);
|
||||
#else
|
||||
Var_Set (TARGET, gn->path == (char *) NULL ? gn->name : gn->path, gn);
|
||||
#endif LIBRARIES
|
||||
#endif /* LIBRARIES */
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -1025,6 +1162,7 @@ Arch_LibOODate (gn)
|
||||
} else if ((gn->mtime > now) || (gn->mtime < gn->cmtime)) {
|
||||
oodate = TRUE;
|
||||
} else {
|
||||
#ifdef RANLIBMAG
|
||||
struct ar_hdr *arhPtr; /* Header for __.SYMDEF */
|
||||
int modTimeTOC; /* The table-of-contents's mod time */
|
||||
|
||||
@ -1046,6 +1184,9 @@ Arch_LibOODate (gn)
|
||||
}
|
||||
oodate = TRUE;
|
||||
}
|
||||
#else
|
||||
oodate = FALSE;
|
||||
#endif
|
||||
}
|
||||
return (oodate);
|
||||
}
|
||||
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)bit.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* bit.h --
|
||||
*
|
||||
* Definition of macros for setting and clearing bits in an array
|
||||
* of integers.
|
||||
*
|
||||
* It is assumed that "int" is 32 bits wide.
|
||||
*/
|
||||
|
||||
#ifndef _BIT
|
||||
#define _BIT
|
||||
|
||||
#include "sprite.h"
|
||||
|
||||
#define BIT_NUM_BITS_PER_INT 32
|
||||
#define BIT_NUM_BITS_PER_BYTE 8
|
||||
|
||||
#define Bit_NumInts(numBits) \
|
||||
(((numBits)+BIT_NUM_BITS_PER_INT -1)/BIT_NUM_BITS_PER_INT)
|
||||
|
||||
#define Bit_NumBytes(numBits) \
|
||||
(Bit_NumInts(numBits) * sizeof(int))
|
||||
|
||||
#define Bit_Alloc(numBits, bitArrayPtr) \
|
||||
bitArrayPtr = (int *)malloc((unsigned)Bit_NumBytes(numBits)); \
|
||||
Bit_Zero((numBits), (bitArrayPtr))
|
||||
|
||||
#define Bit_Free(bitArrayPtr) \
|
||||
free((char *)bitArrayPtr)
|
||||
|
||||
#define Bit_Set(numBits, bitArrayPtr) \
|
||||
((bitArrayPtr)[(numBits)/BIT_NUM_BITS_PER_INT] |= \
|
||||
(1 << ((numBits) % BIT_NUM_BITS_PER_INT)))
|
||||
|
||||
#define Bit_IsSet(numBits, bitArrayPtr) \
|
||||
((bitArrayPtr)[(numBits)/BIT_NUM_BITS_PER_INT] & \
|
||||
(1 << ((numBits) % BIT_NUM_BITS_PER_INT)))
|
||||
|
||||
#define Bit_Clear(numBits, bitArrayPtr) \
|
||||
((bitArrayPtr)[(numBits)/BIT_NUM_BITS_PER_INT] &= \
|
||||
~(1 << ((numBits) % BIT_NUM_BITS_PER_INT)))
|
||||
|
||||
#define Bit_IsClear(numBits, bitArrayPtr) \
|
||||
(!(Bit_IsSet((numBits), (bitArrayPtr))))
|
||||
|
||||
#define Bit_Copy(numBits, srcArrayPtr, destArrayPtr) \
|
||||
bcopy((char *)(srcArrayPtr), (char *)(destArrayPtr), \
|
||||
Bit_NumBytes(numBits))
|
||||
|
||||
#define Bit_Zero(numBits, bitArrayPtr) \
|
||||
bzero((char *)(bitArrayPtr), Bit_NumBytes(numBits))
|
||||
|
||||
extern int Bit_FindFirstSet();
|
||||
extern int Bit_FindFirstClear();
|
||||
extern Boolean Bit_Intersect();
|
||||
extern Boolean Bit_Union();
|
||||
extern Boolean Bit_AnySet();
|
||||
extern int *Bit_Expand();
|
||||
|
||||
#endif /* _BIT */
|
@ -63,7 +63,7 @@ static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
|
||||
#define BufExpand(bp,nb) \
|
||||
if (bp->left < (nb)+1) {\
|
||||
int newSize = (bp)->size + max((nb)+1,BUF_ADD_INC); \
|
||||
Byte *newBuf = (Byte *) realloc((bp)->buffer, newSize); \
|
||||
Byte *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \
|
||||
\
|
||||
(bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
|
||||
(bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)buf.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)buf.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*-
|
||||
|
@ -55,11 +55,11 @@ static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
#include "dir.h"
|
||||
@ -105,10 +105,8 @@ CompatInterrupt (signo)
|
||||
if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) {
|
||||
char *p1;
|
||||
char *file = Var_Value (TARGET, curTarg, &p1);
|
||||
struct stat st;
|
||||
|
||||
if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) &&
|
||||
unlink(file) != -1) {
|
||||
if (!noExecute && eunlink(file) != -1) {
|
||||
printf ("*** %s removed\n", file);
|
||||
}
|
||||
if (p1)
|
||||
@ -151,7 +149,7 @@ CompatRunCommand (cmdp, gnp)
|
||||
register char *cp;
|
||||
Boolean silent, /* Don't print command */
|
||||
errCheck; /* Check errors */
|
||||
union wait reason; /* Reason for child's death */
|
||||
int reason; /* Reason for child's death */
|
||||
int status; /* Description of child's death */
|
||||
int cpid; /* Child actually found */
|
||||
ReturnStatus stat; /* Status of fork */
|
||||
@ -292,7 +290,7 @@ CompatRunCommand (cmdp, gnp)
|
||||
*/
|
||||
while (1) {
|
||||
|
||||
while ((stat = wait((int *)&reason)) != cpid) {
|
||||
while ((stat = wait(&reason)) != cpid) {
|
||||
if (stat == -1 && errno != EINTR) {
|
||||
break;
|
||||
}
|
||||
@ -300,14 +298,14 @@ CompatRunCommand (cmdp, gnp)
|
||||
|
||||
if (stat > -1) {
|
||||
if (WIFSTOPPED(reason)) {
|
||||
status = reason.w_stopval; /* stopped */
|
||||
status = WSTOPSIG(reason); /* stopped */
|
||||
} else if (WIFEXITED(reason)) {
|
||||
status = reason.w_retcode; /* exited */
|
||||
status = WEXITSTATUS(reason); /* exited */
|
||||
if (status != 0) {
|
||||
printf ("*** Error code %d", status);
|
||||
}
|
||||
} else {
|
||||
status = reason.w_termsig; /* signaled */
|
||||
status = WTERMSIG(reason); /* signaled */
|
||||
printf ("*** Signal %d", status);
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,7 @@ typedef enum {
|
||||
* Structures to handle elegantly the different forms of #if's. The
|
||||
* last two fields are stored in condInvert and condDefProc, respectively.
|
||||
*/
|
||||
static void CondPushBack __P((Token));
|
||||
static int CondGetArg __P((char **, char **, char *, Boolean));
|
||||
static Boolean CondDoDefined __P((int, char *));
|
||||
static int CondStrMatch __P((ClientData, ClientData));
|
||||
@ -110,18 +111,19 @@ static struct If {
|
||||
char *form; /* Form of if */
|
||||
int formlen; /* Length of form */
|
||||
Boolean doNot; /* TRUE if default function should be negated */
|
||||
Boolean (*defProc)(); /* Default function to apply */
|
||||
Boolean (*defProc) __P((int, char *)); /* Default function to apply */
|
||||
} ifs[] = {
|
||||
{ "ifdef", 5, FALSE, CondDoDefined },
|
||||
{ "ifndef", 6, TRUE, CondDoDefined },
|
||||
{ "ifmake", 6, FALSE, CondDoMake },
|
||||
{ "ifnmake", 7, TRUE, CondDoMake },
|
||||
{ "if", 2, FALSE, CondDoDefined },
|
||||
{ (char *)0, 0, FALSE, (Boolean (*)())0 }
|
||||
{ NULL, 0, FALSE, NULL }
|
||||
};
|
||||
|
||||
static Boolean condInvert; /* Invert the default function */
|
||||
static Boolean (*condDefProc)(); /* Default function to apply */
|
||||
static Boolean (*condDefProc) /* Default function to apply */
|
||||
__P((int, char *));
|
||||
static char *condExpr; /* The expression to parse */
|
||||
static Token condPushBack=None; /* Single push-back token used in
|
||||
* parsing */
|
||||
@ -758,7 +760,7 @@ error:
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Boolean (*evalProc)();
|
||||
Boolean (*evalProc) __P((int, char *));
|
||||
Boolean invert = FALSE;
|
||||
char *arg;
|
||||
int arglen;
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)config.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)config.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
#define DEFSHELL 1 /* Bourne shell */
|
||||
@ -78,15 +78,40 @@
|
||||
* re-made, causing later targets to appear up-to-date. On systems
|
||||
* that don't have this problem, you should defined this. Under
|
||||
* NFS you probably should not, unless you aren't exporting jobs.
|
||||
*
|
||||
* POSIX
|
||||
* If the POSIX standard for Make is to be followed. There are
|
||||
* several areas that I dislike, hence this constant.
|
||||
*/
|
||||
#define LIBSUFF ".a"
|
||||
#define RECHECK
|
||||
|
||||
#ifndef RANLIBMAG
|
||||
#define RANLIBMAG "__.SYMDEF"
|
||||
/*
|
||||
* POSIX
|
||||
* Adhere to the POSIX 1003.2 draft for the make(1) program.
|
||||
* - Use MAKEFLAGS instead of MAKE to pick arguments from the
|
||||
* environment.
|
||||
* - Allow empty command lines if starting with tab.
|
||||
*/
|
||||
#define POSIX
|
||||
|
||||
/*
|
||||
* SYSVINCLUDE
|
||||
* Recognize system V like include directives [include "filename"]
|
||||
* SYSVVARSUB
|
||||
* Recognize system V like ${VAR:x=y} variable substitutions
|
||||
*/
|
||||
#define SYSVINCLUDE
|
||||
#define SYSVVARSUB
|
||||
|
||||
/*
|
||||
* SUNSHCMD
|
||||
* Recognize SunOS and Solaris:
|
||||
* VAR :sh= CMD # Assign VAR to the command substitution of CMD
|
||||
* ${VAR:sh} # Return the command substitution of the value
|
||||
* # of ${VAR}
|
||||
*/
|
||||
#define SUNSHCMD
|
||||
|
||||
#if !defined(__svr4__) && !defined(__SVR4)
|
||||
# ifndef RANLIBMAG
|
||||
# define RANLIBMAG "__.SYMDEF"
|
||||
# endif
|
||||
#endif
|
||||
/*#define POSIX*/
|
||||
|
@ -348,7 +348,7 @@ DirMatchFiles (pattern, p, expansions)
|
||||
(pattern[0] == '.')))
|
||||
{
|
||||
(void)Lst_AtEnd(expansions,
|
||||
(isDot ? strdup(entry->name) :
|
||||
(isDot ? estrdup(entry->name) :
|
||||
str_concat(p->name, entry->name,
|
||||
STR_ADDSLASH)));
|
||||
}
|
||||
@ -700,7 +700,7 @@ Dir_FindFile (name, path)
|
||||
}
|
||||
hits += 1;
|
||||
dot->hits += 1;
|
||||
return (strdup (name));
|
||||
return (estrdup (name));
|
||||
}
|
||||
|
||||
if (Lst_Open (path) == FAILURE) {
|
||||
@ -811,7 +811,7 @@ Dir_FindFile (name, path)
|
||||
/*
|
||||
* Checking in dot -- DON'T put a leading ./ on the thing.
|
||||
*/
|
||||
file = strdup(name);
|
||||
file = estrdup(name);
|
||||
checkedDot = TRUE;
|
||||
}
|
||||
if (DEBUG(DIR)) {
|
||||
@ -907,7 +907,7 @@ Dir_FindFile (name, path)
|
||||
}
|
||||
|
||||
if (Hash_FindEntry (&p->files, cp) != (Hash_Entry *)NULL) {
|
||||
return (strdup (name));
|
||||
return (estrdup (name));
|
||||
} else {
|
||||
return ((char *) NULL);
|
||||
}
|
||||
@ -922,7 +922,7 @@ Dir_FindFile (name, path)
|
||||
if (DEBUG(DIR)) {
|
||||
printf("got it (in mtime cache)\n");
|
||||
}
|
||||
return(strdup(name));
|
||||
return(estrdup(name));
|
||||
} else if (stat (name, &stb) == 0) {
|
||||
entry = Hash_CreateEntry(&mtimes, name, (Boolean *)NULL);
|
||||
if (DEBUG(DIR)) {
|
||||
@ -930,7 +930,7 @@ Dir_FindFile (name, path)
|
||||
name);
|
||||
}
|
||||
Hash_SetValue(entry, (long)stb.st_mtime);
|
||||
return (strdup (name));
|
||||
return (estrdup (name));
|
||||
} else {
|
||||
if (DEBUG(DIR)) {
|
||||
printf("failed. Returning NULL\n");
|
||||
@ -973,7 +973,7 @@ Dir_MTime (gn)
|
||||
}
|
||||
|
||||
if (fullName == (char *)NULL) {
|
||||
fullName = strdup(gn->name);
|
||||
fullName = estrdup(gn->name);
|
||||
}
|
||||
|
||||
entry = Hash_FindEntry(&mtimes, fullName);
|
||||
@ -1047,7 +1047,7 @@ Dir_AddDir (path, name)
|
||||
|
||||
if ((d = opendir (name)) != (DIR *) NULL) {
|
||||
p = (Path *) emalloc (sizeof (Path));
|
||||
p->name = strdup (name);
|
||||
p->name = estrdup (name);
|
||||
p->hits = 0;
|
||||
p->refCount = 1;
|
||||
Hash_InitTable (&p->files, -1);
|
||||
@ -1059,7 +1059,7 @@ Dir_AddDir (path, name)
|
||||
(void)readdir(d);
|
||||
|
||||
while ((dp = readdir (d)) != (struct dirent *) NULL) {
|
||||
#ifdef sun
|
||||
#if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */
|
||||
/*
|
||||
* The sun directory library doesn't check for a 0 inode
|
||||
* (0-inode slots just take up space), so we have to do
|
||||
@ -1068,7 +1068,7 @@ Dir_AddDir (path, name)
|
||||
if (dp->d_fileno == 0) {
|
||||
continue;
|
||||
}
|
||||
#endif /* sun */
|
||||
#endif /* sun && d_ino */
|
||||
(void)Hash_CreateEntry(&p->files, dp->d_name, (Boolean *)NULL);
|
||||
}
|
||||
(void) closedir (d);
|
||||
@ -1131,7 +1131,7 @@ Dir_MakeFlags (flag, path)
|
||||
LstNode ln; /* the node of the current directory */
|
||||
Path *p; /* the structure describing the current directory */
|
||||
|
||||
str = strdup ("");
|
||||
str = estrdup ("");
|
||||
|
||||
if (Lst_Open (path) == SUCCESS) {
|
||||
while ((ln = Lst_Next (path)) != NILLNODE) {
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)dir.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)dir.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/* dir.h --
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)hash.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)hash.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/* hash.h --
|
||||
|
1517
usr.bin/make/job.c
1517
usr.bin/make/job.c
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)job.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)job.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*-
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)list.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)list.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)lst.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)lst.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*-
|
||||
@ -46,7 +46,7 @@
|
||||
#define _LST_H_
|
||||
|
||||
#include <sprite.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#if __STDC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
@ -66,7 +66,7 @@ void
|
||||
Lst_ForEachFrom (l, ln, proc, d)
|
||||
Lst l;
|
||||
LstNode ln;
|
||||
register int (*proc)();
|
||||
register int (*proc) __P((ClientData, ClientData));
|
||||
register ClientData d;
|
||||
{
|
||||
register ListNode tln = (ListNode)ln;
|
||||
@ -109,3 +109,4 @@ Lst_ForEachFrom (l, ln, proc, d)
|
||||
} while (!result && !LstIsEmpty(list) && !done);
|
||||
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)lstInt.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)lstInt.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*-
|
||||
@ -43,6 +43,7 @@
|
||||
#ifndef _LSTINT_H_
|
||||
#define _LSTINT_H_
|
||||
|
||||
#include "make.h"
|
||||
#include "lst.h"
|
||||
|
||||
typedef struct ListNode {
|
||||
@ -87,7 +88,7 @@ typedef struct {
|
||||
* PAlloc (var, ptype) --
|
||||
* Allocate a pointer-typedef structure 'ptype' into the variable 'var'
|
||||
*/
|
||||
#define PAlloc(var,ptype) var = (ptype) malloc (sizeof (*var))
|
||||
#define PAlloc(var,ptype) var = (ptype) emalloc (sizeof (*var))
|
||||
|
||||
/*
|
||||
* LstValid (l) --
|
||||
|
@ -79,7 +79,10 @@ static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
|
||||
#include <sys/resource.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef MACHINE
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
@ -96,7 +99,7 @@ static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
|
||||
|
||||
#ifndef DEFMAXLOCAL
|
||||
#define DEFMAXLOCAL DEFMAXJOBS
|
||||
#endif DEFMAXLOCAL
|
||||
#endif /* DEFMAXLOCAL */
|
||||
|
||||
#define MAKEFLAGS ".MAKEFLAGS"
|
||||
|
||||
@ -109,7 +112,7 @@ static Boolean noBuiltins; /* -r flag */
|
||||
static Lst makefiles; /* ordered list of makefiles to read */
|
||||
static Boolean printVars; /* print value of one or more vars */
|
||||
static Lst variables; /* list of variables to print */
|
||||
int maxJobs; /* -J argument */
|
||||
int maxJobs; /* -j argument */
|
||||
static int maxLocal; /* -L argument */
|
||||
Boolean compatMake; /* -B argument */
|
||||
Boolean debug; /* -d flag */
|
||||
@ -124,8 +127,10 @@ Boolean oldVars; /* variable substitution style */
|
||||
Boolean checkEnvFirst; /* -e flag */
|
||||
static Boolean jobsRunning; /* TRUE if the jobs might be running */
|
||||
|
||||
static Boolean ReadMakefile();
|
||||
static void usage();
|
||||
static void MainParseArgs __P((int, char **));
|
||||
char * chdir_verify_path __P((char *, char *));
|
||||
static int ReadMakefile __P((ClientData, ClientData));
|
||||
static void usage __P((void));
|
||||
|
||||
static char *curdir; /* startup directory */
|
||||
static char *objdir; /* where we chdir'ed to */
|
||||
@ -152,12 +157,13 @@ MainParseArgs(argc, argv)
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
int c;
|
||||
int forceJobs = 0;
|
||||
|
||||
optind = 1; /* since we're called more than once */
|
||||
#ifdef notyet
|
||||
# define OPTFLAGS "BD:I:L:PSV:d:ef:ij:knqrst"
|
||||
#ifdef REMOTE
|
||||
# define OPTFLAGS "BD:I:L:PSV:d:ef:ij:km:nqrst"
|
||||
#else
|
||||
# define OPTFLAGS "D:I:V:d:ef:ij:knqrst"
|
||||
# define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"
|
||||
#endif
|
||||
rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
|
||||
switch(c) {
|
||||
@ -177,15 +183,16 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
|
||||
Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
|
||||
Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'B':
|
||||
compatMake = TRUE;
|
||||
break;
|
||||
#ifdef REMOTE
|
||||
case 'L':
|
||||
maxLocal = atoi(optarg);
|
||||
Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
|
||||
Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
|
||||
break;
|
||||
#endif
|
||||
case 'P':
|
||||
usePipes = FALSE;
|
||||
Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
|
||||
@ -194,7 +201,6 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
|
||||
keepgoing = FALSE;
|
||||
Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
|
||||
break;
|
||||
#endif
|
||||
case 'd': {
|
||||
char *modules = optarg;
|
||||
|
||||
@ -262,7 +268,11 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
|
||||
Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
|
||||
break;
|
||||
case 'j':
|
||||
forceJobs = TRUE;
|
||||
maxJobs = atoi(optarg);
|
||||
#ifndef REMOTE
|
||||
maxLocal = maxJobs;
|
||||
#endif
|
||||
Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
|
||||
Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
|
||||
break;
|
||||
@ -270,6 +280,11 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
|
||||
keepgoing = TRUE;
|
||||
Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
|
||||
break;
|
||||
case 'm':
|
||||
Dir_AddDir(sysIncPath, optarg);
|
||||
Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
|
||||
Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
|
||||
break;
|
||||
case 'n':
|
||||
noExecute = TRUE;
|
||||
Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
|
||||
@ -297,6 +312,13 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Be compatible if user did not specify -j and did not explicitly
|
||||
* turned compatibility on
|
||||
*/
|
||||
if (!compatMake && !forceJobs)
|
||||
compatMake = TRUE;
|
||||
|
||||
oldVars = TRUE;
|
||||
|
||||
/*
|
||||
@ -317,7 +339,7 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
|
||||
optind = 1; /* - */
|
||||
goto rearg;
|
||||
}
|
||||
(void)Lst_AtEnd(create, (ClientData)strdup(*argv));
|
||||
(void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,13 +429,29 @@ main(argc, argv)
|
||||
Lst targs; /* target nodes to create -- passed to Make_Init */
|
||||
Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
|
||||
struct stat sb, sa;
|
||||
char *p, *p1, *path, *pathp, *pwd, *getenv(), *getwd();
|
||||
char *p, *p1, *path, *pathp, *pwd;
|
||||
char mdpath[MAXPATHLEN + 1];
|
||||
char obpath[MAXPATHLEN + 1];
|
||||
char cdpath[MAXPATHLEN + 1];
|
||||
struct utsname utsname;
|
||||
char *machine = getenv("MACHINE");
|
||||
Lst sysMkPath; /* Path of sys.mk */
|
||||
char *cp = NULL, *start;
|
||||
/* avoid faults on read-only strings */
|
||||
static char syspath[] = _PATH_DEFSYSPATH;
|
||||
|
||||
#ifdef RLIMIT_NOFILE
|
||||
/*
|
||||
* get rid of resource limit on file descriptors
|
||||
*/
|
||||
{
|
||||
struct rlimit rl;
|
||||
if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
|
||||
rl.rlim_cur != rl.rlim_max) {
|
||||
rl.rlim_cur = rl.rlim_max;
|
||||
(void) setrlimit(RLIMIT_NOFILE, &rl);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Find where we are and take care of PWD for the automounter...
|
||||
* All this code is so that we know where we are when we start up
|
||||
@ -447,6 +485,8 @@ main(argc, argv)
|
||||
*/
|
||||
if (!machine) {
|
||||
#ifndef MACHINE
|
||||
struct utsname utsname;
|
||||
|
||||
if (uname(&utsname) == -1) {
|
||||
perror("make: uname");
|
||||
exit(2);
|
||||
@ -512,13 +552,13 @@ main(argc, argv)
|
||||
debug = 0; /* No debug verbosity, please. */
|
||||
jobsRunning = FALSE;
|
||||
|
||||
maxJobs = DEFMAXJOBS; /* Set default max concurrency */
|
||||
maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
|
||||
#ifdef notyet
|
||||
compatMake = FALSE; /* No compat mode */
|
||||
#ifdef REMOTE
|
||||
maxJobs = DEFMAXJOBS; /* Set default max concurrency */
|
||||
#else
|
||||
compatMake = TRUE; /* No compat mode */
|
||||
maxJobs = maxLocal;
|
||||
#endif
|
||||
compatMake = FALSE; /* No compat mode */
|
||||
|
||||
|
||||
/*
|
||||
@ -593,13 +633,41 @@ main(argc, argv)
|
||||
} else
|
||||
Var_Set(".TARGETS", "", VAR_GLOBAL);
|
||||
|
||||
|
||||
/*
|
||||
* Read in the built-in rules first, followed by the specified makefile,
|
||||
* if it was (makefile != (char *) NULL), or the default Makefile and
|
||||
* makefile, in that order, if it wasn't.
|
||||
* If no user-supplied system path was given (through the -m option)
|
||||
* add the directories from the DEFSYSPATH (more than one may be given
|
||||
* as dir1:...:dirn) to the system include path.
|
||||
*/
|
||||
if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
|
||||
Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
|
||||
if (Lst_IsEmpty(sysIncPath)) {
|
||||
for (start = syspath; *start != '\0'; start = cp) {
|
||||
for (cp = start; *cp != '\0' && *cp != ':'; cp++)
|
||||
continue;
|
||||
if (*cp == '\0') {
|
||||
Dir_AddDir(sysIncPath, start);
|
||||
} else {
|
||||
*cp++ = '\0';
|
||||
Dir_AddDir(sysIncPath, start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in the built-in rules first, followed by the specified
|
||||
* makefile, if it was (makefile != (char *) NULL), or the default
|
||||
* Makefile and makefile, in that order, if it wasn't.
|
||||
*/
|
||||
if (!noBuiltins) {
|
||||
LstNode ln;
|
||||
|
||||
sysMkPath = Lst_Init (FALSE);
|
||||
Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
|
||||
if (Lst_IsEmpty(sysMkPath))
|
||||
Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
|
||||
ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
|
||||
if (ln != NILLNODE)
|
||||
Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
|
||||
}
|
||||
|
||||
if (!Lst_IsEmpty(makefiles)) {
|
||||
LstNode ln;
|
||||
@ -607,10 +675,10 @@ main(argc, argv)
|
||||
ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
|
||||
if (ln != NILLNODE)
|
||||
Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
|
||||
} else if (!ReadMakefile("makefile"))
|
||||
(void)ReadMakefile("Makefile");
|
||||
} else if (!ReadMakefile("makefile", NULL))
|
||||
(void)ReadMakefile("Makefile", NULL);
|
||||
|
||||
(void)ReadMakefile(".depend");
|
||||
(void)ReadMakefile(".depend", NULL);
|
||||
|
||||
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
|
||||
if (p1)
|
||||
@ -693,10 +761,6 @@ main(argc, argv)
|
||||
else
|
||||
targs = Targ_FindList(create, TARG_CREATE);
|
||||
|
||||
/*
|
||||
* this was original amMake -- want to allow parallelism, so put this
|
||||
* back in, eventually.
|
||||
*/
|
||||
if (!compatMake && !printVars) {
|
||||
/*
|
||||
* Initialize job module before traversing the graph, now that
|
||||
@ -755,10 +819,11 @@ main(argc, argv)
|
||||
* lots
|
||||
*/
|
||||
static Boolean
|
||||
ReadMakefile(fname)
|
||||
char *fname; /* makefile to read */
|
||||
ReadMakefile(p, q)
|
||||
ClientData p, q;
|
||||
{
|
||||
extern Lst parseIncPath, sysIncPath;
|
||||
char *fname = p; /* makefile to read */
|
||||
extern Lst parseIncPath;
|
||||
FILE *stream;
|
||||
char *name, path[MAXPATHLEN + 1];
|
||||
|
||||
@ -795,6 +860,142 @@ found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Cmd_Exec --
|
||||
* Execute the command in cmd, and return the output of that command
|
||||
* in a string.
|
||||
*
|
||||
* Results:
|
||||
* A string containing the output of the command, or the empty string
|
||||
* If err is not NULL, it contains the reason for the command failure
|
||||
*
|
||||
* Side Effects:
|
||||
* The string must be freed by the caller.
|
||||
*/
|
||||
char *
|
||||
Cmd_Exec(cmd, err)
|
||||
char *cmd;
|
||||
char **err;
|
||||
{
|
||||
char *args[4]; /* Args for invoking the shell */
|
||||
int fds[2]; /* Pipe streams */
|
||||
int cpid; /* Child PID */
|
||||
int pid; /* PID from wait() */
|
||||
char *res; /* result */
|
||||
int status; /* command exit status */
|
||||
Buffer buf; /* buffer to store the result */
|
||||
char *cp;
|
||||
int cc;
|
||||
|
||||
|
||||
*err = NULL;
|
||||
|
||||
/*
|
||||
* Set up arguments for shell
|
||||
*/
|
||||
args[0] = "sh";
|
||||
args[1] = "-c";
|
||||
args[2] = cmd;
|
||||
args[3] = NULL;
|
||||
|
||||
/*
|
||||
* Open a pipe for fetching its output
|
||||
*/
|
||||
if (pipe(fds) == -1) {
|
||||
*err = "Couldn't create pipe for \"%s\"";
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fork
|
||||
*/
|
||||
switch (cpid = vfork()) {
|
||||
case 0:
|
||||
/*
|
||||
* Close input side of pipe
|
||||
*/
|
||||
(void) close(fds[0]);
|
||||
|
||||
/*
|
||||
* Duplicate the output stream to the shell's output, then
|
||||
* shut the extra thing down. Note we don't fetch the error
|
||||
* stream...why not? Why?
|
||||
*/
|
||||
(void) dup2(fds[1], 1);
|
||||
(void) close(fds[1]);
|
||||
|
||||
(void) execv("/bin/sh", args);
|
||||
_exit(1);
|
||||
/*NOTREACHED*/
|
||||
|
||||
case -1:
|
||||
*err = "Couldn't exec \"%s\"";
|
||||
goto bad;
|
||||
|
||||
default:
|
||||
/*
|
||||
* No need for the writing half
|
||||
*/
|
||||
(void) close(fds[1]);
|
||||
|
||||
buf = Buf_Init (MAKE_BSIZE);
|
||||
|
||||
do {
|
||||
char result[BUFSIZ];
|
||||
cc = read(fds[0], result, sizeof(result));
|
||||
if (cc > 0)
|
||||
Buf_AddBytes(buf, cc, (Byte *) result);
|
||||
}
|
||||
while (cc > 0 || (cc == -1 && errno == EINTR));
|
||||
|
||||
/*
|
||||
* Close the input side of the pipe.
|
||||
*/
|
||||
(void) close(fds[0]);
|
||||
|
||||
/*
|
||||
* Wait for the process to exit.
|
||||
*/
|
||||
while(((pid = wait(&status)) != cpid) && (pid >= 0))
|
||||
continue;
|
||||
|
||||
res = (char *)Buf_GetAll (buf, &cc);
|
||||
Buf_Destroy (buf, FALSE);
|
||||
|
||||
if (cc == 0)
|
||||
*err = "Couldn't read shell's output for \"%s\"";
|
||||
|
||||
if (status)
|
||||
*err = "\"%s\" returned non-zero status";
|
||||
|
||||
/*
|
||||
* Null-terminate the result, convert newlines to spaces and
|
||||
* install it in the variable.
|
||||
*/
|
||||
res[cc] = '\0';
|
||||
cp = &res[cc] - 1;
|
||||
|
||||
if (*cp == '\n') {
|
||||
/*
|
||||
* A final newline is just stripped
|
||||
*/
|
||||
*cp-- = '\0';
|
||||
}
|
||||
while (cp >= res) {
|
||||
if (*cp == '\n') {
|
||||
*cp = ' ';
|
||||
}
|
||||
cp--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
bad:
|
||||
res = emalloc(1);
|
||||
*res = '\0';
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Error --
|
||||
* Print an error message given its format.
|
||||
@ -952,17 +1153,46 @@ Finish(errors)
|
||||
* emalloc --
|
||||
* malloc, but die on error.
|
||||
*/
|
||||
char *
|
||||
void *
|
||||
emalloc(len)
|
||||
size_t len;
|
||||
{
|
||||
char *p;
|
||||
void *p;
|
||||
|
||||
if ((p = (char *) malloc(len)) == NULL)
|
||||
if ((p = malloc(len)) == NULL)
|
||||
enomem();
|
||||
return(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* estrdup --
|
||||
* strdup, but die on error.
|
||||
*/
|
||||
char *
|
||||
estrdup(str)
|
||||
const char *str;
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = strdup(str)) == NULL)
|
||||
enomem();
|
||||
return(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* erealloc --
|
||||
* realloc, but die on error.
|
||||
*/
|
||||
void *
|
||||
erealloc(ptr, size)
|
||||
void *ptr;
|
||||
size_t size;
|
||||
{
|
||||
if ((ptr = realloc(ptr, size)) == NULL)
|
||||
enomem();
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* enomem --
|
||||
* die when out of memory.
|
||||
@ -974,6 +1204,26 @@ enomem()
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/*
|
||||
* enunlink --
|
||||
* Remove a file carefully, avoiding directories.
|
||||
*/
|
||||
int
|
||||
eunlink(file)
|
||||
const char *file;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (lstat(file, &st) == -1)
|
||||
return -1;
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
errno = EISDIR;
|
||||
return -1;
|
||||
}
|
||||
return unlink(file);
|
||||
}
|
||||
|
||||
/*
|
||||
* usage --
|
||||
* exit with usage message
|
||||
@ -982,8 +1232,9 @@ static void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile] [-I directory]\n\
|
||||
[-j max_jobs] [-V variable] [variable=value] [target ...]\n");
|
||||
"usage: make [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
|
||||
[-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
|
||||
[variable=value] [target ...]\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,8 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)make.1 8.4 (Berkeley) 3/19/94
|
||||
.\" $Id$
|
||||
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
|
||||
.\" $Id: make.1,v 1.5 1996/10/05 22:27:13 wosch Exp $
|
||||
.\"
|
||||
.Dd March 19, 1994
|
||||
.Dt MAKE 1
|
||||
@ -40,13 +40,14 @@
|
||||
.Nd maintain program dependencies
|
||||
.Sh SYNOPSIS
|
||||
.Nm make
|
||||
.Op Fl eiknqrst
|
||||
.Op Fl Beiknqrst
|
||||
.Op Fl D Ar variable
|
||||
.Op Fl d Ar flags
|
||||
.Op Fl f Ar makefile
|
||||
.Op Fl I Ar directory
|
||||
.Bk -words
|
||||
.Op Fl j Ar max_jobs
|
||||
.Op Fl m Ar directory
|
||||
.Ek
|
||||
.Op Fl V Ar variable
|
||||
.Op Ar variable=value
|
||||
@ -75,6 +76,9 @@ and makefiles, please refer to
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl B
|
||||
Try to be backwards compatible by executing a single shell per command and
|
||||
by executing the commands to make the sources of a dependency line in sequence.
|
||||
.It Fl D Ar variable
|
||||
Define
|
||||
.Ar variable
|
||||
@ -128,8 +132,9 @@ standard input is read.
|
||||
Multiple makefile's may be specified, and are read in the order specified.
|
||||
.It Fl I Ar directory
|
||||
Specify a directory in which to search for makefiles and included makefiles.
|
||||
The system makefile directory is automatically included as part of this
|
||||
list.
|
||||
The system makefile directory (or directories, see the
|
||||
.Fl m
|
||||
option) is automatically included as part of this list.
|
||||
.It Fl i
|
||||
Ignore non-zero exit of shell commands in the makefile.
|
||||
Equivalent to specifying
|
||||
@ -138,10 +143,20 @@ before each command line in the makefile.
|
||||
.It Fl j Ar max_jobs
|
||||
Specify the maximum number of jobs that
|
||||
.Nm make
|
||||
may have running at any one time.
|
||||
may have running at any one time. Turns compatibility mode off, unless the
|
||||
.Ar B
|
||||
flag is also specified.
|
||||
.It Fl k
|
||||
Continue processing after errors are encountered, but only on those targets
|
||||
that do not depend on the target whose creation caused the error.
|
||||
.It Fl m Ar directory
|
||||
Specify a directory in which to search for sys.mk and makefiles included
|
||||
via the <...> style. Multiple directories can be added to form a search path.
|
||||
This path will override the default system include path: /usr/share/mk.
|
||||
Furthermore the system include path will be appended to the search path used
|
||||
for "..."-style inclusions (see the
|
||||
.Fl I
|
||||
option).
|
||||
.It Fl n
|
||||
Display the commands that would have been executed, but do not actually
|
||||
execute them.
|
||||
@ -291,13 +306,13 @@ between the previous contents of the variable and the appended value.
|
||||
Variables are expanded by surrounding the variable name with either
|
||||
curly braces
|
||||
.Pq Ql {}
|
||||
or parenthesis
|
||||
or parentheses
|
||||
.Pq Ql ()
|
||||
and preceding it with
|
||||
a dollar sign
|
||||
.Pq Ql \&$ .
|
||||
If the variable name contains only a single letter, the surrounding
|
||||
braces or parenthesis are not required.
|
||||
braces or parentheses are not required.
|
||||
This shorter form is not recommended.
|
||||
.Pp
|
||||
Variable substitution occurs at two distinct times, depending on where
|
||||
@ -386,10 +401,11 @@ i.e.
|
||||
.Ql \&$$
|
||||
expands to a single dollar
|
||||
sign.
|
||||
.It Ev MAKE
|
||||
.It Va .MAKE
|
||||
The name that
|
||||
.Nm make
|
||||
was executed with.
|
||||
was executed with
|
||||
.Pq Va argv Op 0
|
||||
.It Va .CURDIR
|
||||
A path to the directory where
|
||||
.Nm make
|
||||
@ -414,7 +430,7 @@ executes.
|
||||
.It Ev PWD
|
||||
Alternate path to the current directory.
|
||||
.Nm make
|
||||
normally sets
|
||||
normally sets
|
||||
.Ql Va .CURDIR
|
||||
to the canonical path given by
|
||||
.Xr getcwd 2 .
|
||||
@ -520,23 +536,23 @@ This is the
|
||||
.At V
|
||||
style variable substitution.
|
||||
It must be the last modifier specified.
|
||||
If
|
||||
If
|
||||
.Ar old_string
|
||||
or
|
||||
.Ar new_string
|
||||
do not contain the pattern matching character
|
||||
.Ar %
|
||||
then it is assumed that they are
|
||||
then it is assumed that they are
|
||||
anchored at the end of each word, so only suffixes or entire
|
||||
words may be replaced. Otherwise
|
||||
words may be replaced. Otherwise
|
||||
.Ar %
|
||||
is the substring of
|
||||
.Ar old_string
|
||||
is the substring of
|
||||
.Ar old_string
|
||||
to be replaced in
|
||||
.Ar new_string
|
||||
.El
|
||||
.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
|
||||
Makefile inclusion, conditional structures and for loops reminiscent
|
||||
Makefile inclusion, conditional structures and for loops reminiscent
|
||||
of the C programming language are provided in
|
||||
.Nm make .
|
||||
All such structures are identified by a line beginning with a single
|
||||
@ -738,14 +754,14 @@ In both cases this continues until a
|
||||
or
|
||||
.Ql Ic .endif
|
||||
is found.
|
||||
.Pp
|
||||
.Pp
|
||||
For loops are typically used to apply a set of rules to a list of files.
|
||||
The syntax of a for loop is:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Ic \&.for
|
||||
.Ar variable
|
||||
.Ic in
|
||||
.Ar variable
|
||||
.Ic in
|
||||
.Ar expression
|
||||
.Xc
|
||||
.It Xo
|
||||
@ -756,12 +772,12 @@ The syntax of a for loop is:
|
||||
.Xc
|
||||
.El
|
||||
After the for
|
||||
.Ic expression
|
||||
is evaluated, it is split into words. The
|
||||
.Ic expression
|
||||
is evaluated, it is split into words. The
|
||||
iteration
|
||||
.Ic variable
|
||||
is successively set to each word, and substituted in the
|
||||
.Ic make-rules
|
||||
is successively set to each word, and substituted in the
|
||||
.Ic make-rules
|
||||
inside the body of the for loop.
|
||||
.Sh COMMENTS
|
||||
Comments begin with a hash
|
||||
@ -815,6 +831,12 @@ If the target already has commands, the
|
||||
.Ic .USE
|
||||
target's commands are appended
|
||||
to them.
|
||||
.It Ic .WAIT
|
||||
If special
|
||||
.Ic .WAIT
|
||||
source is appears in a dependency line, the sources that precede it are
|
||||
made before the sources that succeed it in the line. Loops are not being
|
||||
detected and targets that form loops will be silently ignored.
|
||||
.El
|
||||
.Sh "SPECIAL TARGETS"
|
||||
Special targets may not be included with other targets, i.e. they must be
|
||||
@ -863,11 +885,30 @@ The flags are as if typed to the shell, though the
|
||||
.Fl f
|
||||
option will have
|
||||
no effect.
|
||||
.\" XXX: NOT YET!!!!
|
||||
.\" .It Ic .NOTPARALLEL
|
||||
.\" The named targets are executed in non parallel mode. If no targets are
|
||||
.\" specified, then all targets are executed in non parallel mode.
|
||||
.It Ic .NOTPARALLEL
|
||||
Disable parallel mode.
|
||||
.It Ic .NO_PARALLEL
|
||||
Same as above, for compatibility with other pmake variants.
|
||||
.It Ic .ORDER
|
||||
The named targets are made in sequence.
|
||||
.\" XXX: NOT YET!!!!
|
||||
.\" .It Ic .PARALLEL
|
||||
.\" The named targets are executed in parallel mode. If no targets are
|
||||
.\" specified, then all targets are executed in parallel mode.
|
||||
.It Ic .PATH
|
||||
The sources are directories which are to be searched for files not
|
||||
found in the current directory.
|
||||
If no sources are specified, any previously specified directories are
|
||||
deleted.
|
||||
.It Ic .PHONY
|
||||
Apply the
|
||||
.Ic .PHONY
|
||||
attribute to any specified sources. Targets with this attribute are always
|
||||
considered to be out of date.
|
||||
.It Ic .PRECIOUS
|
||||
Apply the
|
||||
.Ic .PRECIOUS
|
||||
|
@ -207,7 +207,7 @@ Make_OODate (gn)
|
||||
printf(".JOIN node...");
|
||||
}
|
||||
oodate = gn->childMade;
|
||||
} else if (gn->type & (OP_FORCE|OP_EXEC)) {
|
||||
} else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
|
||||
/*
|
||||
* A node which is the object of the force (!) operator or which has
|
||||
* the .EXEC attribute is always considered out-of-date.
|
||||
@ -215,6 +215,8 @@ Make_OODate (gn)
|
||||
if (DEBUG(MAKE)) {
|
||||
if (gn->type & OP_FORCE) {
|
||||
printf("! operator...");
|
||||
} else if (gn->type & OP_PHONY) {
|
||||
printf(".PHONY node...");
|
||||
} else {
|
||||
printf(".EXEC node...");
|
||||
}
|
||||
@ -570,9 +572,16 @@ MakeAddAllSrc (cgnp, pgnp)
|
||||
GNode *pgn = (GNode *) pgnp;
|
||||
if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
|
||||
char *child;
|
||||
char *p1;
|
||||
char *p1 = NULL;
|
||||
|
||||
child = Var_Value(TARGET, cgn, &p1);
|
||||
if (OP_NOP(cgn->type)) {
|
||||
/*
|
||||
* this node is only source; use the specific pathname for it
|
||||
*/
|
||||
child = cgn->path ? cgn->path : cgn->name;
|
||||
}
|
||||
else
|
||||
child = Var_Value(TARGET, cgn, &p1);
|
||||
Var_Append (ALLSRC, child, pgn);
|
||||
if (pgn->type & OP_JOIN) {
|
||||
if (cgn->made == MADE) {
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)make.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)make.h 8.3 (Berkeley) 6/13/95
|
||||
*/
|
||||
|
||||
/*-
|
||||
@ -50,15 +50,17 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifndef MAKE_BOOTSTRAP
|
||||
#if !defined(MAKE_BOOTSTRAP) && defined(BSD)
|
||||
#include <sys/cdefs.h>
|
||||
#else
|
||||
#ifndef __P
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
#define __P(protos) protos /* full-blown ANSI C */
|
||||
#else
|
||||
#define __P(protos) () /* traditional C preprocessor */
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if __STDC__
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -100,6 +102,7 @@ typedef struct GNode {
|
||||
char *name; /* The target's name */
|
||||
char *path; /* The full pathname of the file */
|
||||
int type; /* Its type (see the OP flags, below) */
|
||||
int order; /* Its wait weight */
|
||||
|
||||
Boolean make; /* TRUE if this target needs to be remade */
|
||||
enum {
|
||||
@ -192,6 +195,7 @@ typedef struct GNode {
|
||||
* local variables. */
|
||||
#define OP_NOTMAIN 0x00008000 /* The node is exempt from normal 'main
|
||||
* target' processing in parse.c */
|
||||
#define OP_PHONY 0x00010000 /* Not a file target; run always */
|
||||
/* Attributes applied by PMake */
|
||||
#define OP_TRANSFORM 0x80000000 /* The node is a transformation rule */
|
||||
#define OP_MEMBER 0x40000000 /* Target is a member of an archive */
|
||||
@ -322,6 +326,8 @@ extern time_t now; /* The time at the start of this whole
|
||||
|
||||
extern Boolean oldVars; /* Do old-style variable substitution */
|
||||
|
||||
extern Lst sysIncPath; /* The system include path. */
|
||||
|
||||
/*
|
||||
* debug control:
|
||||
* There is one bit per module. It is up to the module what debug
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nonints.h 8.3 (Berkeley) 3/19/94
|
||||
* from: @(#)nonints.h 8.3 (Berkeley) 3/19/94
|
||||
*/
|
||||
|
||||
/* arch.c */
|
||||
@ -63,14 +63,18 @@ void For_Run __P((void));
|
||||
/* main.c */
|
||||
void Main_ParseArgLine __P((char *));
|
||||
int main __P((int, char **));
|
||||
char *Cmd_Exec __P((char *, char **));
|
||||
void Error __P((char *, ...));
|
||||
void Fatal __P((char *, ...));
|
||||
void Punt __P((char *, ...));
|
||||
void DieHorribly __P((void));
|
||||
int PrintAddr __P((ClientData, ClientData));
|
||||
void Finish __P((int));
|
||||
char *emalloc __P((size_t));
|
||||
char *estrdup __P((const char *));
|
||||
void *emalloc __P((size_t));
|
||||
void *erealloc __P((void *, size_t));
|
||||
void enomem __P((void));
|
||||
int eunlink __P((const char *));
|
||||
|
||||
/* parse.c */
|
||||
void Parse_Error __P((int, char *, ...));
|
||||
|
@ -90,7 +90,6 @@ static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
#include "dir.h"
|
||||
@ -162,16 +161,20 @@ typedef enum {
|
||||
NotParallel, /* .NOTPARALELL */
|
||||
Null, /* .NULL */
|
||||
Order, /* .ORDER */
|
||||
Parallel, /* .PARALLEL */
|
||||
ExPath, /* .PATH */
|
||||
Phony, /* .PHONY */
|
||||
Precious, /* .PRECIOUS */
|
||||
ExShell, /* .SHELL */
|
||||
Silent, /* .SILENT */
|
||||
SingleShell, /* .SINGLESHELL */
|
||||
Suffixes, /* .SUFFIXES */
|
||||
Wait, /* .WAIT */
|
||||
Attribute /* Generic attribute */
|
||||
} ParseSpecial;
|
||||
|
||||
static ParseSpecial specType;
|
||||
static int waiting;
|
||||
|
||||
/*
|
||||
* Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER
|
||||
@ -207,10 +210,13 @@ static struct {
|
||||
{ ".MFLAGS", MFlags, 0 },
|
||||
{ ".NOTMAIN", Attribute, OP_NOTMAIN },
|
||||
{ ".NOTPARALLEL", NotParallel, 0 },
|
||||
{ ".NO_PARALLEL", NotParallel, 0 },
|
||||
{ ".NULL", Null, 0 },
|
||||
{ ".OPTIONAL", Attribute, OP_OPTIONAL },
|
||||
{ ".ORDER", Order, 0 },
|
||||
{ ".PARALLEL", Parallel, 0 },
|
||||
{ ".PATH", ExPath, 0 },
|
||||
{ ".PHONY", Phony, OP_PHONY },
|
||||
{ ".PRECIOUS", Precious, OP_PRECIOUS },
|
||||
{ ".RECURSIVE", Attribute, OP_MAKE },
|
||||
{ ".SHELL", ExShell, 0 },
|
||||
@ -218,12 +224,14 @@ static struct {
|
||||
{ ".SINGLESHELL", SingleShell, 0 },
|
||||
{ ".SUFFIXES", Suffixes, 0 },
|
||||
{ ".USE", Attribute, OP_USE },
|
||||
{ ".WAIT", Wait, 0 },
|
||||
};
|
||||
|
||||
static int ParseFindKeyword __P((char *));
|
||||
static int ParseLinkSrc __P((ClientData, ClientData));
|
||||
static int ParseDoOp __P((ClientData, ClientData));
|
||||
static void ParseDoSrc __P((int, char *));
|
||||
static int ParseAddDep __P((ClientData, ClientData));
|
||||
static void ParseDoSrc __P((int, char *, Lst));
|
||||
static int ParseFindMain __P((ClientData, ClientData));
|
||||
static int ParseAddDir __P((ClientData, ClientData));
|
||||
static int ParseClearPath __P((ClientData, ClientData));
|
||||
@ -435,6 +443,45 @@ ParseDoOp (gnp, opp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-
|
||||
*---------------------------------------------------------------------
|
||||
* ParseAddDep --
|
||||
* Check if the pair of GNodes given needs to be synchronized.
|
||||
* This has to be when two nodes are on different sides of a
|
||||
* .WAIT directive.
|
||||
*
|
||||
* Results:
|
||||
* Returns 1 if the two targets need to be ordered, 0 otherwise.
|
||||
* If it returns 1, the search can stop
|
||||
*
|
||||
* Side Effects:
|
||||
* A dependency can be added between the two nodes.
|
||||
*
|
||||
*---------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
ParseAddDep(pp, sp)
|
||||
ClientData pp;
|
||||
ClientData sp;
|
||||
{
|
||||
GNode *p = (GNode *) pp;
|
||||
GNode *s = (GNode *) sp;
|
||||
|
||||
if (p->order < s->order) {
|
||||
/*
|
||||
* XXX: This can cause loops, and loops can cause unmade targets,
|
||||
* but checking is tedious, and the debugging output can show the
|
||||
* problem
|
||||
*/
|
||||
(void)Lst_AtEnd(p->successors, (ClientData)s);
|
||||
(void)Lst_AtEnd(s->preds, (ClientData)p);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*---------------------------------------------------------------------
|
||||
* ParseDoSrc --
|
||||
@ -453,23 +500,30 @@ ParseDoOp (gnp, opp)
|
||||
*---------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
ParseDoSrc (tOp, src)
|
||||
ParseDoSrc (tOp, src, allsrc)
|
||||
int tOp; /* operator (if any) from special targets */
|
||||
char *src; /* name of the source to handle */
|
||||
Lst allsrc; /* List of all sources to wait for */
|
||||
{
|
||||
int op; /* operator (if any) from special source */
|
||||
GNode *gn;
|
||||
GNode *gn = NULL;
|
||||
|
||||
op = 0;
|
||||
if (*src == '.' && isupper (src[1])) {
|
||||
int keywd = ParseFindKeyword(src);
|
||||
if (keywd != -1) {
|
||||
op = parseKeywords[keywd].op;
|
||||
int op = parseKeywords[keywd].op;
|
||||
if (op != 0) {
|
||||
Lst_ForEach (targets, ParseDoOp, (ClientData)&op);
|
||||
return;
|
||||
}
|
||||
if (parseKeywords[keywd].spec == Wait) {
|
||||
waiting++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (op != 0) {
|
||||
Lst_ForEach (targets, ParseDoOp, (ClientData)&op);
|
||||
} else if (specType == Main) {
|
||||
|
||||
switch (specType) {
|
||||
case Main:
|
||||
/*
|
||||
* If we have noted the existence of a .MAIN, it means we need
|
||||
* to add the sources of said target to the list of things
|
||||
@ -478,13 +532,15 @@ ParseDoSrc (tOp, src)
|
||||
* invoked if the user didn't specify a target on the command
|
||||
* line. This is to allow #ifmake's to succeed, or something...
|
||||
*/
|
||||
(void) Lst_AtEnd (create, (ClientData)strdup(src));
|
||||
(void) Lst_AtEnd (create, (ClientData)estrdup(src));
|
||||
/*
|
||||
* Add the name to the .TARGETS variable as well, so the user cna
|
||||
* employ that, if desired.
|
||||
*/
|
||||
Var_Append(".TARGETS", src, VAR_GLOBAL);
|
||||
} else if (specType == Order) {
|
||||
return;
|
||||
|
||||
case Order:
|
||||
/*
|
||||
* Create proper predecessor/successor links between the previous
|
||||
* source and the current one.
|
||||
@ -498,7 +554,9 @@ ParseDoSrc (tOp, src)
|
||||
* The current source now becomes the predecessor for the next one.
|
||||
*/
|
||||
predecessor = gn;
|
||||
} else {
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* If the source is not an attribute, we need to find/create
|
||||
* a node for it. After that we can apply any operator to it
|
||||
@ -529,6 +587,13 @@ ParseDoSrc (tOp, src)
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
gn->order = waiting;
|
||||
(void)Lst_AtEnd(allsrc, (ClientData)gn);
|
||||
if (waiting) {
|
||||
Lst_ForEach(allsrc, ParseAddDep, (ClientData)gn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -651,16 +716,20 @@ ParseDoDependency (line)
|
||||
Lst paths; /* List of search paths to alter when parsing
|
||||
* a list of .PATH targets */
|
||||
int tOp; /* operator from special target */
|
||||
Lst sources; /* list of source names after expansion */
|
||||
Lst sources; /* list of archive source names after
|
||||
* expansion */
|
||||
Lst curTargs; /* list of target names to be found and added
|
||||
* to the targets list */
|
||||
Lst curSrcs; /* list of sources in order */
|
||||
|
||||
tOp = 0;
|
||||
|
||||
specType = Not;
|
||||
waiting = 0;
|
||||
paths = (Lst)NULL;
|
||||
|
||||
curTargs = Lst_Init(FALSE);
|
||||
curSrcs = Lst_Init(FALSE);
|
||||
|
||||
do {
|
||||
for (cp = line;
|
||||
@ -757,6 +826,7 @@ ParseDoDependency (line)
|
||||
* life easier later, when we'll
|
||||
* use Make_HandleUse to actually
|
||||
* apply the .DEFAULT commands.
|
||||
* .PHONY The list of targets
|
||||
* .BEGIN
|
||||
* .END
|
||||
* .INTERRUPT Are not to be considered the
|
||||
@ -1100,7 +1170,7 @@ ParseDoDependency (line)
|
||||
|
||||
while (!Lst_IsEmpty (sources)) {
|
||||
gn = (GNode *) Lst_DeQueue (sources);
|
||||
ParseDoSrc (tOp, gn->name);
|
||||
ParseDoSrc (tOp, gn->name, curSrcs);
|
||||
}
|
||||
Lst_Destroy (sources, NOFREE);
|
||||
cp = line;
|
||||
@ -1110,7 +1180,7 @@ ParseDoDependency (line)
|
||||
cp += 1;
|
||||
}
|
||||
|
||||
ParseDoSrc (tOp, line);
|
||||
ParseDoSrc (tOp, line, curSrcs);
|
||||
}
|
||||
while (*cp && isspace (*cp)) {
|
||||
cp++;
|
||||
@ -1129,6 +1199,10 @@ ParseDoDependency (line)
|
||||
Lst_ForEach (targets, ParseFindMain, (ClientData)0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, destroy the list of sources
|
||||
*/
|
||||
Lst_Destroy(curSrcs, NOFREE);
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -1153,60 +1227,80 @@ Parse_IsVar (line)
|
||||
{
|
||||
register Boolean wasSpace = FALSE; /* set TRUE if found a space */
|
||||
register Boolean haveName = FALSE; /* Set TRUE if have a variable name */
|
||||
int level = 0;
|
||||
#define ISEQOPERATOR(c) \
|
||||
(((c) == '+') || ((c) == ':') || ((c) == '?') || ((c) == '!'))
|
||||
|
||||
/*
|
||||
* Skip to variable name
|
||||
*/
|
||||
while ((*line == ' ') || (*line == '\t')) {
|
||||
line++;
|
||||
}
|
||||
for (;(*line == ' ') || (*line == '\t'); line++)
|
||||
continue;
|
||||
|
||||
while (*line != '=') {
|
||||
if (*line == '\0') {
|
||||
for (; *line != '=' || level != 0; line++)
|
||||
switch (*line) {
|
||||
case '\0':
|
||||
/*
|
||||
* end-of-line -- can't be a variable assignment.
|
||||
*/
|
||||
return (FALSE);
|
||||
} else if ((*line == ' ') || (*line == '\t')) {
|
||||
return FALSE;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
/*
|
||||
* there can be as much white space as desired so long as there is
|
||||
* only one word before the operator
|
||||
*/
|
||||
wasSpace = TRUE;
|
||||
} else if (wasSpace && haveName) {
|
||||
/*
|
||||
* Stop when an = operator is found.
|
||||
*/
|
||||
if ((*line == '+') || (*line == ':') || (*line == '?') ||
|
||||
(*line == '!')) {
|
||||
break;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
case '{':
|
||||
level++;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
case ')':
|
||||
level--;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (wasSpace && haveName) {
|
||||
if (ISEQOPERATOR(*line)) {
|
||||
/*
|
||||
* We must have a finished word
|
||||
*/
|
||||
if (level != 0)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* When an = operator [+?!:] is found, the next
|
||||
* character must be an = or it ain't a valid
|
||||
* assignment.
|
||||
*/
|
||||
if (line[1] == '=')
|
||||
return haveName;
|
||||
#ifdef SUNSHCMD
|
||||
/*
|
||||
* This is a shell command
|
||||
*/
|
||||
if (strncmp(line, ":sh", 3) == 0)
|
||||
return haveName;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* This is the start of another word, so not assignment.
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the start of another word, so not assignment.
|
||||
*/
|
||||
return (FALSE);
|
||||
} else {
|
||||
haveName = TRUE;
|
||||
wasSpace = FALSE;
|
||||
else {
|
||||
haveName = TRUE;
|
||||
wasSpace = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
line++;
|
||||
}
|
||||
|
||||
/*
|
||||
* A final check: if we stopped on a +, ?, ! or :, the next character must
|
||||
* be an = or it ain't a valid assignment
|
||||
*/
|
||||
if (((*line == '+') ||
|
||||
(*line == '?') ||
|
||||
(*line == ':') ||
|
||||
(*line == '!')) &&
|
||||
(line[1] != '='))
|
||||
{
|
||||
return (FALSE);
|
||||
} else {
|
||||
return (haveName);
|
||||
}
|
||||
return haveName;
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -1300,6 +1394,17 @@ Parse_DoVar (line, ctxt)
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef SUNSHCMD
|
||||
while (*opc != ':')
|
||||
if (--opc < line)
|
||||
break;
|
||||
|
||||
if (strncmp(opc, ":sh", 3) == 0) {
|
||||
type = VAR_SHELL;
|
||||
*opc = '\0';
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
type = VAR_NORMAL;
|
||||
break;
|
||||
}
|
||||
@ -1331,157 +1436,38 @@ Parse_DoVar (line, ctxt)
|
||||
Var_Set(line, cp, ctxt);
|
||||
free(cp);
|
||||
} else if (type == VAR_SHELL) {
|
||||
char *args[4]; /* Args for invoking the shell */
|
||||
int fds[2]; /* Pipe streams */
|
||||
int cpid; /* Child PID */
|
||||
int pid; /* PID from wait() */
|
||||
Boolean freeCmd; /* TRUE if the command needs to be freed, i.e.
|
||||
* if any variable expansion was performed */
|
||||
Boolean freeCmd = FALSE; /* TRUE if the command needs to be freed, i.e.
|
||||
* if any variable expansion was performed */
|
||||
char *res, *err;
|
||||
|
||||
/*
|
||||
* Avoid clobbered variable warnings by forcing the compiler
|
||||
* to ``unregister'' variables
|
||||
*/
|
||||
#if __GNUC__
|
||||
(void) &freeCmd;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up arguments for shell
|
||||
*/
|
||||
args[0] = "sh";
|
||||
args[1] = "-c";
|
||||
if (strchr(cp, '$') != (char *)NULL) {
|
||||
if (strchr(cp, '$') != NULL) {
|
||||
/*
|
||||
* There's a dollar sign in the command, so perform variable
|
||||
* expansion on the whole thing. The resulting string will need
|
||||
* freeing when we're done, so set freeCmd to TRUE.
|
||||
*/
|
||||
args[2] = Var_Subst(NULL, cp, VAR_CMD, TRUE);
|
||||
cp = Var_Subst(NULL, cp, VAR_CMD, TRUE);
|
||||
freeCmd = TRUE;
|
||||
} else {
|
||||
args[2] = cp;
|
||||
freeCmd = FALSE;
|
||||
}
|
||||
args[3] = (char *)NULL;
|
||||
|
||||
/*
|
||||
* Open a pipe for fetching its output
|
||||
*/
|
||||
pipe(fds);
|
||||
res = Cmd_Exec(cp, &err);
|
||||
Var_Set(line, res, ctxt);
|
||||
free(res);
|
||||
|
||||
/*
|
||||
* Fork
|
||||
*/
|
||||
cpid = vfork();
|
||||
if (cpid == 0) {
|
||||
/*
|
||||
* Close input side of pipe
|
||||
*/
|
||||
close(fds[0]);
|
||||
if (err)
|
||||
Parse_Error(PARSE_WARNING, err, cp);
|
||||
|
||||
/*
|
||||
* Duplicate the output stream to the shell's output, then
|
||||
* shut the extra thing down. Note we don't fetch the error
|
||||
* stream...why not? Why?
|
||||
*/
|
||||
dup2(fds[1], 1);
|
||||
close(fds[1]);
|
||||
|
||||
execv("/bin/sh", args);
|
||||
_exit(1);
|
||||
} else if (cpid < 0) {
|
||||
/*
|
||||
* Couldn't fork -- tell the user and make the variable null
|
||||
*/
|
||||
Parse_Error(PARSE_WARNING, "Couldn't exec \"%s\"", cp);
|
||||
Var_Set(line, "", ctxt);
|
||||
} else {
|
||||
int status;
|
||||
int cc;
|
||||
Buffer buf;
|
||||
char *res;
|
||||
|
||||
/*
|
||||
* No need for the writing half
|
||||
*/
|
||||
close(fds[1]);
|
||||
|
||||
buf = Buf_Init (MAKE_BSIZE);
|
||||
|
||||
do {
|
||||
char result[BUFSIZ];
|
||||
cc = read(fds[0], result, sizeof(result));
|
||||
if (cc > 0)
|
||||
Buf_AddBytes(buf, cc, (Byte *) result);
|
||||
}
|
||||
while (cc > 0 || (cc == -1 && errno == EINTR));
|
||||
|
||||
/*
|
||||
* Close the input side of the pipe.
|
||||
*/
|
||||
close(fds[0]);
|
||||
|
||||
/*
|
||||
* Wait for the process to exit.
|
||||
*/
|
||||
while(((pid = wait(&status)) != cpid) && (pid >= 0))
|
||||
continue;
|
||||
|
||||
if (cc == -1) {
|
||||
/*
|
||||
* Couldn't read all of the child's output -- tell the user
|
||||
* but still use whatever we read. Null output isn't an
|
||||
* error unless there was an error reading it.
|
||||
*/
|
||||
Parse_Error(PARSE_WARNING, "Couldn't read shell's output");
|
||||
}
|
||||
|
||||
res = (char *)Buf_GetAll (buf, &cc);
|
||||
Buf_Destroy (buf, FALSE);
|
||||
|
||||
if (status) {
|
||||
/*
|
||||
* Child returned an error -- tell the user but still use
|
||||
* the result.
|
||||
*/
|
||||
Parse_Error(PARSE_WARNING, "\"%s\" returned non-zero", cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Null-terminate the result, convert newlines to spaces and
|
||||
* install it in the variable.
|
||||
*/
|
||||
res[cc] = '\0';
|
||||
cp = &res[cc] - 1;
|
||||
|
||||
if (*cp == '\n') {
|
||||
/*
|
||||
* A final newline is just stripped
|
||||
*/
|
||||
*cp-- = '\0';
|
||||
}
|
||||
while (cp >= res) {
|
||||
if (*cp == '\n') {
|
||||
*cp = ' ';
|
||||
}
|
||||
cp--;
|
||||
}
|
||||
Var_Set(line, res, ctxt);
|
||||
free(res);
|
||||
|
||||
}
|
||||
if (freeCmd) {
|
||||
free(args[2]);
|
||||
}
|
||||
if (freeCmd)
|
||||
free(cp);
|
||||
} else {
|
||||
/*
|
||||
* Normal assignment -- just do it.
|
||||
*/
|
||||
Var_Set (line, cp, ctxt);
|
||||
Var_Set(line, cp, ctxt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
* ParseAddCmd --
|
||||
* Lst_ForEach function to add a command line to all targets
|
||||
@ -1639,17 +1625,20 @@ ParseDoInclude (file)
|
||||
* leading path components and call Dir_FindFile to see if
|
||||
* we can locate the beast.
|
||||
*/
|
||||
char *prefEnd;
|
||||
char *prefEnd, *Fname;
|
||||
|
||||
prefEnd = strrchr (fname, '/');
|
||||
/* Make a temporary copy of this, to be safe. */
|
||||
Fname = estrdup(fname);
|
||||
|
||||
prefEnd = strrchr (Fname, '/');
|
||||
if (prefEnd != (char *)NULL) {
|
||||
char *newName;
|
||||
|
||||
*prefEnd = '\0';
|
||||
if (file[0] == '/')
|
||||
newName = strdup(file);
|
||||
newName = estrdup(file);
|
||||
else
|
||||
newName = str_concat (fname, file, STR_ADDSLASH);
|
||||
newName = str_concat (Fname, file, STR_ADDSLASH);
|
||||
fullname = Dir_FindFile (newName, parseIncPath);
|
||||
if (fullname == (char *)NULL) {
|
||||
fullname = Dir_FindFile(newName, dirSearchPath);
|
||||
@ -1659,6 +1648,7 @@ ParseDoInclude (file)
|
||||
} else {
|
||||
fullname = (char *)NULL;
|
||||
}
|
||||
free (Fname);
|
||||
} else {
|
||||
fullname = (char *)NULL;
|
||||
}
|
||||
@ -1763,7 +1753,7 @@ Parse_FromString(str)
|
||||
curPTR = (PTR *) emalloc (sizeof (PTR));
|
||||
curPTR->str = curPTR->ptr = str;
|
||||
lineno = 0;
|
||||
fname = strdup(fname);
|
||||
fname = estrdup(fname);
|
||||
}
|
||||
|
||||
|
||||
@ -2189,7 +2179,11 @@ test_char:
|
||||
break;
|
||||
case '#':
|
||||
if (!ignComment) {
|
||||
if (compatMake && (lastc != '\\')) {
|
||||
if (
|
||||
#if 0
|
||||
compatMake &&
|
||||
#endif
|
||||
(lastc != '\\')) {
|
||||
/*
|
||||
* If the character is a hash mark and it isn't escaped
|
||||
* (or we're being compatible), the thing is a comment.
|
||||
@ -2247,7 +2241,7 @@ test_char:
|
||||
while (*ep)
|
||||
++ep;
|
||||
while (ep > line + 1 && (ep[-1] == ' ' || ep[-1] == '\t')) {
|
||||
if (ep[-2] == '\\')
|
||||
if (ep > line + 1 && ep[-2] == '\\')
|
||||
break;
|
||||
--ep;
|
||||
}
|
||||
@ -2421,13 +2415,13 @@ Parse_File(name, stream)
|
||||
continue;
|
||||
} else {
|
||||
Parse_Error (PARSE_FATAL,
|
||||
"Unassociated shell command \"%.20s\"",
|
||||
"Unassociated shell command \"%s\"",
|
||||
cp);
|
||||
}
|
||||
}
|
||||
#ifdef SYSVINCLUDE
|
||||
} else if (strncmp (line, "include", 7) == 0 &&
|
||||
isspace(line[7]) &&
|
||||
isspace((unsigned char) line[7]) &&
|
||||
strchr(line, ':') == NULL) {
|
||||
/*
|
||||
* It's an S3/S5-style "include".
|
||||
@ -2536,30 +2530,11 @@ Parse_File(name, stream)
|
||||
void
|
||||
Parse_Init ()
|
||||
{
|
||||
char *cp = NULL, *start;
|
||||
/* avoid faults on read-only strings */
|
||||
static char syspath[] = _PATH_DEFSYSPATH;
|
||||
|
||||
mainNode = NILGNODE;
|
||||
parseIncPath = Lst_Init (FALSE);
|
||||
sysIncPath = Lst_Init (FALSE);
|
||||
includes = Lst_Init (FALSE);
|
||||
targCmds = Lst_Init (FALSE);
|
||||
|
||||
/*
|
||||
* Add the directories from the DEFSYSPATH (more than one may be given
|
||||
* as dir1:...:dirn) to the system include path.
|
||||
*/
|
||||
for (start = syspath; *start != '\0'; start = cp) {
|
||||
for (cp = start; *cp != '\0' && *cp != ':'; cp++)
|
||||
continue;
|
||||
if (*cp == '\0') {
|
||||
Dir_AddDir(sysIncPath, start);
|
||||
} else {
|
||||
*cp++ = '\0';
|
||||
Dir_AddDir(sysIncPath, start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -31,11 +31,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pathnames.h 5.2 (Berkeley) 6/1/90
|
||||
* $Id: pathnames.h,v 1.3 1996/06/24 04:24:35 jkh Exp $
|
||||
* $Id: pathnames.h,v 1.4 1996/09/18 06:06:39 swallace Exp $
|
||||
*/
|
||||
|
||||
#define _PATH_OBJDIR "obj"
|
||||
#define _PATH_OBJDIRPREFIX "/usr/obj"
|
||||
#define _PATH_DEFSHELLDIR "/bin"
|
||||
#define _PATH_DEFSYSMK "/usr/share/mk/sys.mk"
|
||||
#define _PATH_DEFSYSMK "sys.mk"
|
||||
#define _PATH_DEFSYSPATH "/usr/share/mk"
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sprite.h 8.1 (Berkeley) 6/6/93
|
||||
* from: @(#)sprite.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
#ifndef lint
|
||||
/* from: static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; */
|
||||
static char *rcsid = "$Id: str.c,v 1.4 1995/05/30 06:32:05 rgrimes Exp $";
|
||||
static char *rcsid = "$Id: str.c,v 1.5 1995/06/18 12:34:12 ache Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "make.h"
|
||||
@ -55,7 +55,7 @@ void
|
||||
str_init()
|
||||
{
|
||||
char *p1;
|
||||
argv = (char **)emalloc((argmax = 50) * sizeof(char *));
|
||||
argv = (char **)emalloc(((argmax = 50) + 1) * sizeof(char *));
|
||||
argv[0] = Var_Value(".MAKE", VAR_GLOBAL, &p1);
|
||||
}
|
||||
|
||||
@ -202,9 +202,8 @@ brk_string(str, store_argc, expand)
|
||||
*t++ = '\0';
|
||||
if (argc == argmax) {
|
||||
argmax *= 2; /* ramp up fast */
|
||||
if (!(argv = (char **)realloc(argv,
|
||||
argmax * sizeof(char *))))
|
||||
enomem();
|
||||
argv = (char **)erealloc(argv,
|
||||
(argmax + 1) * sizeof(char *));
|
||||
}
|
||||
argv[argc++] = start;
|
||||
start = (char *)NULL;
|
||||
|
@ -95,7 +95,6 @@ static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94";
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
#include "dir.h"
|
||||
#include "bit.h"
|
||||
|
||||
static Lst sufflist; /* Lst of suffixes */
|
||||
static Lst suffClean; /* Lst of suffixes to be cleaned */
|
||||
@ -159,6 +158,7 @@ static int SuffSuffIsSuffixP __P((ClientData, ClientData));
|
||||
static int SuffSuffHasNameP __P((ClientData, ClientData));
|
||||
static int SuffSuffIsPrefix __P((ClientData, ClientData));
|
||||
static int SuffGNHasNameP __P((ClientData, ClientData));
|
||||
static void SuffUnRef __P((ClientData, ClientData));
|
||||
static void SuffFree __P((ClientData));
|
||||
static void SuffInsert __P((Lst, Suff *));
|
||||
static void SuffRemove __P((Lst, Suff *));
|
||||
@ -796,7 +796,7 @@ Suff_AddSuffix (str)
|
||||
if (ln == NILLNODE) {
|
||||
s = (Suff *) emalloc (sizeof (Suff));
|
||||
|
||||
s->name = strdup (str);
|
||||
s->name = estrdup (str);
|
||||
s->nameLen = strlen (s->name);
|
||||
s->searchPath = Lst_Init (FALSE);
|
||||
s->children = Lst_Init (FALSE);
|
||||
@ -1003,7 +1003,7 @@ SuffAddSrc (sp, lsp)
|
||||
* that...
|
||||
*/
|
||||
s2 = (Src *) emalloc (sizeof (Src));
|
||||
s2->file = strdup(targ->pref);
|
||||
s2->file = estrdup(targ->pref);
|
||||
s2->pref = targ->pref;
|
||||
s2->parent = targ;
|
||||
s2->node = NILGNODE;
|
||||
@ -1266,7 +1266,7 @@ SuffFindCmds (targ, slst)
|
||||
* again (ick)), and return the new structure.
|
||||
*/
|
||||
ret = (Src *)emalloc (sizeof (Src));
|
||||
ret->file = strdup(s->name);
|
||||
ret->file = estrdup(s->name);
|
||||
ret->pref = targ->pref;
|
||||
ret->suff = suff;
|
||||
suff->refCount++;
|
||||
@ -1841,7 +1841,8 @@ SuffFindNormalDeps(gn, slst)
|
||||
* children, then look for any overriding transformations they imply.
|
||||
* Should we find one, we discard the one we found before.
|
||||
*/
|
||||
while(ln != NILLNODE) {
|
||||
|
||||
while (ln != NILLNODE) {
|
||||
/*
|
||||
* Look for next possible suffix...
|
||||
*/
|
||||
@ -1855,7 +1856,7 @@ SuffFindNormalDeps(gn, slst)
|
||||
* Allocate a Src structure to which things can be transformed
|
||||
*/
|
||||
targ = (Src *)emalloc(sizeof (Src));
|
||||
targ->file = strdup(gn->name);
|
||||
targ->file = estrdup(gn->name);
|
||||
targ->suff = (Suff *)Lst_Datum(ln);
|
||||
targ->suff->refCount++;
|
||||
targ->node = gn;
|
||||
@ -1900,13 +1901,13 @@ SuffFindNormalDeps(gn, slst)
|
||||
}
|
||||
|
||||
targ = (Src *)emalloc(sizeof (Src));
|
||||
targ->file = strdup(gn->name);
|
||||
targ->file = estrdup(gn->name);
|
||||
targ->suff = suffNull;
|
||||
targ->suff->refCount++;
|
||||
targ->node = gn;
|
||||
targ->parent = (Src *)NULL;
|
||||
targ->children = 0;
|
||||
targ->pref = strdup(sopref);
|
||||
targ->pref = estrdup(sopref);
|
||||
#ifdef DEBUG_SRC
|
||||
targ->cp = Lst_Init(FALSE);
|
||||
#endif
|
||||
@ -1916,7 +1917,7 @@ SuffFindNormalDeps(gn, slst)
|
||||
* or dependencies defined for this gnode
|
||||
*/
|
||||
if (Lst_IsEmpty(gn->commands) && Lst_IsEmpty(gn->children))
|
||||
SuffAddLevel(srcs, targ);
|
||||
SuffAddLevel(srcs, targ);
|
||||
else {
|
||||
if (DEBUG(SUFF))
|
||||
printf("not ");
|
||||
@ -1988,6 +1989,7 @@ sfnd_abort:
|
||||
(targ == NULL ? dirSearchPath :
|
||||
targ->suff->searchPath));
|
||||
if (gn->path != NULL) {
|
||||
char *ptr;
|
||||
Var_Set(TARGET, gn->path, gn);
|
||||
|
||||
if (targ != NULL) {
|
||||
@ -1995,7 +1997,7 @@ sfnd_abort:
|
||||
* Suffix known for the thing -- trim the suffix off
|
||||
* the path to form the proper .PREFIX variable.
|
||||
*/
|
||||
int len = strlen(gn->path);
|
||||
int savep = strlen(gn->path) - targ->suff->nameLen;
|
||||
char savec;
|
||||
|
||||
if (gn->suffix)
|
||||
@ -2003,12 +2005,17 @@ sfnd_abort:
|
||||
gn->suffix = targ->suff;
|
||||
gn->suffix->refCount++;
|
||||
|
||||
savec = gn->path[len-targ->suff->nameLen];
|
||||
gn->path[len-targ->suff->nameLen] = '\0';
|
||||
savec = gn->path[savep];
|
||||
gn->path[savep] = '\0';
|
||||
|
||||
Var_Set(PREFIX, gn->path, gn);
|
||||
if ((ptr = strrchr(gn->path, '/')) != NULL)
|
||||
ptr++;
|
||||
else
|
||||
ptr = gn->path;
|
||||
|
||||
gn->path[len-targ->suff->nameLen] = savec;
|
||||
Var_Set(PREFIX, ptr, gn);
|
||||
|
||||
gn->path[savep] = savec;
|
||||
} else {
|
||||
/*
|
||||
* The .PREFIX gets the full path if the target has
|
||||
@ -2018,7 +2025,12 @@ sfnd_abort:
|
||||
gn->suffix->refCount--;
|
||||
gn->suffix = NULL;
|
||||
|
||||
Var_Set(PREFIX, gn->path, gn);
|
||||
if ((ptr = strrchr(gn->path, '/')) != NULL)
|
||||
ptr++;
|
||||
else
|
||||
ptr = gn->path;
|
||||
|
||||
Var_Set(PREFIX, ptr, gn);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2034,7 +2046,7 @@ sfnd_abort:
|
||||
gn->suffix->refCount++;
|
||||
if (gn->path != NULL)
|
||||
free(gn->path);
|
||||
gn->path = strdup(gn->name);
|
||||
gn->path = estrdup(gn->name);
|
||||
}
|
||||
|
||||
goto sfnd_return;
|
||||
@ -2135,7 +2147,7 @@ sfnd_abort:
|
||||
*/
|
||||
if (gn->path)
|
||||
free(gn->path);
|
||||
gn->path = strdup(gn->name);
|
||||
gn->path = estrdup(gn->name);
|
||||
|
||||
/*
|
||||
* Nuke the transformation path and the Src structures left over in the
|
||||
@ -2316,7 +2328,7 @@ Suff_Init ()
|
||||
*/
|
||||
emptySuff = suffNull = (Suff *) emalloc (sizeof (Suff));
|
||||
|
||||
suffNull->name = strdup ("");
|
||||
suffNull->name = estrdup ("");
|
||||
suffNull->nameLen = 0;
|
||||
suffNull->searchPath = Lst_Init (FALSE);
|
||||
Dir_Concat(suffNull->searchPath, dirSearchPath);
|
||||
|
@ -158,7 +158,7 @@ Targ_NewGN (name)
|
||||
register GNode *gn;
|
||||
|
||||
gn = (GNode *) emalloc (sizeof (GNode));
|
||||
gn->name = strdup (name);
|
||||
gn->name = estrdup (name);
|
||||
gn->path = (char *) 0;
|
||||
if (name[0] == '-' && name[1] == 'l') {
|
||||
gn->type = OP_LIB;
|
||||
@ -169,6 +169,7 @@ Targ_NewGN (name)
|
||||
gn->make = FALSE;
|
||||
gn->made = UNMADE;
|
||||
gn->childMade = FALSE;
|
||||
gn->order = 0;
|
||||
gn->mtime = gn->cmtime = 0;
|
||||
gn->iParents = Lst_Init (FALSE);
|
||||
gn->cohorts = Lst_Init (FALSE);
|
||||
@ -467,9 +468,9 @@ Targ_FmtTime (time)
|
||||
|
||||
parts = localtime(&time);
|
||||
|
||||
sprintf (buf, "%d:%02d:%02d %s %d, 19%d",
|
||||
sprintf (buf, "%d:%02d:%02d %s %d, %d",
|
||||
parts->tm_hour, parts->tm_min, parts->tm_sec,
|
||||
months[parts->tm_mon], parts->tm_mday, parts->tm_year);
|
||||
months[parts->tm_mon], parts->tm_mday, 1900 + parts->tm_year);
|
||||
return(buf);
|
||||
}
|
||||
|
||||
|
349
usr.bin/make/util.c
Normal file
349
usr.bin/make/util.c
Normal file
@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Missing stuff from OS's
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$NetBSD: util.c,v 1.7 1996/08/30 17:59:44 thorpej Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "make.h"
|
||||
|
||||
#if !__STDC__
|
||||
# ifndef const
|
||||
# define const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef sun
|
||||
|
||||
|
||||
|
||||
extern int errno, sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
|
||||
char *
|
||||
strerror(e)
|
||||
int e;
|
||||
{
|
||||
static char buf[100];
|
||||
if (e < 0 || e >= sys_nerr) {
|
||||
sprintf(buf, "Unknown error %d", e);
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
return sys_errlist[e];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ultrix
|
||||
#include <string.h>
|
||||
|
||||
/* strdup
|
||||
*
|
||||
* Make a duplicate of a string.
|
||||
* For systems which lack this function.
|
||||
*/
|
||||
char *
|
||||
strdup(str)
|
||||
const char *str;
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
len = strlen(str) + 1;
|
||||
if ((p = malloc(len)) == NULL)
|
||||
return NULL;
|
||||
|
||||
return memcpy(p, str, len);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(sun) || defined(__hpux) || defined(__sgi)
|
||||
|
||||
int
|
||||
setenv(name, value, dum)
|
||||
const char *name;
|
||||
const char *value;
|
||||
int dum;
|
||||
{
|
||||
register char *p;
|
||||
int len = strlen(name) + strlen(value) + 2; /* = \0 */
|
||||
char *ptr = (char*) malloc(len);
|
||||
|
||||
(void) dum;
|
||||
|
||||
if (ptr == NULL)
|
||||
return -1;
|
||||
|
||||
p = ptr;
|
||||
|
||||
while (*name)
|
||||
*p++ = *name++;
|
||||
|
||||
*p++ = '=';
|
||||
|
||||
while (*value)
|
||||
*p++ = *value++;
|
||||
|
||||
*p = '\0';
|
||||
|
||||
len = putenv(ptr);
|
||||
/* free(ptr); */
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __hpux
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
int
|
||||
killpg(pid, sig)
|
||||
int pid, sig;
|
||||
{
|
||||
return kill(-pid, sig);
|
||||
}
|
||||
|
||||
void
|
||||
srandom(seed)
|
||||
long seed;
|
||||
{
|
||||
srand48(seed);
|
||||
}
|
||||
|
||||
long
|
||||
random()
|
||||
{
|
||||
return lrand48();
|
||||
}
|
||||
|
||||
/* turn into bsd signals */
|
||||
void (*
|
||||
signal(s, a)) ()
|
||||
int s;
|
||||
void (*a)();
|
||||
{
|
||||
struct sigvec osv, sv;
|
||||
|
||||
(void) sigvector(s, (struct sigvec *) 0, &osv);
|
||||
sv = osv;
|
||||
sv.sv_handler = a;
|
||||
#ifdef SV_BSDSIG
|
||||
sv.sv_flags = SV_BSDSIG;
|
||||
#endif
|
||||
|
||||
if (sigvector(s, &sv, (struct sigvec *) 0) == -1)
|
||||
return (BADSIG);
|
||||
return (osv.sv_handler);
|
||||
}
|
||||
|
||||
#if !defined(BSD) && !defined(d_fileno)
|
||||
# define d_fileno d_ino
|
||||
#endif
|
||||
|
||||
#ifndef DEV_DEV_COMPARE
|
||||
# define DEV_DEV_COMPARE(a, b) ((a) == (b))
|
||||
#endif
|
||||
#define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
|
||||
#define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
|
||||
|
||||
|
||||
/* strrcpy():
|
||||
* Like strcpy, going backwards and returning the new pointer
|
||||
*/
|
||||
static char *
|
||||
strrcpy(ptr, str)
|
||||
register char *ptr, *str;
|
||||
{
|
||||
register int len = strlen(str);
|
||||
|
||||
while (len)
|
||||
*--ptr = str[--len];
|
||||
|
||||
return (ptr);
|
||||
} /* end strrcpy */
|
||||
|
||||
|
||||
char *
|
||||
getwd(pathname)
|
||||
char *pathname;
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
extern int errno;
|
||||
|
||||
struct stat st_root, st_cur, st_next, st_dotdot;
|
||||
char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
|
||||
char *pathptr, *nextpathptr, *cur_name_add;
|
||||
|
||||
/* find the inode of root */
|
||||
if (stat("/", &st_root) == -1) {
|
||||
(void) sprintf(pathname,
|
||||
"getwd: Cannot stat \"/\" (%s)", strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
pathbuf[MAXPATHLEN - 1] = '\0';
|
||||
pathptr = &pathbuf[MAXPATHLEN - 1];
|
||||
nextpathbuf[MAXPATHLEN - 1] = '\0';
|
||||
cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
|
||||
|
||||
/* find the inode of the current directory */
|
||||
if (lstat(".", &st_cur) == -1) {
|
||||
(void) sprintf(pathname,
|
||||
"getwd: Cannot stat \".\" (%s)", strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
nextpathptr = strrcpy(nextpathptr, "../");
|
||||
|
||||
/* Descend to root */
|
||||
for (;;) {
|
||||
|
||||
/* look if we found root yet */
|
||||
if (st_cur.st_ino == st_root.st_ino &&
|
||||
DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
|
||||
(void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
|
||||
return (pathname);
|
||||
}
|
||||
|
||||
/* open the parent directory */
|
||||
if (stat(nextpathptr, &st_dotdot) == -1) {
|
||||
(void) sprintf(pathname,
|
||||
"getwd: Cannot stat directory \"%s\" (%s)",
|
||||
nextpathptr, strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
if ((dp = opendir(nextpathptr)) == NULL) {
|
||||
(void) sprintf(pathname,
|
||||
"getwd: Cannot open directory \"%s\" (%s)",
|
||||
nextpathptr, strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* look in the parent for the entry with the same inode */
|
||||
if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
|
||||
/* Parent has same device. No need to stat every member */
|
||||
for (d = readdir(dp); d != NULL; d = readdir(dp))
|
||||
if (d->d_fileno == st_cur.st_ino)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Parent has a different device. This is a mount point so we
|
||||
* need to stat every member
|
||||
*/
|
||||
for (d = readdir(dp); d != NULL; d = readdir(dp)) {
|
||||
if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
|
||||
continue;
|
||||
(void) strcpy(cur_name_add, d->d_name);
|
||||
if (lstat(nextpathptr, &st_next) == -1) {
|
||||
(void) sprintf(pathname, "getwd: Cannot stat \"%s\" (%s)",
|
||||
d->d_name, strerror(errno));
|
||||
(void) closedir(dp);
|
||||
return (NULL);
|
||||
}
|
||||
/* check if we found it yet */
|
||||
if (st_next.st_ino == st_cur.st_ino &&
|
||||
DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == NULL) {
|
||||
(void) sprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
|
||||
(void) closedir(dp);
|
||||
return (NULL);
|
||||
}
|
||||
st_cur = st_dotdot;
|
||||
pathptr = strrcpy(pathptr, d->d_name);
|
||||
pathptr = strrcpy(pathptr, "/");
|
||||
nextpathptr = strrcpy(nextpathptr, "../");
|
||||
(void) closedir(dp);
|
||||
*cur_name_add = '\0';
|
||||
}
|
||||
} /* end getwd */
|
||||
|
||||
|
||||
char *sys_siglist[] = {
|
||||
"Signal 0",
|
||||
"Hangup", /* SIGHUP */
|
||||
"Interrupt", /* SIGINT */
|
||||
"Quit", /* SIGQUIT */
|
||||
"Illegal instruction", /* SIGILL */
|
||||
"Trace/BPT trap", /* SIGTRAP */
|
||||
"IOT trap", /* SIGIOT */
|
||||
"EMT trap", /* SIGEMT */
|
||||
"Floating point exception", /* SIGFPE */
|
||||
"Killed", /* SIGKILL */
|
||||
"Bus error", /* SIGBUS */
|
||||
"Segmentation fault", /* SIGSEGV */
|
||||
"Bad system call", /* SIGSYS */
|
||||
"Broken pipe", /* SIGPIPE */
|
||||
"Alarm clock", /* SIGALRM */
|
||||
"Terminated", /* SIGTERM */
|
||||
"User defined signal 1", /* SIGUSR1 */
|
||||
"User defined signal 2", /* SIGUSR2 */
|
||||
"Child exited", /* SIGCLD */
|
||||
"Power-fail restart", /* SIGPWR */
|
||||
"Virtual timer expired", /* SIGVTALRM */
|
||||
"Profiling timer expired", /* SIGPROF */
|
||||
"I/O possible", /* SIGIO */
|
||||
"Window size changes", /* SIGWINDOW */
|
||||
"Stopped (signal)", /* SIGSTOP */
|
||||
"Stopped", /* SIGTSTP */
|
||||
"Continued", /* SIGCONT */
|
||||
"Stopped (tty input)", /* SIGTTIN */
|
||||
"Stopped (tty output)", /* SIGTTOU */
|
||||
"Urgent I/O condition", /* SIGURG */
|
||||
"Remote lock lost (NFS)", /* SIGLOST */
|
||||
"Signal 31", /* reserved */
|
||||
"DIL signal" /* SIGDIL */
|
||||
};
|
||||
|
||||
int
|
||||
utimes(file, tvp)
|
||||
char *file;
|
||||
struct timeval tvp[2];
|
||||
{
|
||||
struct utimbuf t;
|
||||
|
||||
t.actime = tvp[0].tv_sec;
|
||||
t.modtime = tvp[1].tv_sec;
|
||||
return(utime(file, &t));
|
||||
}
|
||||
|
||||
|
||||
#endif /* __hpux */
|
||||
|
||||
#if defined(sun) && defined(__svr4__)
|
||||
#include <signal.h>
|
||||
|
||||
/* turn into bsd signals */
|
||||
void (*
|
||||
signal(s, a)) ()
|
||||
int s;
|
||||
void (*a)();
|
||||
{
|
||||
struct sigaction sa, osa;
|
||||
|
||||
sa.sa_handler = a;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART;
|
||||
|
||||
if (sigaction(s, &sa, &osa) == -1)
|
||||
return SIG_ERR;
|
||||
else
|
||||
return osa.sa_handler;
|
||||
}
|
||||
|
||||
#endif
|
@ -158,7 +158,9 @@ static Boolean VarTail __P((char *, Boolean, Buffer, ClientData));
|
||||
static Boolean VarSuffix __P((char *, Boolean, Buffer, ClientData));
|
||||
static Boolean VarRoot __P((char *, Boolean, Buffer, ClientData));
|
||||
static Boolean VarMatch __P((char *, Boolean, Buffer, ClientData));
|
||||
#ifdef SYSVVARSUB
|
||||
static Boolean VarSYSVMatch __P((char *, Boolean, Buffer, ClientData));
|
||||
#endif
|
||||
static Boolean VarNoMatch __P((char *, Boolean, Buffer, ClientData));
|
||||
static Boolean VarSubstitute __P((char *, Boolean, Buffer, ClientData));
|
||||
static char *VarModify __P((char *, Boolean (*)(char *, Boolean, Buffer,
|
||||
@ -272,7 +274,7 @@ VarFind (name, ctxt, flags)
|
||||
int len;
|
||||
|
||||
v = (Var *) emalloc(sizeof(Var));
|
||||
v->name = strdup(name);
|
||||
v->name = estrdup(name);
|
||||
|
||||
len = strlen(env);
|
||||
|
||||
@ -325,7 +327,7 @@ VarAdd (name, val, ctxt)
|
||||
|
||||
v = (Var *) emalloc (sizeof (Var));
|
||||
|
||||
v->name = strdup (name);
|
||||
v->name = estrdup (name);
|
||||
|
||||
len = val ? strlen(val) : 0;
|
||||
v->val = Buf_Init(len+1);
|
||||
@ -775,8 +777,7 @@ VarMatch (word, addSpace, buf, pattern)
|
||||
return(addSpace);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef SYSVVARSUB
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* VarSYSVMatch --
|
||||
@ -818,6 +819,7 @@ VarSYSVMatch (word, addSpace, buf, patp)
|
||||
|
||||
return(addSpace);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-
|
||||
@ -1100,7 +1102,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
|
||||
Boolean haveModifier;/* TRUE if have modifiers for the variable */
|
||||
register char endc; /* Ending character when variable in parens
|
||||
* or braces */
|
||||
register char startc; /* Starting character when variable in parens
|
||||
register char startc=0; /* Starting character when variable in parens
|
||||
* or braces */
|
||||
int cnt; /* Used to count brace pairs when variable in
|
||||
* in parens or braces */
|
||||
@ -1617,7 +1619,22 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
|
||||
break;
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
default: {
|
||||
#ifdef SUNSHCMD
|
||||
case 's':
|
||||
if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
|
||||
char *err;
|
||||
newStr = Cmd_Exec (str, &err);
|
||||
if (err)
|
||||
Error (err, str);
|
||||
cp = tstr + 2;
|
||||
termc = *cp;
|
||||
break;
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
#ifdef SYSVVARSUB
|
||||
/*
|
||||
* This can either be a bogus modifier or a System-V
|
||||
* substitution command.
|
||||
@ -1684,7 +1701,9 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
|
||||
pattern.lhs[pattern.leftLen] = '=';
|
||||
pattern.rhs[pattern.rightLen] = endc;
|
||||
termc = endc;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
Error ("Unknown modifier '%c'\n", *tstr);
|
||||
for (cp = tstr+1;
|
||||
*cp != ':' && *cp != endc && *cp != '\0';
|
||||
|
Loading…
Reference in New Issue
Block a user