Merge branch 'illumos'

This commit is contained in:
Georg Sauthoff 2016-08-21 15:01:27 +02:00
commit 83e0598cad
67 changed files with 29814 additions and 0 deletions

384
COPYING Normal file
View file

@ -0,0 +1,384 @@
Unless otherwise noted, all files in this distribution are released
under the Common Development and Distribution License (CDDL).
Exceptions are noted within the associated source files.
--------------------------------------------------------------------
COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0
1. Definitions.
1.1. "Contributor" means each individual or entity that creates
or contributes to the creation of Modifications.
1.2. "Contributor Version" means the combination of the Original
Software, prior Modifications used by a Contributor (if any),
and the Modifications made by that particular Contributor.
1.3. "Covered Software" means (a) the Original Software, or (b)
Modifications, or (c) the combination of files containing
Original Software with files containing Modifications, in
each case including portions thereof.
1.4. "Executable" means the Covered Software in any form other
than Source Code.
1.5. "Initial Developer" means the individual or entity that first
makes Original Software available under this License.
1.6. "Larger Work" means a work which combines Covered Software or
portions thereof with code not governed by the terms of this
License.
1.7. "License" means this document.
1.8. "Licensable" means having the right to grant, to the maximum
extent possible, whether at the time of the initial grant or
subsequently acquired, any and all of the rights conveyed
herein.
1.9. "Modifications" means the Source Code and Executable form of
any of the following:
A. Any file that results from an addition to, deletion from or
modification of the contents of a file containing Original
Software or previous Modifications;
B. Any new file that contains any part of the Original
Software or previous Modifications; or
C. Any new file that is contributed or otherwise made
available under the terms of this License.
1.10. "Original Software" means the Source Code and Executable
form of computer software code that is originally released
under this License.
1.11. "Patent Claims" means any patent claim(s), now owned or
hereafter acquired, including without limitation, method,
process, and apparatus claims, in any patent Licensable by
grantor.
1.12. "Source Code" means (a) the common form of computer software
code in which modifications are made and (b) associated
documentation included in or with such code.
1.13. "You" (or "Your") means an individual or a legal entity
exercising rights under, and complying with all of the terms
of, this License. For legal entities, "You" includes any
entity which controls, is controlled by, or is under common
control with You. For purposes of this definition,
"control" means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by
contract or otherwise, or (b) ownership of more than fifty
percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants.
2.1. The Initial Developer Grant.
Conditioned upon Your compliance with Section 3.1 below and
subject to third party intellectual property claims, the Initial
Developer hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or
trademark) Licensable by Initial Developer, to use,
reproduce, modify, display, perform, sublicense and
distribute the Original Software (or portions thereof),
with or without Modifications, and/or as part of a Larger
Work; and
(b) under Patent Claims infringed by the making, using or
selling of Original Software, to make, have made, use,
practice, sell, and offer for sale, and/or otherwise
dispose of the Original Software (or portions thereof).
(c) The licenses granted in Sections 2.1(a) and (b) are
effective on the date Initial Developer first distributes
or otherwise makes the Original Software available to a
third party under the terms of this License.
(d) Notwithstanding Section 2.1(b) above, no patent license is
granted: (1) for code that You delete from the Original
Software, or (2) for infringements caused by: (i) the
modification of the Original Software, or (ii) the
combination of the Original Software with other software
or devices.
2.2. Contributor Grant.
Conditioned upon Your compliance with Section 3.1 below and
subject to third party intellectual property claims, each
Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or
trademark) Licensable by Contributor to use, reproduce,
modify, display, perform, sublicense and distribute the
Modifications created by such Contributor (or portions
thereof), either on an unmodified basis, with other
Modifications, as Covered Software and/or as part of a
Larger Work; and
(b) under Patent Claims infringed by the making, using, or
selling of Modifications made by that Contributor either
alone and/or in combination with its Contributor Version
(or portions of such combination), to make, use, sell,
offer for sale, have made, and/or otherwise dispose of:
(1) Modifications made by that Contributor (or portions
thereof); and (2) the combination of Modifications made by
that Contributor with its Contributor Version (or portions
of such combination).
(c) The licenses granted in Sections 2.2(a) and 2.2(b) are
effective on the date Contributor first distributes or
otherwise makes the Modifications available to a third
party.
(d) Notwithstanding Section 2.2(b) above, no patent license is
granted: (1) for any code that Contributor has deleted
from the Contributor Version; (2) for infringements caused
by: (i) third party modifications of Contributor Version,
or (ii) the combination of Modifications made by that
Contributor with other software (except as part of the
Contributor Version) or other devices; or (3) under Patent
Claims infringed by Covered Software in the absence of
Modifications made by that Contributor.
3. Distribution Obligations.
3.1. Availability of Source Code.
Any Covered Software that You distribute or otherwise make
available in Executable form must also be made available in Source
Code form and that Source Code form must be distributed only under
the terms of this License. You must include a copy of this
License with every copy of the Source Code form of the Covered
Software You distribute or otherwise make available. You must
inform recipients of any such Covered Software in Executable form
as to how they can obtain such Covered Software in Source Code
form in a reasonable manner on or through a medium customarily
used for software exchange.
3.2. Modifications.
The Modifications that You create or to which You contribute are
governed by the terms of this License. You represent that You
believe Your Modifications are Your original creation(s) and/or
You have sufficient rights to grant the rights conveyed by this
License.
3.3. Required Notices.
You must include a notice in each of Your Modifications that
identifies You as the Contributor of the Modification. You may
not remove or alter any copyright, patent or trademark notices
contained within the Covered Software, or any notices of licensing
or any descriptive text giving attribution to any Contributor or
the Initial Developer.
3.4. Application of Additional Terms.
You may not offer or impose any terms on any Covered Software in
Source Code form that alters or restricts the applicable version
of this License or the recipients' rights hereunder. You may
choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of
Covered Software. However, you may do so only on Your own behalf,
and not on behalf of the Initial Developer or any Contributor.
You must make it absolutely clear that any such warranty, support,
indemnity or liability obligation is offered by You alone, and You
hereby agree to indemnify the Initial Developer and every
Contributor for any liability incurred by the Initial Developer or
such Contributor as a result of warranty, support, indemnity or
liability terms You offer.
3.5. Distribution of Executable Versions.
You may distribute the Executable form of the Covered Software
under the terms of this License or under the terms of a license of
Your choice, which may contain terms different from this License,
provided that You are in compliance with the terms of this License
and that the license for the Executable form does not attempt to
limit or alter the recipient's rights in the Source Code form from
the rights set forth in this License. If You distribute the
Covered Software in Executable form under a different license, You
must make it absolutely clear that any terms which differ from
this License are offered by You alone, not by the Initial
Developer or Contributor. You hereby agree to indemnify the
Initial Developer and every Contributor for any liability incurred
by the Initial Developer or such Contributor as a result of any
such terms You offer.
3.6. Larger Works.
You may create a Larger Work by combining Covered Software with
other code not governed by the terms of this License and
distribute the Larger Work as a single product. In such a case,
You must make sure the requirements of this License are fulfilled
for the Covered Software.
4. Versions of the License.
4.1. New Versions.
Sun Microsystems, Inc. is the initial license steward and may
publish revised and/or new versions of this License from time to
time. Each version will be given a distinguishing version number.
Except as provided in Section 4.3, no one other than the license
steward has the right to modify this License.
4.2. Effect of New Versions.
You may always continue to use, distribute or otherwise make the
Covered Software available under the terms of the version of the
License under which You originally received the Covered Software.
If the Initial Developer includes a notice in the Original
Software prohibiting it from being distributed or otherwise made
available under any subsequent version of the License, You must
distribute and make the Covered Software available under the terms
of the version of the License under which You originally received
the Covered Software. Otherwise, You may also choose to use,
distribute or otherwise make the Covered Software available under
the terms of any subsequent version of the License published by
the license steward.
4.3. Modified Versions.
When You are an Initial Developer and You want to create a new
license for Your Original Software, You may create and use a
modified version of this License if You: (a) rename the license
and remove any references to the name of the license steward
(except to note that the license differs from this License); and
(b) otherwise make it clear that the license contains terms which
differ from this License.
5. DISCLAIMER OF WARRANTY.
COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
DISCLAIMER.
6. TERMINATION.
6.1. This License and the rights granted hereunder will terminate
automatically if You fail to comply with terms herein and fail to
cure such breach within 30 days of becoming aware of the breach.
Provisions which, by their nature, must remain in effect beyond
the termination of this License shall survive.
6.2. If You assert a patent infringement claim (excluding
declaratory judgment actions) against Initial Developer or a
Contributor (the Initial Developer or Contributor against whom You
assert such claim is referred to as "Participant") alleging that
the Participant Software (meaning the Contributor Version where
the Participant is a Contributor or the Original Software where
the Participant is the Initial Developer) directly or indirectly
infringes any patent, then any and all rights granted directly or
indirectly to You by such Participant, the Initial Developer (if
the Initial Developer is not the Participant) and all Contributors
under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
notice from Participant terminate prospectively and automatically
at the expiration of such 60 day notice period, unless if within
such 60 day period You withdraw Your claim with respect to the
Participant Software against such Participant either unilaterally
or pursuant to a written agreement with Participant.
6.3. In the event of termination under Sections 6.1 or 6.2 above,
all end user licenses that have been validly granted by You or any
distributor hereunder prior to termination (excluding licenses
granted to You by any distributor) shall survive termination.
7. LIMITATION OF LIABILITY.
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
APPLY TO YOU.
8. U.S. GOVERNMENT END USERS.
The Covered Software is a "commercial item," as that term is
defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
computer software" (as that term is defined at 48
C.F.R. 252.227-7014(a)(1)) and "commercial computer software
documentation" as such terms are used in 48 C.F.R. 12.212
(Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
U.S. Government End Users acquire Covered Software with only those
rights set forth herein. This U.S. Government Rights clause is in
lieu of, and supersedes, any other FAR, DFAR, or other clause or
provision that addresses Government rights in computer software
under this License.
9. MISCELLANEOUS.
This License represents the complete agreement concerning subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. This License shall be governed
by the law of the jurisdiction specified in a notice contained
within the Original Software (except to the extent applicable law,
if any, provides otherwise), excluding such jurisdiction's
conflict-of-law provisions. Any litigation relating to this
License shall be subject to the jurisdiction of the courts located
in the jurisdiction and venue specified in a notice contained
within the Original Software, with the losing party responsible
for costs, including, without limitation, court costs and
reasonable attorneys' fees and expenses. The application of the
United Nations Convention on Contracts for the International Sale
of Goods is expressly excluded. Any law or regulation which
provides that the language of a contract shall be construed
against the drafter shall not apply to this License. You agree
that You alone are responsible for compliance with the United
States export administration regulations (and the export control
laws and regulation of any other countries) when You use,
distribute or otherwise make available any Covered Software.
10. RESPONSIBILITY FOR CLAIMS.
As between Initial Developer and the Contributors, each party is
responsible for claims and damages arising, directly or
indirectly, out of its utilization of rights under this License
and You agree to work with Initial Developer and Contributors to
distribute such responsibility on an equitable basis. Nothing
herein is intended or shall be deemed to constitute any admission
of liability.
--------------------------------------------------------------------
NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND
DISTRIBUTION LICENSE (CDDL)
For Covered Software in this distribution, this License shall
be governed by the laws of the State of California (excluding
conflict-of-law provisions).
Any litigation relating to this License shall be subject to the
jurisdiction of the Federal Courts of the Northern District of
California and the state courts of the State of California, with
venue lying in Santa Clara County, California.

846
bin/ar.cc Normal file
View file

@ -0,0 +1,846 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* ar.c
*
* Deal with the lib.a(member.o) and lib.a((entry-point)) notations
*
* Look inside archives for notations a(b) and a((b))
* a(b) is file member b in archive a
* a((b)) is entry point b in object archive a
*
* For 6.0, create a make which can understand all archive
* formats. This is kind of tricky, and <ar.h> isnt any help.
*/
/*
* Included files
*/
#include <alloca.h> /* alloca() */
#include <ar.h>
#include <errno.h> /* errno */
#include <fcntl.h> /* open() */
#include <libintl.h>
#include <mk/defs.h>
#include <mksh/misc.h> /* retmem_mb() */
struct ranlib {
union {
off_t ran_strx; /* string table index of */
char *ran_name; /* symbol defined by */
} ran_un;
off_t ran_off; /* library member at this offset */
};
#include <unistd.h> /* close() */
/*
* Defined macros
*/
#ifndef S5EMUL
#undef BITSPERBYTE
#define BITSPERBYTE 8
#endif
/*
* Defines for all the different archive formats. See next comment
* block for justification for not using <ar.h>s versions.
*/
#define AR_5_MAGIC "<ar>" /* 5.0 format magic string */
#define AR_5_MAGIC_LENGTH 4 /* 5.0 format string length */
#define AR_PORT_MAGIC "!<arch>\n" /* Port. (6.0) magic string */
#define AR_PORT_MAGIC_LENGTH 8 /* Port. (6.0) string length */
#define AR_PORT_END_MAGIC "`\n" /* Port. (6.0) end of header */
#define AR_PORT_WORD 4 /* Port. (6.0) 'word' length */
/*
* typedefs & structs
*/
/*
* These are the archive file headers for the formats. Note
* that it really doesnt matter if these structures are defined
* here. They are correct as of the respective archive format
* releases. If the archive format is changed, then since backwards
* compatability is the desired behavior, a new structure is added
* to the list.
*/
typedef struct { /* 5.0 ar header format: vax family; 3b family */
char ar_magic[AR_5_MAGIC_LENGTH]; /* AR_5_MAGIC*/
char ar_name[16]; /* Space terminated */
char ar_date[AR_PORT_WORD]; /* sgetl() accessed */
char ar_syms[AR_PORT_WORD]; /* sgetl() accessed */
} Arh_5;
typedef struct { /* 5.0 ar symbol format: vax family; 3b family */
char sym_name[8]; /* Space terminated */
char sym_ptr[AR_PORT_WORD]; /* sgetl() accessed */
} Ars_5;
typedef struct { /* 5.0 ar member format: vax family; 3b family */
char arf_name[16]; /* Space terminated */
char arf_date[AR_PORT_WORD]; /* sgetl() accessed */
char arf_uid[AR_PORT_WORD]; /* sgetl() accessed */
char arf_gid[AR_PORT_WORD]; /* sgetl() accessed */
char arf_mode[AR_PORT_WORD]; /* sgetl() accessed */
char arf_size[AR_PORT_WORD]; /* sgetl() accessed */
} Arf_5;
typedef struct { /* Portable (6.0) ar format: vax family; 3b family */
char ar_name[16]; /* Space terminated */
/* left-adjusted fields; decimal ascii; blank filled */
char ar_date[12];
char ar_uid[6];
char ar_gid[6];
char ar_mode[8]; /* octal ascii */
char ar_size[10];
/* special end-of-header string (AR_PORT_END_MAGIC) */
char ar_fmag[2];
} Ar_port;
enum ar_type {
AR_5,
AR_PORT
};
typedef unsigned int ar_port_word; // must be 4-bytes long
typedef struct {
FILE *fd;
/* to distiguish ar format */
enum ar_type type;
/* where first ar member header is at */
long first_ar_mem;
/* where the symbol lookup starts */
long sym_begin;
/* the number of symbols available */
long num_symbols;
/* length of symbol directory file */
long sym_size;
Arh_5 arh_5;
Ars_5 ars_5;
Arf_5 arf_5;
Ar_port ar_port;
} Ar;
/*
* Static variables
*/
/*
* File table of contents
*/
extern timestruc_t& read_archive(register Name target);
static Boolean open_archive(char *filename, register Ar *arp);
static void close_archive(register Ar *arp);
static Boolean read_archive_dir(register Ar *arp, Name library, char **long_names_table);
static void translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table);
static long sgetl(char *);
/*
* read_archive(target)
*
* Read the contents of an ar file.
*
* Return value:
* The time the member was created
*
* Parameters:
* target The member to find time for
*
* Global variables used:
* empty_name The Name ""
*/
int read_member_header (Ar_port *header, FILE *fd, char* filename);
int process_long_names_member (register Ar *arp, char **long_names_table, char *filename);
timestruc_t&
read_archive(register Name target)
{
register Property member;
wchar_t *slash;
String_rec true_member_name;
wchar_t buffer[STRING_BUFFER_LENGTH];
register Name true_member = NULL;
Ar ar;
char *long_names_table = NULL; /* Table of long
member names */
member = get_prop(target->prop, member_prop);
/*
* Check if the member has directory component.
* If so, remove the dir and see if we know the date.
*/
if (member->body.member.member != NULL) {
Wstring member_string(member->body.member.member);
wchar_t * wcb = member_string.get_string();
if((slash = (wchar_t *) wcsrchr(wcb, (int) slash_char)) != NULL) {
INIT_STRING_FROM_STACK(true_member_name, buffer);
append_string(member->body.member.library->string_mb,
&true_member_name,
FIND_LENGTH);
append_char((int) parenleft_char, &true_member_name);
append_string(slash + 1, &true_member_name, FIND_LENGTH);
append_char((int) parenright_char, &true_member_name);
true_member = GETNAME(true_member_name.buffer.start,
FIND_LENGTH);
if (true_member->stat.time != file_no_time) {
target->stat.time = true_member->stat.time;
return target->stat.time;
}
}
}
if (open_archive(member->body.member.library->string_mb, &ar) == failed) {
if (errno == ENOENT) {
target->stat.stat_errno = ENOENT;
close_archive(&ar);
if (member->body.member.member == NULL) {
member->body.member.member = empty_name;
}
return target->stat.time = file_doesnt_exist;
} else {
fatal(gettext("Can't access archive `%s': %s"),
member->body.member.library->string_mb,
errmsg(errno));
}
}
if (target->stat.time == file_no_time) {
if (read_archive_dir(&ar, member->body.member.library,
&long_names_table)
== failed){
fatal(gettext("Can't access archive `%s': %s"),
member->body.member.library->string_mb,
errmsg(errno));
}
}
if (member->body.member.entry != NULL) {
translate_entry(&ar, target, member,&long_names_table);
}
close_archive(&ar);
if (long_names_table) {
retmem_mb(long_names_table);
}
if (true_member != NULL) {
target->stat.time = true_member->stat.time;
}
if (target->stat.time == file_no_time) {
target->stat.time = file_doesnt_exist;
}
return target->stat.time;
}
/*
* open_archive(filename, arp)
*
* Return value:
* Indicates if open failed or not
*
* Parameters:
* filename The name of the archive we need to read
* arp Pointer to ar file description block
*
* Global variables used:
*/
static Boolean
open_archive(char *filename, register Ar *arp)
{
int fd;
char mag_5[AR_5_MAGIC_LENGTH];
char mag_port[AR_PORT_MAGIC_LENGTH];
char buffer[4];
arp->fd = NULL;
fd = open_vroot(filename, O_RDONLY, 0, NULL, VROOT_DEFAULT);
if ((fd < 0) || ((arp->fd = fdopen(fd, "r")) == NULL)) {
return failed;
}
(void) fcntl(fileno(arp->fd), F_SETFD, 1);
if (fread(mag_port, AR_PORT_MAGIC_LENGTH, 1, arp->fd) != 1) {
return failed;
}
if (IS_EQUALN(mag_port, AR_PORT_MAGIC, AR_PORT_MAGIC_LENGTH)) {
arp->type = AR_PORT;
/*
* Read in first member header to find out if there is
* a symbol definition table.
*/
int ret = read_member_header(&arp->ar_port, arp->fd, filename);
if (ret == failed) {
return failed;
} else if(ret == -1) {
/* There is no member header - empty archive */
arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
arp->first_ar_mem = ftell(arp->fd);
return succeeded;
}
/*
* The following values are the default if there is
* no symbol directory and long member names.
*/
arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
arp->first_ar_mem = ftell(arp->fd) - (long) sizeof (Ar_port);
/*
* Do we have a symbol table? A symbol table is always
* the first member in an archive. In 4.1.x it has the
* name __.SYMDEF, in SVr4, it has the name "/ "
*/
/*
MBSTOWCS(wcs_buffer, "/ ");
if (IS_WEQUALN(arp->ar_port.ar_name, wcs_buffer, 16)) {
*/
if (IS_EQUALN(arp->ar_port.ar_name,
"/ ",
16)) {
if (sscanf(arp->ar_port.ar_size,
"%ld",
&arp->sym_size) != 1) {
return failed;
}
arp->sym_size += (arp->sym_size & 1); /* round up */
if (fread(buffer, sizeof buffer, 1, arp->fd) != 1) {
return failed;
}
arp->num_symbols = sgetl(buffer);
arp->sym_begin = ftell(arp->fd);
arp->first_ar_mem = arp->sym_begin +
arp->sym_size - sizeof buffer;
}
return succeeded;
}
fatal(gettext("`%s' is not an archive"), filename);
/* NOTREACHED */
return failed;
}
/*
* close_archive(arp)
*
* Parameters:
* arp Pointer to ar file description block
*
* Global variables used:
*/
static void
close_archive(register Ar *arp)
{
if (arp->fd != NULL) {
(void) fclose(arp->fd);
}
}
/*
* read_archive_dir(arp, library, long_names_table)
*
* Reads the directory of an archive and enters all
* the members into the make symboltable in lib(member) format
* with their dates.
*
* Parameters:
* arp Pointer to ar file description block
* library Name of lib to enter members for.
* Used to form "lib(member)" string.
* long_names_table table that contains list of members
* with names > 15 characters long
*
* Global variables used:
*/
static Boolean
read_archive_dir(register Ar *arp, Name library, char **long_names_table)
{
wchar_t *name_string;
wchar_t *member_string;
register long len;
register wchar_t *p;
register char *q;
register Name name;
Property member;
long ptr;
long date;
int offset;
/*
* If any of the members has a name > 15 chars,
* it will be found here.
*/
if (process_long_names_member(arp, long_names_table, library->string_mb) == failed) {
return failed;
}
name_string = ALLOC_WC((int) (library->hash.length +
(int) ar_member_name_len * 2));
(void) mbstowcs(name_string, library->string_mb, (int) library->hash.length);
member_string = name_string + library->hash.length;
*member_string++ = (int) parenleft_char;
if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
goto read_error;
}
/* Read the directory using the appropriate format */
switch (arp->type) {
case AR_5:
for (;;) {
if (fread((char *) &arp->arf_5, sizeof arp->arf_5, 1, arp->fd)
!= 1) {
if (feof(arp->fd)) {
return succeeded;
}
break;
}
len = sizeof arp->arf_5.arf_name;
for (p = member_string, q = arp->arf_5.arf_name;
(len > 0) && (*q != (int) nul_char) && !isspace(*q);
) {
MBTOWC(p, q);
p++;
q++;
}
*p++ = (int) parenright_char;
*p = (int) nul_char;
name = GETNAME(name_string, FIND_LENGTH);
/*
* [tolik] Fix for dmake bug 1234018.
* If name->stat.time is already set, then it should not
* be changed. (D)make propogates time stamp for one
* member, and when it calls exists() for another member,
* the first one may be changed.
*/
if(name->stat.time == file_no_time) {
name->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
name->stat.time.tv_nsec = LONG_MAX;
}
name->is_member = library->is_member;
member = maybe_append_prop(name, member_prop);
member->body.member.library = library;
*--p = (int) nul_char;
if (member->body.member.member == NULL) {
member->body.member.member =
GETNAME(member_string, FIND_LENGTH);
}
ptr = sgetl(arp->arf_5.arf_size);
ptr += (ptr & 1);
if (fseek(arp->fd, ptr, 1) != 0) {
goto read_error;
}
}
break;
case AR_PORT:
for (;;) {
if ((fread((char *) &arp->ar_port,
sizeof arp->ar_port,
1,
arp->fd) != 1) ||
!IS_EQUALN(arp->ar_port.ar_fmag,
AR_PORT_END_MAGIC,
sizeof arp->ar_port.ar_fmag)) {
if (feof(arp->fd)) {
return succeeded;
}
fatal(
gettext("Read error in archive `%s': invalid archive file member header at 0x%x"),
library->string_mb,
ftell(arp->fd)
);
}
/* If it's a long name, retrieve it from long name table */
if (arp->ar_port.ar_name[0] == '/') {
/*
* "len" is used for hashing the string.
* We're using "ar_member_name_len" instead of
* the actual name length since it's the longest
* string the "ar" command can handle at this
* point.
*/
len = ar_member_name_len;
sscanf(arp->ar_port.ar_name + 1,
"%ld",
&offset);
q = *long_names_table + offset;
} else {
q = arp->ar_port.ar_name;
len = sizeof arp->ar_port.ar_name;
}
for (p = member_string;
(len > 0) &&
(*q != (int) nul_char) &&
!isspace(*q) &&
(*q != (int) slash_char);
) {
MBTOWC(p, q);
p++;
q++;
}
*p++ = (int) parenright_char;
*p = (int) nul_char;
name = GETNAME(name_string, FIND_LENGTH);
name->is_member = library->is_member;
member = maybe_append_prop(name, member_prop);
member->body.member.library = library;
*--p = (int) nul_char;
if (member->body.member.member == NULL) {
member->body.member.member =
GETNAME(member_string, FIND_LENGTH);
}
if (sscanf(arp->ar_port.ar_date, "%ld", &date) != 1) {
WCSTOMBS(mbs_buffer, name_string);
fatal(gettext("Bad date field for member `%s' in archive `%s'"),
mbs_buffer,
library->string_mb);
}
/*
* [tolik] Fix for dmake bug 1234018.
*/
if(name->stat.time == file_no_time) {
name->stat.time.tv_sec = date;
name->stat.time.tv_nsec = LONG_MAX;
}
if (sscanf(arp->ar_port.ar_size, "%ld", &ptr) != 1) {
WCSTOMBS(mbs_buffer, name_string);
fatal(gettext("Bad size field for member `%s' in archive `%s'"),
mbs_buffer,
library->string_mb);
}
ptr += (ptr & 1);
if (fseek(arp->fd, ptr, 1) != 0) {
goto read_error;
}
}
break;
}
/* Only here if fread() [or IS_EQUALN()] failed and not at EOF */
read_error:
fatal(gettext("Read error in archive `%s': %s"),
library->string_mb,
errmsg(errno));
/* NOTREACHED */
}
/*
* process_long_names_member(arp)
*
* If the archive contains members with names longer
* than 15 characters, then it has a special member
* with the name "// " that contains a table
* of null-terminated long names. This member
* is always the first member, after the symbol table
* if it exists.
*
* Parameters:
* arp Pointer to ar file description block
*
* Global variables used:
*/
int
process_long_names_member(register Ar *arp, char **long_names_table, char *filename)
{
Ar_port *ar_member_header;
int table_size;
if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
return failed;
}
if ((ar_member_header =
(Ar_port *) alloca((int) sizeof(Ar_port))) == NULL){
perror(gettext("memory allocation failure"));
return failed;
}
int ret = read_member_header(ar_member_header, arp->fd, filename);
if (ret == failed) {
return failed;
} else if(ret == -1) {
/* There is no member header - empty archive */
return succeeded;
}
/* Do we have special member containing long names? */
if (IS_EQUALN(ar_member_header->ar_name,
"// ",
16)){
if (sscanf(ar_member_header->ar_size,
"%ld",
&table_size) != 1) {
return failed;
}
*long_names_table = (char *) malloc(table_size);
/* Read the list of long member names into the table */
if (fread(*long_names_table, table_size, 1, arp->fd) != 1) {
return failed;
}
arp->first_ar_mem = ftell(arp->fd);
}
return succeeded;
}
/*
* translate_entry(arp, target, member)
*
* Finds the member for one lib.a((entry))
*
* Parameters:
* arp Pointer to ar file description block
* target Target to find member name for
* member Property to fill in with info
*
* Global variables used:
*/
static void
translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table)
{
register int len;
register int i;
wchar_t *member_string;
ar_port_word *offs;
int strtablen;
char *syms; /* string table */
char *csym; /* string table */
ar_port_word *offend; /* end of offsets table */
int date;
register wchar_t *ap;
register char *hp;
int maxs;
int offset;
char buffer[4];
if (arp->sym_begin == 0L || arp->num_symbols == 0L) {
fatal(gettext("Cannot find symbol `%s' in archive `%s'"),
member->body.member.entry->string_mb,
member->body.member.library->string_mb);
}
if (fseek(arp->fd, arp->sym_begin, 0) != 0) {
goto read_error;
}
member_string = ALLOC_WC((int) ((int) ar_member_name_len * 2));
switch (arp->type) {
case AR_5:
if ((len = member->body.member.entry->hash.length) > 8) {
len = 8;
}
for (i = 0; i < arp->num_symbols; i++) {
if (fread((char *) &arp->ars_5,
sizeof arp->ars_5,
1,
arp->fd) != 1) {
goto read_error;
}
if (IS_EQUALN(arp->ars_5.sym_name,
member->body.member.entry->string_mb,
len)) {
if ((fseek(arp->fd,
sgetl(arp->ars_5.sym_ptr),
0) != 0) ||
(fread((char *) &arp->arf_5,
sizeof arp->arf_5,
1,
arp->fd) != 1)) {
goto read_error;
}
MBSTOWCS(wcs_buffer, arp->arf_5.arf_name);
(void) wcsncpy(member_string,
wcs_buffer,
wcslen(wcs_buffer));
member_string[sizeof(arp->arf_5.arf_name)] =
(int) nul_char;
member->body.member.member =
GETNAME(member_string, FIND_LENGTH);
target->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
target->stat.time.tv_nsec = LONG_MAX;
return;
}
}
break;
case AR_PORT:
offs = (ar_port_word *) alloca((int) (arp->num_symbols * AR_PORT_WORD));
if (fread((char *) offs,
AR_PORT_WORD,
(int) arp->num_symbols,
arp->fd) != arp->num_symbols) {
goto read_error;
}
for(i=0;i<arp->num_symbols;i++) {
*((int*)buffer)=offs[i];
offs[i]=(ar_port_word)sgetl(buffer);
}
strtablen=arp->sym_size-4-(int) (arp->num_symbols * AR_PORT_WORD);
syms = (char *) alloca(strtablen);
if (fread(syms,
sizeof (char),
strtablen,
arp->fd) != strtablen) {
goto read_error;
}
offend = &offs[arp->num_symbols];
while (offs < offend) {
maxs = strlen(member->body.member.entry->string_mb);
if(strlen(syms) > maxs)
maxs = strlen(syms);
if (IS_EQUALN(syms,
member->body.member.entry->string_mb,
maxs)) {
if (fseek(arp->fd,
(long) *offs,
0) != 0) {
goto read_error;
}
if ((fread((char *) &arp->ar_port,
sizeof arp->ar_port,
1,
arp->fd) != 1) ||
!IS_EQUALN(arp->ar_port.ar_fmag,
AR_PORT_END_MAGIC,
sizeof arp->ar_port.ar_fmag)) {
goto read_error;
}
if (sscanf(arp->ar_port.ar_date,
"%ld",
&date) != 1) {
fatal(gettext("Bad date field for member `%s' in archive `%s'"),
arp->ar_port.ar_name,
target->string_mb);
}
/* If it's a long name, retrieve it from long name table */
if (arp->ar_port.ar_name[0] == '/') {
sscanf(arp->ar_port.ar_name + 1,
"%ld",
&offset);
len = ar_member_name_len;
hp = *long_names_table + offset;
} else {
len = sizeof arp->ar_port.ar_name;
hp = arp->ar_port.ar_name;
}
ap = member_string;
while (*hp &&
(*hp != (int) slash_char) &&
(ap < &member_string[len])) {
MBTOWC(ap, hp);
ap++;
hp++;
}
*ap = (int) nul_char;
member->body.member.member =
GETNAME(member_string, FIND_LENGTH);
target->stat.time.tv_sec = date;
target->stat.time.tv_nsec = LONG_MAX;
return;
}
offs++;
while(*syms!='\0') syms++;
syms++;
}
}
fatal(gettext("Cannot find symbol `%s' in archive `%s'"),
member->body.member.entry->string_mb,
member->body.member.library->string_mb);
/*NOTREACHED*/
read_error:
if (ferror(arp->fd)) {
fatal(gettext("Read error in archive `%s': %s"),
member->body.member.library->string_mb,
errmsg(errno));
} else {
fatal(gettext("Read error in archive `%s': Premature EOF"),
member->body.member.library->string_mb);
}
}
/*
* sgetl(buffer)
*
* The intent here is to provide a means to make the value of
* bytes in an io-buffer correspond to the value of a long
* in the memory while doing the io a long at a time.
* Files written and read in this way are machine-independent.
*
* Return value:
* Long int read from buffer
* Parameters:
* buffer buffer we need to read long int from
*
* Global variables used:
*/
static long
sgetl(register char *buffer)
{
register long w = 0;
register int i = BITSPERBYTE * AR_PORT_WORD;
while ((i -= BITSPERBYTE) >= 0) {
w |= (long) ((unsigned char) *buffer++) << i;
}
return w;
}
/*
* read_member_header(header, fd, filename)
*
* reads the member header for the 4.1.x and SVr4 archives.
*
* Return value:
* fails if read error or member
* header is not the right format
* Parameters:
* header There's one before each archive member
* fd file descriptor for the archive file.
*
* Global variables used:
*/
int
read_member_header(Ar_port *header, FILE *fd, char* filename)
{
int num = fread((char *) header, sizeof (Ar_port), 1, fd);
if (num != 1 && feof(fd)) {
/* There is no member header - empty archive */
return -1;
}
if ((num != 1) ||
!IS_EQUALN(
AR_PORT_END_MAGIC,
header->ar_fmag,
sizeof (header->ar_fmag)
)
) {
fatal(
gettext("Read error in archive `%s': invalid archive file member header at 0x%x"),
filename,
ftell(fd)
);
}
return succeeded;
}

108
bin/depvar.cc Normal file
View file

@ -0,0 +1,108 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1995 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Included files
*/
#include <libintl.h>
#include <mk/defs.h>
#include <mksh/misc.h> /* getmem() */
/*
* This file deals with "Dependency Variables".
* The "-V var" command line option is used to indicate
* that var is a dependency variable. Used in conjunction with
* the -P option the user is asking if the named variables affect
* the dependencies of the given target.
*/
struct _Depvar {
Name name; /* Name of variable */
struct _Depvar *next; /* Linked list */
Boolean cmdline; /* Macro defined on the cmdline? */
};
typedef struct _Depvar *Depvar;
static Depvar depvar_list;
static Depvar *bpatch = &depvar_list;
static Boolean variant_deps;
/*
* Add a name to the list.
*/
void
depvar_add_to_list(Name name, Boolean cmdline)
{
Depvar dv;
dv = ALLOC(Depvar);
dv->name = name;
dv->next = NULL;
dv->cmdline = cmdline;
*bpatch = dv;
bpatch = &dv->next;
}
/*
* The macro `name' has been used in either the left-hand or
* right-hand side of a dependency. See if it is in the
* list. Two things are looked for. Names given as args
* to the -V list are checked so as to set the same/differ
* output for the -P option. Names given as macro=value
* command-line args are checked and, if found, an NSE
* warning is produced.
*/
void
depvar_dep_macro_used(Name name)
{
Depvar dv;
for (dv = depvar_list; dv != NULL; dv = dv->next) {
if (name == dv->name) {
variant_deps = true;
break;
}
}
}
/*
* Print the results. If any of the Dependency Variables
* affected the dependencies then the dependencies potentially
* differ because of these variables.
*/
void
depvar_print_results(void)
{
if (variant_deps) {
printf(gettext("differ\n"));
} else {
printf(gettext("same\n"));
}
}

3209
bin/doname.cc Normal file

File diff suppressed because it is too large Load diff

163
bin/dosys.cc Normal file
View file

@ -0,0 +1,163 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* dosys.cc
*
* Execute one commandline
*/
/*
* Included files
*/
#include <fcntl.h> /* open() */
#include <mk/defs.h>
#include <mksh/dosys.h> /* doshell(), doexec() */
#include <mksh/misc.h> /* getmem() */
#include <sys/stat.h> /* open() */
#include <unistd.h> /* getpid() */
/*
* Defined macros
*/
/*
* typedefs & structs
*/
/*
* Static variables
*/
static int filter_file;
static char *filter_file_name;
/*
* File table of contents
*/
static void redirect_stderr(void);
/*
* dosys(command, ignore_error, call_make, silent_error, target)
*
* Check if command string contains meta chars and dispatch to
* the proper routine for executing one command line.
*
* Return value:
* Indicates if the command execution failed
*
* Parameters:
* command The command to run
* ignore_error Should make abort when an error is seen?
* call_make Did command reference $(MAKE) ?
* silent_error Should error messages be suppressed for pmake?
* target Target we are building
*
* Global variables used:
* do_not_exec_rule Is -n on?
* working_on_targets We started processing real targets
*/
Doname
dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target)
{
timestruc_t before;
register int length = command->hash.length;
Wstring wcb(command);
register wchar_t *p = wcb.get_string();
register wchar_t *q;
Doname result;
/* Strip spaces from head of command string */
while (iswspace(*p)) {
p++, length--;
}
if (*p == (int) nul_char) {
return build_failed;
}
/* If we are faking it we just return */
if (do_not_exec_rule &&
working_on_targets &&
!call_make &&
!always_exec) {
return build_ok;
}
/* no_action_was_taken is used to print special message */
no_action_was_taken = false;
/* Copy string to make it OK to write it. */
q = ALLOC_WC(length + 1);
(void) wcscpy(q, p);
/* Write the state file iff this command uses make. */
if (call_make && command_changed) {
write_state_file(0, false);
}
make_state->stat.time = file_no_time;
(void)exists(make_state);
before = make_state->stat.time;
/*
* Run command directly if it contains no shell meta chars,
* else run it using the shell.
*/
if (await(ignore_error,
silent_error,
target,
wcb.get_string(),
command->meta ?
doshell(q, ignore_error,
stdout_file, stderr_file, 0) :
doexec(q, ignore_error,
stdout_file, stderr_file,
vroot_path, 0),
NULL,
-1
)) {
result = build_ok;
} else {
result = build_failed;
}
retmem(q);
if ((report_dependencies_level == 0) &&
call_make) {
make_state->stat.time = file_no_time;
(void)exists(make_state);
if (before == make_state->stat.time) {
return result;
}
makefile_type = reading_statefile;
if (read_trace_level > 1) {
trace_reader = true;
}
temp_file_number++;
(void) read_simple_file(make_state,
false,
false,
false,
false,
false,
true);
trace_reader = false;
}
return result;
}

711
bin/files.cc Normal file
View file

@ -0,0 +1,711 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* files.c
*
* Various file related routines:
* Figure out if file exists
* Wildcard resolution for directory reader
* Directory reader
*/
/*
* Included files
*/
#include <dirent.h> /* opendir() */
#include <errno.h> /* errno */
#include <mk/defs.h>
#include <mksh/macro.h> /* getvar() */
#include <mksh/misc.h> /* get_prop(), append_prop() */
#include <sys/stat.h> /* lstat() */
#include <libintl.h>
/*
* Defined macros
*/
/*
* typedefs & structs
*/
/*
* Static variables
*/
/*
* File table of contents
*/
extern timestruc_t& exists(register Name target);
extern void set_target_stat(register Name target, struct stat buf);
static timestruc_t& vpath_exists(register Name target);
static Name enter_file_name(wchar_t *name_string, wchar_t *library);
static Boolean star_match(register char *string, register char *pattern);
static Boolean amatch(register wchar_t *string, register wchar_t *pattern);
/*
* exists(target)
*
* Figure out the timestamp for one target.
*
* Return value:
* The time the target was created
*
* Parameters:
* target The target to check
*
* Global variables used:
* debug_level Should we trace the stat call?
* recursion_level Used for tracing
* vpath_defined Was the variable VPATH defined in environment?
*/
timestruc_t&
exists(register Name target)
{
struct stat buf;
register int result;
/* We cache stat information. */
if (target->stat.time != file_no_time) {
return target->stat.time;
}
/*
* If the target is a member, we have to extract the time
* from the archive.
*/
if (target->is_member &&
(get_prop(target->prop, member_prop) != NULL)) {
return read_archive(target);
}
if (debug_level > 1) {
(void) printf("%*sstat(%s)\n",
recursion_level,
"",
target->string_mb);
}
result = lstat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
if ((result != -1) && ((buf.st_mode & S_IFMT) == S_IFLNK)) {
/*
* If the file is a symbolic link, we remember that
* and then we get the status for the refd file.
*/
target->stat.is_sym_link = true;
result = stat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
} else {
target->stat.is_sym_link = false;
}
if (result < 0) {
target->stat.time = file_doesnt_exist;
target->stat.stat_errno = errno;
if ((errno == ENOENT) &&
vpath_defined &&
/* azv, fixing bug 1262942, VPATH works with a leaf name
* but not a directory name.
*/
(target->string_mb[0] != (int) slash_char) ) {
/* BID_1214655 */
/* azv */
vpath_exists(target);
// return vpath_exists(target);
}
} else {
/* Save all the information we need about the file */
target->stat.stat_errno = 0;
target->stat.is_file = true;
target->stat.mode = buf.st_mode & 0777;
target->stat.size = buf.st_size;
target->stat.is_dir =
BOOLEAN((buf.st_mode & S_IFMT) == S_IFDIR);
if (target->stat.is_dir) {
target->stat.time = file_is_dir;
} else {
/* target->stat.time = buf.st_mtime; */
/* BID_1129806 */
/* vis@nbsp.nsk.su */
target->stat.time = MAX(buf.st_mtim, file_min_time);
}
}
if ((target->colon_splits > 0) &&
(get_prop(target->prop, time_prop) == NULL)) {
append_prop(target, time_prop)->body.time.time =
target->stat.time;
}
return target->stat.time;
}
/*
* set_target_stat( target, buf)
*
* Called by exists() to set some stat fields in the Name structure
* to those read by the stat_vroot() call (from disk).
*
* Parameters:
* target The target whose stat field is set
* buf stat values (on disk) of the file
* represented by target.
*/
void
set_target_stat(register Name target, struct stat buf)
{
target->stat.stat_errno = 0;
target->stat.is_file = true;
target->stat.mode = buf.st_mode & 0777;
target->stat.size = buf.st_size;
target->stat.is_dir =
BOOLEAN((buf.st_mode & S_IFMT) == S_IFDIR);
if (target->stat.is_dir) {
target->stat.time = file_is_dir;
} else {
/* target->stat.time = buf.st_mtime; */
/* BID_1129806 */
/* vis@nbsp.nsk.su */
target->stat.time = MAX(buf.st_mtim, file_min_time);
}
}
/*
* vpath_exists(target)
*
* Called if exists() discovers that there is a VPATH defined.
* This function stats the VPATH translation of the target.
*
* Return value:
* The time the target was created
*
* Parameters:
* target The target to check
*
* Global variables used:
* vpath_name The Name "VPATH", used to get macro value
*/
static timestruc_t&
vpath_exists(register Name target)
{
wchar_t *vpath;
wchar_t file_name[MAXPATHLEN];
wchar_t *name_p;
Name alias;
/*
* To avoid recursive search through VPATH when exists(alias) is called
*/
vpath_defined = false;
Wstring wcb(getvar(vpath_name));
Wstring wcb1(target);
vpath = wcb.get_string();
while (*vpath != (int) nul_char) {
name_p = file_name;
while ((*vpath != (int) colon_char) &&
(*vpath != (int) nul_char)) {
*name_p++ = *vpath++;
}
*name_p++ = (int) slash_char;
(void) wcscpy(name_p, wcb1.get_string());
alias = GETNAME(file_name, FIND_LENGTH);
if (exists(alias) != file_doesnt_exist) {
target->stat.is_file = true;
target->stat.mode = alias->stat.mode;
target->stat.size = alias->stat.size;
target->stat.is_dir = alias->stat.is_dir;
target->stat.time = alias->stat.time;
maybe_append_prop(target, vpath_alias_prop)->
body.vpath_alias.alias = alias;
target->has_vpath_alias_prop = true;
vpath_defined = true;
return alias->stat.time;
}
while ((*vpath != (int) nul_char) &&
((*vpath == (int) colon_char) || iswspace(*vpath))) {
vpath++;
}
}
/*
* Restore vpath_defined
*/
vpath_defined = true;
return target->stat.time;
}
/*
* read_dir(dir, pattern, line, library)
*
* Used to enter the contents of directories into makes namespace.
* Presence of a file is important when scanning for implicit rules.
* read_dir() is also used to expand wildcards in dependency lists.
*
* Return value:
* Non-0 if we found files to match the pattern
*
* Parameters:
* dir Path to the directory to read
* pattern Pattern for that files should match or NULL
* line When we scan using a pattern we enter files
* we find as dependencies for this line
* library If we scan for "lib.a(<wildcard-member>)"
*
* Global variables used:
* debug_level Should we trace the dir reading?
* dot The Name ".", compared against
* sccs_dir_path The path to the SCCS dir (from PROJECTDIR)
* vpath_defined Was the variable VPATH defined in environment?
* vpath_name The Name "VPATH", use to get macro value
*/
int
read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library)
{
wchar_t file_name[MAXPATHLEN];
wchar_t *file_name_p = file_name;
Name file;
wchar_t plain_file_name[MAXPATHLEN];
wchar_t *plain_file_name_p;
Name plain_file;
wchar_t tmp_wcs_buffer[MAXPATHLEN];
DIR *dir_fd;
int m_local_dependency=0;
#define d_fileno d_ino
register struct dirent *dp;
wchar_t *vpath = NULL;
wchar_t *p;
int result = 0;
if(dir->hash.length >= MAXPATHLEN) {
return 0;
}
Wstring wcb(dir);
Wstring vps;
/* A directory is only read once unless we need to expand wildcards. */
if (pattern == NULL) {
if (dir->has_read_dir) {
return 0;
}
dir->has_read_dir = true;
}
/* Check if VPATH is active and setup list if it is. */
if (vpath_defined && (dir == dot)) {
vps.init(getvar(vpath_name));
vpath = vps.get_string();
}
/*
* Prepare the string where we build the full name of the
* files in the directory.
*/
if ((dir->hash.length > 1) || (wcb.get_string()[0] != (int) period_char)) {
(void) wcscpy(file_name, wcb.get_string());
MBSTOWCS(wcs_buffer, "/");
(void) wcscat(file_name, wcs_buffer);
file_name_p = file_name + wcslen(file_name);
}
/* Open the directory. */
vpath_loop:
dir_fd = opendir(dir->string_mb);
if (dir_fd == NULL) {
return 0;
}
/* Read all the directory entries. */
while ((dp = readdir(dir_fd)) != NULL) {
/* We ignore "." and ".." */
if ((dp->d_fileno == 0) ||
((dp->d_name[0] == (int) period_char) &&
((dp->d_name[1] == 0) ||
((dp->d_name[1] == (int) period_char) &&
(dp->d_name[2] == 0))))) {
continue;
}
/*
* Build the full name of the file using whatever
* path supplied to the function.
*/
MBSTOWCS(tmp_wcs_buffer, dp->d_name);
(void) wcscpy(file_name_p, tmp_wcs_buffer);
file = enter_file_name(file_name, library);
if ((pattern != NULL) && amatch(tmp_wcs_buffer, pattern)) {
/*
* If we are expanding a wildcard pattern, we
* enter the file as a dependency for the target.
*/
if (debug_level > 0){
WCSTOMBS(mbs_buffer, pattern);
(void) printf(gettext("'%s: %s' due to %s expansion\n"),
line->body.line.target->string_mb,
file->string_mb,
mbs_buffer);
}
enter_dependency(line, file, false);
result++;
} else {
/*
* If the file has an SCCS/s. file,
* we will detect that later on.
*/
file->stat.has_sccs = NO_SCCS;
/*
* If this is an s. file, we also enter it as if it
* existed in the plain directory.
*/
if ((dp->d_name[0] == 's') &&
(dp->d_name[1] == (int) period_char)) {
MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
plain_file_name_p = plain_file_name;
(void) wcscpy(plain_file_name_p, tmp_wcs_buffer);
plain_file = GETNAME(plain_file_name, FIND_LENGTH);
plain_file->stat.is_file = true;
plain_file->stat.has_sccs = HAS_SCCS;
/*
* Enter the s. file as a dependency for the
* plain file.
*/
maybe_append_prop(plain_file, sccs_prop)->
body.sccs.file = file;
MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
if ((pattern != NULL) &&
amatch(tmp_wcs_buffer, pattern)) {
if (debug_level > 0) {
WCSTOMBS(mbs_buffer, pattern);
(void) printf(gettext("'%s: %s' due to %s expansion\n"),
line->body.line.target->
string_mb,
plain_file->string_mb,
mbs_buffer);
}
enter_dependency(line, plain_file, false);
result++;
}
}
}
}
(void) closedir(dir_fd);
if ((vpath != NULL) && (*vpath != (int) nul_char)) {
while ((*vpath != (int) nul_char) &&
(iswspace(*vpath) || (*vpath == (int) colon_char))) {
vpath++;
}
p = vpath;
while ((*vpath != (int) colon_char) &&
(*vpath != (int) nul_char)) {
vpath++;
}
if (vpath > p) {
dir = GETNAME(p, vpath - p);
goto vpath_loop;
}
}
/*
* look into SCCS directory only if it's not svr4. For svr4 dont do that.
*/
/*
* Now read the SCCS directory.
* Files in the SCSC directory are considered to be part of the set of
* files in the plain directory. They are also entered in their own right.
* Prepare the string where we build the true name of the SCCS files.
*/
(void) wcsncpy(plain_file_name,
file_name,
file_name_p - file_name);
plain_file_name[file_name_p - file_name] = 0;
plain_file_name_p = plain_file_name + wcslen(plain_file_name);
if(!svr4) {
if (sccs_dir_path != NULL) {
wchar_t tmp_wchar;
wchar_t path[MAXPATHLEN];
char mb_path[MAXPATHLEN];
if (file_name_p - file_name > 0) {
tmp_wchar = *file_name_p;
*file_name_p = 0;
WCSTOMBS(mbs_buffer, file_name);
(void) sprintf(mb_path, "%s/%s/SCCS",
sccs_dir_path,
mbs_buffer);
*file_name_p = tmp_wchar;
} else {
(void) sprintf(mb_path, "%s/SCCS", sccs_dir_path);
}
MBSTOWCS(path, mb_path);
(void) wcscpy(file_name, path);
} else {
MBSTOWCS(wcs_buffer, "SCCS");
(void) wcscpy(file_name_p, wcs_buffer);
}
} else {
MBSTOWCS(wcs_buffer, ".");
(void) wcscpy(file_name_p, wcs_buffer);
}
/* Internalize the constructed SCCS dir name. */
(void) exists(dir = GETNAME(file_name, FIND_LENGTH));
/* Just give up if the directory file doesnt exist. */
if (!dir->stat.is_file) {
return result;
}
/* Open the directory. */
dir_fd = opendir(dir->string_mb);
if (dir_fd == NULL) {
return result;
}
MBSTOWCS(wcs_buffer, "/");
(void) wcscat(file_name, wcs_buffer);
file_name_p = file_name + wcslen(file_name);
while ((dp = readdir(dir_fd)) != NULL) {
if ((dp->d_fileno == 0) ||
((dp->d_name[0] == (int) period_char) &&
((dp->d_name[1] == 0) ||
((dp->d_name[1] == (int) period_char) &&
(dp->d_name[2] == 0))))) {
continue;
}
/* Construct and internalize the true name of the SCCS file. */
MBSTOWCS(wcs_buffer, dp->d_name);
(void) wcscpy(file_name_p, wcs_buffer);
file = GETNAME(file_name, FIND_LENGTH);
file->stat.is_file = true;
file->stat.has_sccs = NO_SCCS;
/*
* If this is an s. file, we also enter it as if it
* existed in the plain directory.
*/
if ((dp->d_name[0] == 's') &&
(dp->d_name[1] == (int) period_char)) {
MBSTOWCS(wcs_buffer, dp->d_name + 2);
(void) wcscpy(plain_file_name_p, wcs_buffer);
plain_file = GETNAME(plain_file_name, FIND_LENGTH);
plain_file->stat.is_file = true;
plain_file->stat.has_sccs = HAS_SCCS;
/* if sccs dependency is already set,skip */
if(plain_file->prop) {
Property sprop = get_prop(plain_file->prop,sccs_prop);
if(sprop != NULL) {
if (sprop->body.sccs.file) {
goto try_pattern;
}
}
}
/*
* Enter the s. file as a dependency for the
* plain file.
*/
maybe_append_prop(plain_file, sccs_prop)->
body.sccs.file = file;
try_pattern:
MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
if ((pattern != NULL) &&
amatch(tmp_wcs_buffer, pattern)) {
if (debug_level > 0) {
WCSTOMBS(mbs_buffer, pattern);
(void) printf(gettext("'%s: %s' due to %s expansion\n"),
line->body.line.target->
string_mb,
plain_file->string_mb,
mbs_buffer);
}
enter_dependency(line, plain_file, false);
result++;
}
}
}
(void) closedir(dir_fd);
return result;
}
/*
* enter_file_name(name_string, library)
*
* Helper function for read_dir().
*
* Return value:
* The Name that was entered
*
* Parameters:
* name_string Name of the file we want to enter
* library The library it is a member of, if any
*
* Global variables used:
*/
static Name
enter_file_name(wchar_t *name_string, wchar_t *library)
{
wchar_t buffer[STRING_BUFFER_LENGTH];
String_rec lib_name;
Name name;
Property prop;
if (library == NULL) {
name = GETNAME(name_string, FIND_LENGTH);
name->stat.is_file = true;
return name;
}
INIT_STRING_FROM_STACK(lib_name, buffer);
append_string(library, &lib_name, FIND_LENGTH);
append_char((int) parenleft_char, &lib_name);
append_string(name_string, &lib_name, FIND_LENGTH);
append_char((int) parenright_char, &lib_name);
name = GETNAME(lib_name.buffer.start, FIND_LENGTH);
name->stat.is_file = true;
name->is_member = true;
prop = maybe_append_prop(name, member_prop);
prop->body.member.library = GETNAME(library, FIND_LENGTH);
prop->body.member.library->stat.is_file = true;
prop->body.member.entry = NULL;
prop->body.member.member = GETNAME(name_string, FIND_LENGTH);
prop->body.member.member->stat.is_file = true;
return name;
}
/*
* star_match(string, pattern)
*
* This is a regular shell type wildcard pattern matcher
* It is used when xpanding wildcards in dependency lists
*
* Return value:
* Indication if the string matched the pattern
*
* Parameters:
* string String to match
* pattern Pattern to match it against
*
* Global variables used:
*/
static Boolean
star_match(register wchar_t *string, register wchar_t *pattern)
{
register int pattern_ch;
switch (*pattern) {
case 0:
return succeeded;
case bracketleft_char:
case question_char:
case asterisk_char:
while (*string) {
if (amatch(string++, pattern)) {
return succeeded;
}
}
break;
default:
pattern_ch = (int) *pattern++;
while (*string) {
if ((*string++ == pattern_ch) &&
amatch(string, pattern)) {
return succeeded;
}
}
break;
}
return failed;
}
/*
* amatch(string, pattern)
*
* Helper function for shell pattern matching
*
* Return value:
* Indication if the string matched the pattern
*
* Parameters:
* string String to match
* pattern Pattern to match it against
*
* Global variables used:
*/
static Boolean
amatch(register wchar_t *string, register wchar_t *pattern)
{
register long lower_bound;
register long string_ch;
register long pattern_ch;
register int k;
top:
for (; 1; pattern++, string++) {
lower_bound = 017777777777;
string_ch = *string;
switch (pattern_ch = *pattern) {
case bracketleft_char:
k = 0;
while ((pattern_ch = *++pattern) != 0) {
switch (pattern_ch) {
case bracketright_char:
if (!k) {
return failed;
}
string++;
pattern++;
goto top;
case hyphen_char:
k |= (lower_bound <= string_ch) &&
(string_ch <=
(pattern_ch = pattern[1]));
default:
if (string_ch ==
(lower_bound = pattern_ch)) {
k++;
}
}
}
return failed;
case asterisk_char:
return star_match(string, ++pattern);
case 0:
return BOOLEAN(!string_ch);
case question_char:
if (string_ch == 0) {
return failed;
}
break;
default:
if (pattern_ch != string_ch) {
return failed;
}
break;
}
}
/* NOTREACHED */
}

181
bin/globals.cc Normal file
View file

@ -0,0 +1,181 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* globals.cc
*
* This declares all global variables
*/
/*
* Included files
*/
#include <nl_types.h>
#include <mk/defs.h>
#include <sys/stat.h>
/*
* Defined macros
*/
/*
* typedefs & structs
*/
/*
* Global variables used by make only
*/
FILE *dependency_report_file;
/*
* Global variables used by make
*/
Boolean allrules_read=false;
Name posix_name;
Name svr4_name;
Boolean sdot_target; /* used to identify s.m(/M)akefile */
Boolean all_parallel;
Boolean assign_done;
int foo;
Boolean build_failed_seen;
Name built_last_make_run;
Name c_at;
Boolean cleanup;
Boolean close_report;
Boolean command_changed;
Boolean commands_done;
Chain conditional_targets;
Name conditionals;
Boolean continue_after_error; /* `-k' */
Property current_line;
Name current_make_version;
Name current_target;
short debug_level;
Cmd_line default_rule;
Name default_rule_name;
Name default_target_to_build;
Name dmake_group;
Name dmake_max_jobs;
Name dmake_mode;
DMake_mode dmake_mode_type;
Name dmake_output_mode;
DMake_output_mode output_mode = txt1_mode;
Name dmake_odir;
Name dmake_rcfile;
Name done;
Name dot;
Name dot_keep_state;
Name dot_keep_state_file;
Name empty_name;
Boolean fatal_in_progress;
int file_number;
#if 0
Boolean filter_stderr; /* `-X' */
#endif
Name force;
Name ignore_name;
Boolean ignore_errors; /* `-i' */
Boolean ignore_errors_all; /* `-i' */
Name init;
int job_msg_id;
Boolean keep_state;
Name make_state;
timestruc_t make_state_before;
Dependency makefiles_used;
Name makeflags;
// Boolean make_state_locked; // Moved to lib/mksh
Name make_version;
char mbs_buffer2[(MAXPATHLEN * MB_LEN_MAX)];
char *mbs_ptr;
char *mbs_ptr2;
Boolean depinfo_already_read = false;
Boolean no_action_was_taken = true; /* true if we've not **
** run any command */
Boolean no_parallel = false;
Name no_parallel_name;
Name not_auto;
Boolean only_parallel;
Boolean parallel;
Name parallel_name;
Name localhost_name;
int parallel_process_cnt;
Percent percent_list;
Dyntarget dyntarget_list;
Name plus;
Name pmake_machinesfile;
Name precious;
Name primary_makefile;
Boolean quest; /* `-q' */
short read_trace_level;
Boolean reading_dependencies = false;
Name recursive_name;
int recursion_level;
short report_dependencies_level = 0; /* -P */
Boolean report_pwd;
Boolean rewrite_statefile;
Running running_list;
char *sccs_dir_path;
Name sccs_get_name;
Name sccs_get_posix_name;
Cmd_line sccs_get_rule;
Cmd_line sccs_get_org_rule;
Cmd_line sccs_get_posix_rule;
Name get_name;
Cmd_line get_rule;
Name get_posix_name;
Cmd_line get_posix_rule;
Boolean all_precious;
Boolean silent_all; /* `-s' */
Boolean report_cwd; /* `-w' */
Boolean silent; /* `-s' */
Name silent_name;
char *stderr_file = NULL;
char *stdout_file = NULL;
Boolean stdout_stderr_same;
Dependency suffixes;
Name suffixes_name;
Name sunpro_dependencies;
Boolean target_variants;
const char *tmpdir = "/tmp";
const char *temp_file_directory = ".";
Name temp_file_name;
short temp_file_number;
time_t timing_start;
wchar_t *top_level_target;
Boolean touch; /* `-t' */
Boolean trace_reader; /* `-D' */
Boolean build_unconditional; /* `-u' */
pathpt vroot_path = VROOT_DEFAULT;
Name wait_name;
wchar_t wcs_buffer2[MAXPATHLEN];
wchar_t *wcs_ptr;
wchar_t *wcs_ptr2;
long int hostid;
/*
* File table of contents
*/

1462
bin/implicit.cc Normal file

File diff suppressed because it is too large Load diff

167
bin/macro.cc Normal file
View file

@ -0,0 +1,167 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* macro.cc
*
* Handle expansion of make macros
*/
/*
* Included files
*/
#include <mk/defs.h>
#include <mksh/macro.h> /* getvar(), expand_value() */
#include <mksh/misc.h> /* getmem() */
/*
* Defined macros
*/
/*
* typedefs & structs
*/
/*
* Static variables
*/
/*
* File table of contents
*/
void
setvar_append(register Name name, register Name value)
{
register Property macro_apx = get_prop(name->prop, macro_append_prop);
register Property macro = get_prop(name->prop, macro_prop);
int length;
String_rec destination;
wchar_t buffer[STRING_BUFFER_LENGTH];
register Chain chain;
Name val = NULL;
if(macro_apx == NULL) {
macro_apx = append_prop(name, macro_append_prop);
if(macro != NULL) {
macro_apx->body.macro_appendix.value = macro->body.macro.value;
}
}
val = macro_apx->body.macro_appendix.value_to_append;
INIT_STRING_FROM_STACK(destination, buffer);
buffer[0] = 0;
if (val != NULL) {
APPEND_NAME(val,
&destination,
(int) val->hash.length);
if (value != NULL) {
MBTOWC(wcs_buffer, " ");
append_char(wcs_buffer[0], &destination);
}
}
if (value != NULL) {
APPEND_NAME(value,
&destination,
(int) value->hash.length);
}
value = GETNAME(destination.buffer.start, FIND_LENGTH);
if (destination.free_after_use) {
retmem(destination.buffer.start);
}
macro_apx->body.macro_appendix.value_to_append = value;
SETVAR(name, empty_name, true);
}
/*
* setvar_envvar()
*
* This function scans the list of environment variables that have
* dynamic values and sets them.
*
* Parameters:
*
* Global variables used:
* envvar A list of environment vars with $ in value
*/
void
setvar_envvar(void)
{
wchar_t buffer[STRING_BUFFER_LENGTH];
int length;
register char *mbs, *tmp_mbs_buffer = NULL;
register char *env, *tmp_mbs_buffer2 = NULL;
Envvar p;
String_rec value;
for (p = envvar; p != NULL; p = p->next) {
if (p->already_put
) {
continue;
}
INIT_STRING_FROM_STACK(value, buffer);
expand_value(p->value, &value, false);
if ((length = wcslen(value.buffer.start)) >= MAXPATHLEN) {
mbs = tmp_mbs_buffer = getmem((length + 1) * MB_LEN_MAX);
(void) wcstombs(mbs,
value.buffer.start,
(length + 1) * MB_LEN_MAX);
} else {
mbs = mbs_buffer;
WCSTOMBS(mbs, value.buffer.start);
}
length = 2 + strlen(p->name->string_mb) + strlen(mbs);
if (!p->already_put || length > (MAXPATHLEN * MB_LEN_MAX)) {
env = tmp_mbs_buffer2 = getmem(length);
} else {
env = mbs_buffer2;
}
(void) sprintf(env,
"%s=%s",
p->name->string_mb,
mbs);
if (!p->already_put) {
(void) putenv(env);
p->already_put = true;
if (p->env_string) {
retmem_mb(p->env_string);
}
p->env_string = env;
tmp_mbs_buffer2 = NULL; // We should not return this memory now
}
if (tmp_mbs_buffer2) {
retmem_mb(tmp_mbs_buffer2);
tmp_mbs_buffer2 = NULL;
}
if (tmp_mbs_buffer) {
retmem_mb(tmp_mbs_buffer);
tmp_mbs_buffer = NULL;
}
}
}

3215
bin/main.cc Normal file

File diff suppressed because it is too large Load diff

498
bin/make.rules.file Normal file
View file

@ -0,0 +1,498 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
SUFFIXES = .o .c .c~ .cc .cc~ .y .y~ .l .l~ .s .s~ .sh .sh~ .S .S~ .i .ln \
.h .h~ .f .f~ .for .for~ .F .F~ .f90 .f90~ .ftn .ftn~ .mod .mod~ \
.sym .def .def~ .p .p~ .r .r~ .cps .cps~ .C .C~ .Y .Y~ .L .L~ \
.java .java~ .class
.SUFFIXES: $(SUFFIXES)
# OUTPUT_OPTION should be defined to "-o $@" when
# the default rules are used for non-local files.
OUTPUT_OPTION=
# C language section.
CC=cc
CFLAGS=
CPPFLAGS=
LINT=lint
LINTFLAGS=
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LINT.c=$(LINT) $(LINTFLAGS) $(CPPFLAGS)
.c:
$(LINK.c) -o $@ $< $(LDLIBS)
.c~:
$(GET) $(GFLAGS) -p $< > $*.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $*.c
.c.o:
$(COMPILE.c) $(OUTPUT_OPTION) $<
.c~.o:
$(GET) $(GFLAGS) -p $< > $*.c
$(CC) $(CFLAGS) -c $*.c
.c.i:
$(CC) $(CFLAGS) $(CPPFLAGS) -P $<
.c~.i:
$(GET) $(GFLAGS) -p $< > $*.c
$(CC) $(CFLAGS) $(CPPFLAGS) -P $*.c
.c.ln:
$(LINT.c) $(OUTPUT_OPTION) -c $<
.c~.ln:
$(GET) $(GFLAGS) -p $< > $*.c
$(LINT.c) $(OUTPUT_OPTION) -c $*.c
.c.a:
$(COMPILE.c) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.c~.a:
$(GET) $(GFLAGS) -p $< > $*.c
$(COMPILE.c) -o $% $*.c
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
# C language section. yacc.
YACC=yacc
YFLAGS=
YACC.y=$(YACC) $(YFLAGS)
.y:
$(YACC.y) $<
$(LINK.c) -o $@ y.tab.c $(LDLIBS)
$(RM) y.tab.c
.y~:
$(GET) $(GFLAGS) -p $< > $*.y
$(YACC) $(YFLAGS) $*.y
$(COMPILE.c) -o $@ y.tab.c
$(RM) y.tab.c
.y.c:
$(YACC.y) $<
mv y.tab.c $@
.y~.c:
$(GET) $(GFLAGS) -p $< > $*.y
$(YACC) $(YFLAGS) $*.y
mv y.tab.c $@
.y.ln:
$(YACC.y) $<
$(LINT.c) -o $@ -i y.tab.c
$(RM) y.tab.c
.y~.ln:
$(GET) $(GFLAGS) -p $< > $*.y
$(YACC.y) $*.y
$(LINT.c) -o $@ -i y.tab.c
$(RM) y.tab.c
.y.o:
$(YACC.y) $<
$(COMPILE.c) -o $@ y.tab.c
$(RM) y.tab.c
.y~.o:
$(GET) $(GFLAGS) -p $< > $*.y
$(YACC) $(YFLAGS) $*.y
$(CC) $(CFLAGS) -c y.tab.c
rm -f y.tab.c
mv y.tab.o $@
# C language section. lex.
LEX=lex
LFLAGS=
LEX.l=$(LEX) $(LFLAGS) -t
.l:
$(RM) $*.c
$(LEX.l) $< > $*.c
$(LINK.c) -o $@ $*.c -ll $(LDLIBS)
$(RM) $*.c
.l~:
$(GET) $(GFLAGS) -p $< > $*.l
$(LEX) $(LFLAGS) $*.l
$(CC) $(CFLAGS) -c lex.yy.c
rm -f lex.yy.c
mv lex.yy.c $@
.l.c :
$(RM) $@
$(LEX.l) $< > $@
.l~.c:
$(GET) $(GFLAGS) -p $< > $*.l
$(LEX) $(LFLAGS) $*.l
mv lex.yy.c $@
.l.ln:
$(RM) $*.c
$(LEX.l) $< > $*.c
$(LINT.c) -o $@ -i $*.c
$(RM) $*.c
.l~.ln:
$(GET) $(GFLAGS) -p $< > $*.l
$(RM) $*.c
$(LEX.l) $*.l > $*.c
$(LINT.c) -o $@ -i $*.c
$(RM) $*.c
.l.o:
$(RM) $*.c
$(LEX.l) $< > $*.c
$(COMPILE.c) -o $@ $*.c
$(RM) $*.c
.l~.o:
$(GET) $(GFLAGS) -p $< > $*.l
$(LEX) $(LFLAGS) $*.l
$(CC) $(CFLAGS) -c lex.yy.c
rm -f lex.yy.c
mv lex.yy.c $@
# C++ language section.
CCC=CC
CCFLAGS=
COMPILE.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) -c
LINK.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS)
COMPILE.C=$(CCC) $(CCFLAGS) $(CPPFLAGS) -c
LINK.C=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS)
.cc:
$(LINK.cc) -o $@ $< $(LDLIBS)
.cc~:
$(GET) $(GFLAGS) -p $< > $*.cc
$(LINK.cc) -o $@ $*.cc $(LDLIBS)
.cc.o:
$(COMPILE.cc) $(OUTPUT_OPTION) $<
.cc~.o:
$(GET) $(GFLAGS) -p $< > $*.cc
$(COMPILE.cc) $(OUTPUT_OPTION) $*.cc
.cc.i:
$(CCC) $(CCFLAGS) $(CPPFLAGS) -P $<
.cc~.i:
$(GET) $(GFLAGS) -p $< > $*.cc
$(CCC) $(CCFLAGS) $(CPPFLAGS) -P $*.cc
.cc.a:
$(COMPILE.cc) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.cc~.a:
$(GET) $(GFLAGS) -p $< > $*.cc
$(COMPILE.cc) -o $% $*.cc
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.C:
$(LINK.C) -o $@ $< $(LDLIBS)
.C~:
$(GET) $(GFLAGS) -p $< > $*.C
$(LINK.C) -o $@ $*.C $(LDLIBS)
.C.o:
$(COMPILE.C) $(OUTPUT_OPTION) $<
.C~.o:
$(GET) $(GFLAGS) -p $< > $*.C
$(COMPILE.C) $(OUTPUT_OPTION) $*.C
.C.i:
$(CCC) $(CCFLAGS) $(CPPFLAGS) -P $<
.C~.i:
$(GET) $(GFLAGS) -p $< > $*.C
$(CCC) $(CCFLAGS) $(CPPFLAGS) -P $*.C
.C.a:
$(COMPILE.C) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.C~.a:
$(GET) $(GFLAGS) -p $< > $*.C
$(COMPILE.C) -o $% $*.C
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
# FORTRAN section.
FC=f77
FFLAGS=
COMPILE.f=$(FC) $(FFLAGS) -c
LINK.f=$(FC) $(FFLAGS) $(LDFLAGS)
COMPILE.F=$(FC) $(FFLAGS) $(CPPFLAGS) -c
LINK.F=$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS)
.f:
$(LINK.f) -o $@ $< $(LDLIBS)
.f~:
$(GET) $(GFLAGS) -p $< > $*.f
$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.f
.f.o:
$(COMPILE.f) $(OUTPUT_OPTION) $<
.f~.o:
$(GET) $(GFLAGS) -p $< > $*.f
$(FC) $(FFLAGS) -c $*.f
.f.a:
$(COMPILE.f) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.f~.a:
$(GET) $(GFLAGS) -p $< > $*.f
$(COMPILE.f) -o $% $*.f
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.for:
$(LINK.f) -o $@ $< $(LDLIBS)
.for~:
$(GET) $(GFLAGS) -p $< > $*.for
$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.for
.for.o:
$(COMPILE.f) $(OUTPUT_OPTION) $<
.for~.o:
$(GET) $(GFLAGS) -p $< > $*.for
$(FC) $(FFLAGS) -c $*.for
.for.a:
$(COMPILE.f) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.for~.a:
$(GET) $(GFLAGS) -p $< > $*.for
$(COMPILE.f) -o $% $*.for
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.F:
$(LINK.F) -o $@ $< $(LDLIBS)
.F~:
$(GET) $(GFLAGS) -p $< > $*.F
$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.F
.F.o:
$(COMPILE.F) $(OUTPUT_OPTION) $<
.F~.o:
$(GET) $(GFLAGS) -p $< > $*.F
$(FC) $(FFLAGS) -c $*.F
.F.a:
$(COMPILE.F) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.F~.a:
$(GET) $(GFLAGS) -p $< > $*.F
$(COMPILE.F) -o $% $*.F
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
# FORTRAN section. ratfor.
RFLAGS=
COMPILE.r=$(FC) $(FFLAGS) $(RFLAGS) -c
LINK.r=$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS)
.r:
$(LINK.r) -o $@ $< $(LDLIBS)
.r~:
$(GET) $(GFLAGS) -p $< > $*.r
$(LINK.r) -o $@ $*.r $(LDLIBS)
.r.o:
$(COMPILE.r) $(OUTPUT_OPTION) $<
.r~.o:
$(GET) $(GFLAGS) -p $< > $*.r
$(COMPILE.r) $(OUTPUT_OPTION) $*.r
.r.a:
$(COMPILE.r) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.r~.a:
$(GET) $(GFLAGS) -p $< > $*.r
$(COMPILE.r) -o $% $*.r
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
# FORTRAN 90 section.
F90C=f90
F90FLAGS=
COMPILE.f90=$(F90C) $(F90FLAGS) -c
LINK.f90=$(F90C) $(F90FLAGS) $(LDFLAGS)
COMPILE.ftn=$(F90C) $(F90FLAGS) -c
LINK.ftn=$(F90C) $(F90FLAGS) $(LDFLAGS)
.f90:
$(LINK.f90) -o $@ $< $(LDLIBS)
.f90~:
$(GET) $(GFLAGS) -p $< > $*.f90
$(LINK.f90) -o $@ $*.f90 $(LDLIBS)
.f90.o:
$(COMPILE.f90) $(OUTPUT_OPTION) $<
.f90~.o:
$(GET) $(GFLAGS) -p $< > $*.f90
$(COMPILE.f90) $(OUTPUT_OPTION) $*.f90
.f90.a:
$(COMPILE.f90) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.f90~.a:
$(GET) $(GFLAGS) -p $< > $*.f90
$(COMPILE.f90) -o $% $*.f90
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.ftn:
$(LINK.ftn) -o $@ $< $(LDLIBS)
.ftn~:
$(GET) $(GFLAGS) -p $< > $*.ftn
$(LINK.ftn) -o $@ $*.ftn $(LDLIBS)
.ftn.o:
$(COMPILE.ftn) $(OUTPUT_OPTION) $<
.ftn~.o:
$(GET) $(GFLAGS) -p $< > $*.ftn
$(COMPILE.ftn) $(OUTPUT_OPTION) $*.ftn
.ftn.a:
$(COMPILE.ftn) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.ftn~.a:
$(GET) $(GFLAGS) -p $< > $*.ftn
$(COMPILE.ftn) -o $% $*.ftn
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
# Modula-2 section.
M2C=m2c
M2FLAGS=
MODFLAGS=
DEFFLAGS=
COMPILE.def=$(M2C) $(M2FLAGS) $(DEFFLAGS)
COMPILE.mod=$(M2C) $(M2FLAGS) $(MODFLAGS)
.def.sym:
$(COMPILE.def) -o $@ $<
.def~.sym:
$(GET) $(GFLAGS) -p $< > $*.def
$(COMPILE.def) -o $@ $*.def
.mod:
$(COMPILE.mod) -o $@ -e $@ $<
.mod~:
$(GET) $(GFLAGS) -p $< > $*.mod
$(COMPILE.mod) -o $@ -e $@ $*.mod
.mod.o:
$(COMPILE.mod) -o $@ $<
.mod~.o:
$(GET) $(GFLAGS) -p $< > $*.mod
$(COMPILE.mod) -o $@ $*.mod
.mod.a:
$(COMPILE.mod) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.mod~.a:
$(GET) $(GFLAGS) -p $< > $*.mod
$(COMPILE.mod) -o $% $*.mod
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
# Pascal section.
PC=pc
PFLAGS=
COMPILE.p=$(PC) $(PFLAGS) $(CPPFLAGS) -c
LINK.p=$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS)
.p:
$(LINK.p) -o $@ $< $(LDLIBS)
.p~:
$(GET) $(GFLAGS) -p $< > $*.p
$(LINK.p) -o $@ $*.p $(LDLIBS)
.p.o:
$(COMPILE.p) $(OUTPUT_OPTION) $<
.p~.o:
$(GET) $(GFLAGS) -p $< > $*.p
$(COMPILE.p) $(OUTPUT_OPTION) $*.p
.p.a:
$(COMPILE.p) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.p~.a:
$(GET) $(GFLAGS) -p $< > $*.p
$(COMPILE.p) -o $% $*.p
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
# Assembly section.
AS=as
ASFLAGS=
COMPILE.s=$(AS) $(ASFLAGS)
COMPILE.S=$(CC) $(ASFLAGS) $(CPPFLAGS) -c
.s.o:
$(COMPILE.s) -o $@ $<
.s~.o:
$(GET) $(GFLAGS) -p $< > $*.s
$(COMPILE.s) -o $@ $*.s
.s.a:
$(COMPILE.s) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.s~.a:
$(GET) $(GFLAGS) -p $< > $*.s
$(COMPILE.s) -o $% $*.s
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.S.o:
$(COMPILE.S) -o $@ $<
.S~.o:
$(GET) $(GFLAGS) -p $< > $*.S
$(COMPILE.S) -o $@ $*.S
.S.a:
$(COMPILE.S) -o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
.S~.a:
$(GET) $(GFLAGS) -p $< > $*.S
$(COMPILE.S) -o $% $*.S
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
# Shell section.
.sh:
$(RM) $@
cat $< > $@
chmod +x $@
.sh~:
$(GET) $(GFLAGS) -p $< > $*.sh
cp $*.sh $@
chmod a+x $@
# NeWS section
CPS=cps
CPSFLAGS=
.cps.h:
$(CPS) $(CPSFLAGS) $*.cps
.cps~.h:
$(GET) $(GFLAGS) -p $< > $*.cps
$(CPS) $(CPSFLAGS) $*.cps
# JAVA section
JAVAC=javac
JAVACFLAGS=
.java.class:
$(JAVAC) $(JAVACFLAGS) $<
.java~.class:
$(GET) $(GFLAGS) -p $< > $*.java
$(JAVAC) $(JAVACFLAGS) $<
# Miscellaneous section.
LD=ld
LDFLAGS=
LDLIBS=
MAKE=make
RM=rm -f
AR=ar
ARFLAGS=rv
GET=get
GFLAGS=
markfile.o: markfile
echo "static char _sccsid[] = \"`grep @'(#)' markfile`\";" > markfile.c
cc -c markfile.c
$(RM) markfile.c
SCCSFLAGS=
SCCSGETFLAGS=-s
.SCCS_GET:
sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@ -G$@
.SCCS_GET_POSIX:
sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@
.GET_POSIX:
$(GET) $(GFLAGS) s.$@

736
bin/misc.cc Normal file
View file

@ -0,0 +1,736 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* misc.cc
*
* This file contains various unclassified routines. Some main groups:
* getname
* Memory allocation
* String handling
* Property handling
* Error message handling
* Make internal state dumping
* main routine support
*/
/*
* Included files
*/
#include <errno.h>
#include <mk/defs.h>
#include <mksh/macro.h> /* SETVAR() */
#include <mksh/misc.h> /* enable_interrupt() */
#include <stdarg.h> /* va_list, va_start(), va_end() */
#include <vroot/report.h> /* SUNPRO_DEPENDENCIES */
#include <libintl.h>
extern void job_adjust_fini();
/*
* Defined macros
*/
/*
* typedefs & structs
*/
/*
* Static variables
*/
/*
* File table of contents
*/
static void print_rule(register Name target);
static void print_target_n_deps(register Name target);
/*****************************************
*
* getname
*/
/*****************************************
*
* Memory allocation
*/
/*
* free_chain()
*
* frees a chain of Name_vector's
*
* Parameters:
* ptr Pointer to the first element in the chain
* to be freed.
*
* Global variables used:
*/
void
free_chain(Name_vector ptr)
{
if (ptr != NULL) {
if (ptr->next != NULL) {
free_chain(ptr->next);
}
free((char *) ptr);
}
}
/*****************************************
*
* String manipulation
*/
/*****************************************
*
* Nameblock property handling
*/
/*****************************************
*
* Error message handling
*/
/*
* fatal(format, args...)
*
* Print a message and die
*
* Parameters:
* format printf type format string
* args Arguments to match the format
*
* Global variables used:
* fatal_in_progress Indicates if this is a recursive call
* parallel_process_cnt Do we need to wait for anything?
* report_pwd Should we report the current path?
*/
/*VARARGS*/
void
fatal(const char *message, ...)
{
va_list args;
va_start(args, message);
(void) fflush(stdout);
(void) fprintf(stderr, gettext("%s: Fatal error: "), getprogname());
(void) vfprintf(stderr, message, args);
(void) fprintf(stderr, "\n");
va_end(args);
if (report_pwd) {
(void) fprintf(stderr,
gettext("Current working directory %s\n"),
get_current_path());
}
(void) fflush(stderr);
if (fatal_in_progress) {
exit_status = 1;
exit(1);
}
fatal_in_progress = true;
/* Let all parallel children finish */
if ((dmake_mode_type == parallel_mode) &&
(parallel_process_cnt > 0)) {
(void) fprintf(stderr,
gettext("Waiting for %d %s to finish\n"),
parallel_process_cnt,
parallel_process_cnt == 1 ?
gettext("job") : gettext("jobs"));
(void) fflush(stderr);
}
while (parallel_process_cnt > 0) {
await_parallel(true);
finish_children(false);
}
job_adjust_fini();
exit_status = 1;
exit(1);
}
/*
* warning(format, args...)
*
* Print a message and continue.
*
* Parameters:
* format printf type format string
* args Arguments to match the format
*
* Global variables used:
* report_pwd Should we report the current path?
*/
/*VARARGS*/
void
warning(char * message, ...)
{
va_list args;
va_start(args, message);
(void) fflush(stdout);
(void) fprintf(stderr, gettext("%s: Warning: "), getprogname());
(void) vfprintf(stderr, message, args);
(void) fprintf(stderr, "\n");
va_end(args);
if (report_pwd) {
(void) fprintf(stderr,
gettext("Current working directory %s\n"),
get_current_path());
}
(void) fflush(stderr);
}
/*
* time_to_string(time)
*
* Take a numeric time value and produce
* a proper string representation.
*
* Return value:
* The string representation of the time
*
* Parameters:
* time The time we need to translate
*
* Global variables used:
*/
char *
time_to_string(const timestruc_t &time)
{
struct tm *tm;
char buf[128];
if (time == file_doesnt_exist) {
return gettext("File does not exist");
}
if (time == file_max_time) {
return gettext("Younger than any file");
}
tm = localtime(&time.tv_sec);
strftime(buf, sizeof (buf), "%c %Z", tm);
buf[127] = (int) nul_char;
return strdup(buf);
}
/*
* get_current_path()
*
* Stuff current_path with the current path if it isnt there already.
*
* Parameters:
*
* Global variables used:
*/
char *
get_current_path(void)
{
char pwd[(MAXPATHLEN * MB_LEN_MAX)];
static char *current_path;
if (current_path == NULL) {
getcwd(pwd, sizeof(pwd));
if (pwd[0] == (int) nul_char) {
pwd[0] = (int) slash_char;
pwd[1] = (int) nul_char;
}
current_path = strdup(pwd);
}
return current_path;
}
/*****************************************
*
* Make internal state dumping
*
* This is a set of routines for dumping the internal make state
* Used for the -p option
*/
/*
* dump_make_state()
*
* Dump make's internal state to stdout
*
* Parameters:
*
* Global variables used:
* svr4 Was ".SVR4" seen in makefile?
* svr4_name The Name ".SVR4", printed
* posix Was ".POSIX" seen in makefile?
* posix_name The Name ".POSIX", printed
* default_rule Points to the .DEFAULT rule
* default_rule_name The Name ".DEFAULT", printed
* default_target_to_build The first target to print
* dot_keep_state The Name ".KEEP_STATE", printed
* dot_keep_state_file The Name ".KEEP_STATE_FILE", printed
* hashtab The make hash table for Name blocks
* ignore_errors Was ".IGNORE" seen in makefile?
* ignore_name The Name ".IGNORE", printed
* keep_state Was ".KEEP_STATE" seen in makefile?
* percent_list The list of % rules
* precious The Name ".PRECIOUS", printed
* sccs_get_name The Name ".SCCS_GET", printed
* sccs_get_posix_name The Name ".SCCS_GET_POSIX", printed
* get_name The Name ".GET", printed
* get_posix_name The Name ".GET_POSIX", printed
* sccs_get_rule Points to the ".SCCS_GET" rule
* silent Was ".SILENT" seen in makefile?
* silent_name The Name ".SILENT", printed
* suffixes The suffix list from ".SUFFIXES"
* suffixes_name The Name ".SUFFIX", printed
*/
void
dump_make_state(void)
{
Name_set::iterator p, e;
register Property prop;
register Dependency dep;
register Cmd_line rule;
Percent percent, percent_depe;
/* Default target */
if (default_target_to_build != NULL) {
print_rule(default_target_to_build);
}
(void) printf("\n");
/* .POSIX */
if (posix) {
(void) printf("%s:\n", posix_name->string_mb);
}
/* .DEFAULT */
if (default_rule != NULL) {
(void) printf("%s:\n", default_rule_name->string_mb);
for (rule = default_rule; rule != NULL; rule = rule->next) {
(void) printf("\t%s\n", rule->command_line->string_mb);
}
}
/* .IGNORE */
if (ignore_errors) {
(void) printf("%s:\n", ignore_name->string_mb);
}
/* .KEEP_STATE: */
if (keep_state) {
(void) printf("%s:\n\n", dot_keep_state->string_mb);
}
/* .PRECIOUS */
(void) printf("%s:", precious->string_mb);
for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
if ((p->stat.is_precious) || (all_precious)) {
(void) printf(" %s", p->string_mb);
}
}
(void) printf("\n");
/* .SCCS_GET */
if (sccs_get_rule != NULL) {
(void) printf("%s:\n", sccs_get_name->string_mb);
for (rule = sccs_get_rule; rule != NULL; rule = rule->next) {
(void) printf("\t%s\n", rule->command_line->string_mb);
}
}
/* .SILENT */
if (silent) {
(void) printf("%s:\n", silent_name->string_mb);
}
/* .SUFFIXES: */
(void) printf("%s:", suffixes_name->string_mb);
for (dep = suffixes; dep != NULL; dep = dep->next) {
(void) printf(" %s", dep->name->string_mb);
build_suffix_list(dep->name);
}
(void) printf("\n\n");
/* % rules */
for (percent = percent_list;
percent != NULL;
percent = percent->next) {
(void) printf("%s:",
percent->name->string_mb);
for (percent_depe = percent->dependencies;
percent_depe != NULL;
percent_depe = percent_depe->next) {
(void) printf(" %s", percent_depe->name->string_mb);
}
(void) printf("\n");
for (rule = percent->command_template;
rule != NULL;
rule = rule->next) {
(void) printf("\t%s\n", rule->command_line->string_mb);
}
}
/* Suffix rules */
for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
Wstring wcb(p);
if (wcb.get_string()[0] == (int) period_char) {
print_rule(p);
}
}
/* Macro assignments */
for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
if (((prop = get_prop(p->prop, macro_prop)) != NULL) &&
(prop->body.macro.value != NULL)) {
(void) printf("%s", p->string_mb);
print_value(prop->body.macro.value,
(Daemon) prop->body.macro.daemon);
}
}
(void) printf("\n");
/* Conditional macro assignments */
for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
for (prop = get_prop(p->prop, conditional_prop);
prop != NULL;
prop = get_prop(prop->next, conditional_prop)) {
(void) printf("%s := %s",
p->string_mb,
prop->body.conditional.name->
string_mb);
if (prop->body.conditional.append) {
printf(" +");
}
else {
printf(" ");
}
print_value(prop->body.conditional.value,
no_daemon);
}
}
(void) printf("\n");
/* All other dependencies */
for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
if (p->colons != no_colon) {
print_rule(p);
}
}
(void) printf("\n");
}
/*
* print_rule(target)
*
* Print the rule for one target
*
* Parameters:
* target Target we print rule for
*
* Global variables used:
*/
static void
print_rule(register Name target)
{
register Cmd_line rule;
register Property line;
register Dependency dependency;
if (target->dependency_printed ||
((line = get_prop(target->prop, line_prop)) == NULL) ||
((line->body.line.command_template == NULL) &&
(line->body.line.dependencies == NULL))) {
return;
}
target->dependency_printed = true;
(void) printf("%s:", target->string_mb);
for (dependency = line->body.line.dependencies;
dependency != NULL;
dependency = dependency->next) {
(void) printf(" %s", dependency->name->string_mb);
}
(void) printf("\n");
for (rule = line->body.line.command_template;
rule != NULL;
rule = rule->next) {
(void) printf("\t%s\n", rule->command_line->string_mb);
}
}
void
dump_target_list(void)
{
Name_set::iterator p, e;
Wstring str;
for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
str.init(p);
wchar_t * wcb = str.get_string();
if ((p->colons != no_colon) &&
((wcb[0] != (int) period_char) ||
((wcb[0] == (int) period_char) &&
(wcschr(wcb, (int) slash_char))))) {
print_target_n_deps(p);
}
}
}
static void
print_target_n_deps(register Name target)
{
register Cmd_line rule;
register Property line;
register Dependency dependency;
if (target->dependency_printed) {
return;
}
target->dependency_printed = true;
(void) printf("%s\n", target->string_mb);
if ((line = get_prop(target->prop, line_prop)) == NULL) {
return;
}
for (dependency = line->body.line.dependencies;
dependency != NULL;
dependency = dependency->next) {
if (!dependency->automatic) {
print_target_n_deps(dependency->name);
}
}
}
/*****************************************
*
* main() support
*/
/*
* load_cached_names()
*
* Load the vector of cached names
*
* Parameters:
*
* Global variables used:
* Many many pointers to Name blocks.
*/
void
load_cached_names(void)
{
char *cp;
Name dollar;
/* Load the cached_names struct */
MBSTOWCS(wcs_buffer, ".BUILT_LAST_MAKE_RUN");
built_last_make_run = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "@");
c_at = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, " *conditionals* ");
conditionals = GETNAME(wcs_buffer, FIND_LENGTH);
/*
* A version of make was released with NSE 1.0 that used
* VERSION-1.1 but this version is identical to VERSION-1.0.
* The version mismatch code makes a special case for this
* situation. If the version number is changed from 1.0
* it should go to 1.2.
*/
MBSTOWCS(wcs_buffer, "VERSION-1.0");
current_make_version = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".SVR4");
svr4_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".POSIX");
posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".DEFAULT");
default_rule_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "$");
dollar = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".DONE");
done = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".");
dot = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".KEEP_STATE");
dot_keep_state = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".KEEP_STATE_FILE");
dot_keep_state_file = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "");
empty_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, " FORCE");
force = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "HOST_ARCH");
host_arch = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "HOST_MACH");
host_mach = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".IGNORE");
ignore_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".INIT");
init = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".LOCAL");
localhost_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".make.state");
make_state = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "MAKEFLAGS");
makeflags = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".MAKE_VERSION");
make_version = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".NO_PARALLEL");
no_parallel_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".NOT_AUTO");
not_auto = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".PARALLEL");
parallel_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "PATH");
path_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "+");
plus = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".PRECIOUS");
precious = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "?");
query = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "^");
hat = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".RECURSIVE");
recursive_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".SCCS_GET");
sccs_get_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".SCCS_GET_POSIX");
sccs_get_posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".GET");
get_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".GET_POSIX");
get_posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "SHELL");
shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".SILENT");
silent_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".SUFFIXES");
suffixes_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, SUNPRO_DEPENDENCIES);
sunpro_dependencies = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "TARGET_ARCH");
target_arch = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "TARGET_MACH");
target_mach = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "VIRTUAL_ROOT");
virtual_root = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, "VPATH");
vpath_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, ".WAIT");
wait_name = GETNAME(wcs_buffer, FIND_LENGTH);
wait_name->state = build_ok;
/* Mark special targets so that the reader treats them properly */
svr4_name->special_reader = svr4_special;
posix_name->special_reader = posix_special;
built_last_make_run->special_reader = built_last_make_run_special;
default_rule_name->special_reader = default_special;
dot_keep_state->special_reader = keep_state_special;
dot_keep_state_file->special_reader = keep_state_file_special;
ignore_name->special_reader = ignore_special;
make_version->special_reader = make_version_special;
no_parallel_name->special_reader = no_parallel_special;
parallel_name->special_reader = parallel_special;
localhost_name->special_reader = localhost_special;
precious->special_reader = precious_special;
sccs_get_name->special_reader = sccs_get_special;
sccs_get_posix_name->special_reader = sccs_get_posix_special;
get_name->special_reader = get_special;
get_posix_name->special_reader = get_posix_special;
silent_name->special_reader = silent_special;
suffixes_name->special_reader = suffixes_special;
/* The value of $$ is $ */
(void) SETVAR(dollar, dollar, false);
dollar->dollar = false;
/* Set the value of $(SHELL) */
if (posix) {
MBSTOWCS(wcs_buffer, "/usr/xpg4/bin/sh");
} else {
MBSTOWCS(wcs_buffer, "/bin/sh");
}
(void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
/*
* Use " FORCE" to simulate a FRC dependency for :: type
* targets with no dependencies.
*/
(void) append_prop(force, line_prop);
force->stat.time = file_max_time;
/* Make sure VPATH is defined before current dir is read */
if ((cp = getenv(vpath_name->string_mb)) != NULL) {
MBSTOWCS(wcs_buffer, cp);
(void) SETVAR(vpath_name,
GETNAME(wcs_buffer, FIND_LENGTH),
false);
}
/* Check if there is NO PATH variable. If not we construct one. */
if (getenv(path_name->string_mb) == NULL) {
vroot_path = NULL;
add_dir_to_path(".", &vroot_path, -1);
add_dir_to_path("/bin", &vroot_path, -1);
add_dir_to_path("/usr/bin", &vroot_path, -1);
}
}
/*
* iterate on list of conditional macros in np, and place them in
* a String_rec starting with, and separated by the '$' character.
*/
void
cond_macros_into_string(Name np, String_rec *buffer)
{
Macro_list macro_list;
/*
* Put the version number at the start of the string
*/
MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
append_string(wcs_buffer, buffer, FIND_LENGTH);
/*
* Add the rest of the conditional macros to the buffer
*/
if (np->depends_on_conditional){
for (macro_list = np->conditional_macro_list;
macro_list != NULL; macro_list = macro_list->next){
append_string(macro_list->macro_name, buffer,
FIND_LENGTH);
append_char((int) equal_char, buffer);
append_string(macro_list->value, buffer, FIND_LENGTH);
append_char((int) dollar_char, buffer);
}
}
}

365
bin/nse_printdep.cc Normal file
View file

@ -0,0 +1,365 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Included files
*/
#include <mk/defs.h>
#include <mksh/misc.h> /* get_prop() */
/*
* File table of contents
*/
void print_dependencies(register Name target, register Property line);
static void print_deps(register Name target, register Property line);
static void print_more_deps(Name target, Name name);
static void print_filename(Name name);
static Boolean should_print_dep(Property line);
static void print_forest(Name target);
static void print_deplist(Dependency head);
void print_value(register Name value, Daemon daemon);
static void print_rule(register Name target);
static void print_rec_info(Name target);
static Boolean is_out_of_date(Property line);
extern void depvar_print_results (void);
/*
* print_dependencies(target, line)
*
* Print all the dependencies of a target. First print all the Makefiles.
* Then print all the dependencies. Finally, print all the .INIT
* dependencies.
*
* Parameters:
* target The target we print dependencies for
* line We get the dependency list from here
*
* Global variables used:
* done The Name ".DONE"
* init The Name ".INIT"
* makefiles_used List of all makefiles read
*/
void
print_dependencies(register Name target, register Property line)
{
Dependency dp;
static Boolean makefiles_printed = false;
if (target_variants) {
depvar_print_results();
}
if (!makefiles_printed) {
/*
* Search the makefile list for the primary makefile,
* then print it and its inclusions. After that go back
* and print the default.mk file and its inclusions.
*/
for (dp = makefiles_used; dp != NULL; dp = dp->next) {
if (dp->name == primary_makefile) {
break;
}
}
if (dp) {
print_deplist(dp);
for (dp = makefiles_used; dp != NULL; dp = dp->next) {
if (dp->name == primary_makefile) {
break;
}
(void)printf(" %s", dp->name->string_mb);
}
}
(void) printf("\n");
makefiles_printed = true;
}
print_deps(target, line);
/*
print_more_deps(target, init);
print_more_deps(target, done);
*/
if (target_variants) {
print_forest(target);
}
}
/*
* print_more_deps(target, name)
*
* Print some special dependencies.
* These are the dependencies for the .INIT and .DONE targets.
*
* Parameters:
* target Target built during make run
* name Special target to print dependencies for
*
* Global variables used:
*/
static void
print_more_deps(Name target, Name name)
{
Property line;
register Dependency dependencies;
line = get_prop(name->prop, line_prop);
if (line != NULL && line->body.line.dependencies != NULL) {
(void) printf("%s:\t", target->string_mb);
print_deplist(line->body.line.dependencies);
(void) printf("\n");
for (dependencies= line->body.line.dependencies;
dependencies != NULL;
dependencies= dependencies->next) {
print_deps(dependencies->name,
get_prop(dependencies->name->prop, line_prop));
}
}
}
/*
* print_deps(target, line, go_recursive)
*
* Print a regular dependency list. Append to this information which
* indicates whether or not the target is recursive.
*
* Parameters:
* target target to print dependencies for
* line We get the dependency list from here
* go_recursive Should we show all dependencies recursively?
*
* Global variables used:
* recursive_name The Name ".RECURSIVE", printed
*/
static void
print_deps(register Name target, register Property line)
{
register Dependency dep;
if ((target->dependency_printed) ||
(target == force)) {
return;
}
target->dependency_printed = true;
/* only print entries that are actually derived and are not leaf
* files and are not the result of sccs get.
*/
if (should_print_dep(line)) {
if ((report_dependencies_level == 2) ||
(report_dependencies_level == 4)) {
if (is_out_of_date(line)) {
(void) printf("1 ");
} else {
(void) printf("0 ");
}
}
print_filename(target);
(void) printf(":\t");
print_deplist(line->body.line.dependencies);
print_rec_info(target);
(void) printf("\n");
for (dep = line->body.line.dependencies;
dep != NULL;
dep = dep->next) {
print_deps(dep->name,
get_prop(dep->name->prop, line_prop));
}
}
}
static Boolean
is_out_of_date(Property line)
{
Dependency dep;
Property line2;
if (line == NULL) {
return false;
}
if (line->body.line.is_out_of_date) {
return true;
}
for (dep = line->body.line.dependencies;
dep != NULL;
dep = dep->next) {
line2 = get_prop(dep->name->prop, line_prop);
if (is_out_of_date(line2)) {
line->body.line.is_out_of_date = true;
return true;
}
}
return false;
}
/*
* Given a dependency print it and all its siblings.
*/
static void
print_deplist(Dependency head)
{
Dependency dp;
for (dp = head; dp != NULL; dp = dp->next) {
if ((report_dependencies_level != 2) ||
((!dp->automatic) ||
(dp->name->is_double_colon))) {
if (dp->name != force) {
putwchar(' ');
print_filename(dp->name);
}
}
}
}
/*
* Print the name of a file for the -P option.
* If the file is a directory put on a trailing slash.
*/
static void
print_filename(Name name)
{
(void) printf("%s", name->string_mb);
/*
if (name->stat.is_dir) {
putwchar('/');
}
*/
}
/*
* should_print_dep(line)
*
* Test if we should print the dependencies of this target.
* The line must exist and either have children dependencies
* or have a command that is not an SCCS command.
*
* Return value:
* true if the dependencies should be printed
*
* Parameters:
* line We get the dependency list from here
*
* Global variables used:
*/
static Boolean
should_print_dep(Property line)
{
if (line == NULL) {
return false;
}
if (line->body.line.dependencies != NULL) {
return true;
}
if (line->body.line.sccs_command) {
return false;
}
return true;
}
/*
* Print out the root nodes of all the dependency trees
* in this makefile.
*/
static void
print_forest(Name target)
{
Name_set::iterator np, e;
Property line;
for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
if (np->is_target && !np->has_parent && np != target) {
(void) doname_check(np, true, false, false);
line = get_prop(np->prop, line_prop);
printf("-\n");
print_deps(np, line);
}
}
}
/*
* This is a set of routines for dumping the internal make state
* Used for the -p option
*/
void
print_value(register Name value, Daemon daemon)
{
Chain cp;
if (value == NULL)
(void)printf("=\n");
else
switch (daemon) {
case no_daemon:
(void)printf("= %s\n", value->string_mb);
break;
case chain_daemon:
for (cp= (Chain) value; cp != NULL; cp= cp->next)
(void)printf(cp->next == NULL ? "%s" : "%s ",
cp->name->string_mb);
(void)printf("\n");
break;
};
}
static void
print_rule(register Name target)
{
register Cmd_line rule;
register Property line;
if (((line= get_prop(target->prop, line_prop)) == NULL) ||
((line->body.line.command_template == NULL) &&
(line->body.line.dependencies == NULL)))
return;
print_dependencies(target, line);
for (rule= line->body.line.command_template; rule != NULL; rule= rule->next)
(void)printf("\t%s\n", rule->command_line->string_mb);
}
/*
* If target is recursive, print the following to standard out:
* .RECURSIVE subdir targ Makefile
*/
static void
print_rec_info(Name target)
{
Recursive_make rp;
wchar_t *colon;
report_recursive_init();
rp = find_recursive_target(target);
if (rp) {
/*
* if found, print starting with the space after the ':'
*/
colon = (wchar_t *) wcschr(rp->oldline, (int) colon_char);
(void) printf("%s", colon + 1);
}
}

1892
bin/parallel.cc Normal file

File diff suppressed because it is too large Load diff

420
bin/pmake.cc Normal file
View file

@ -0,0 +1,420 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Included files
*/
#include <arpa/inet.h>
#include <mk/defs.h>
#include <mksh/misc.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <rpc/rpc.h> /* host2netname(), netname2host() */
#include <libintl.h>
/*
* Defined macros
*/
/*
* typedefs & structs
*/
/*
* Static variables
*/
/*
* File table of contents
*/
static int get_max(wchar_t **ms_address, wchar_t *hostname);
static Boolean pskip_comment(wchar_t **cp_address);
static void pskip_till_next_word(wchar_t **cp);
static Boolean pskip_white_space(wchar_t **cp_address);
/*
* read_make_machines(Name make_machines_name)
*
* For backwards compatibility w/ PMake 1.x, when DMake 2.x is
* being run in parallel mode, DMake should parse the PMake startup
* file $(HOME)/.make.machines to get the PMake max jobs.
*
* Return value:
* int of PMake max jobs
*
* Parameters:
* make_machines_name Name of .make.machines file
*
*/
int
read_make_machines(Name make_machines_name)
{
wchar_t c;
Boolean default_make_machines;
struct hostent *hp;
wchar_t local_host[MAX_HOSTNAMELEN + 1];
char local_host_mb[MAX_HOSTNAMELEN + 1] = "";
int local_host_wslen;
wchar_t full_host[MAXNETNAMELEN + 1];
int full_host_wslen = 0;
char *homedir;
Name MAKE_MACHINES;
struct stat make_machines_buf;
FILE *make_machines_file;
wchar_t *make_machines_list = NULL;
char *make_machines_list_mb = NULL;
wchar_t make_machines_path[MAXPATHLEN];
char mb_make_machines_path[MAXPATHLEN];
wchar_t *mp;
wchar_t *ms;
int pmake_max_jobs = 0;
struct utsname uts_info;
MBSTOWCS(wcs_buffer, "MAKE_MACHINES");
MAKE_MACHINES = GETNAME(wcs_buffer, FIND_LENGTH);
/* Did the user specify a .make.machines file on the command line? */
default_make_machines = false;
if (make_machines_name == NULL) {
/* Try reading the default .make.machines file, in $(HOME). */
homedir = getenv("HOME");
if ((homedir != NULL) && (strlen(homedir) < (sizeof(mb_make_machines_path) - 16))) {
sprintf(mb_make_machines_path,
"%s/.make.machines", homedir);
MBSTOWCS(make_machines_path, mb_make_machines_path);
make_machines_name = GETNAME(make_machines_path, FIND_LENGTH);
default_make_machines = true;
}
if (make_machines_name == NULL) {
/*
* No $(HOME)/.make.machines file.
* Return 0 for PMake max jobs.
*/
return(0);
}
}
/*
make_machines_list_mb = getenv(MAKE_MACHINES->string_mb);
*/
/* Open the .make.machines file. */
if ((make_machines_file = fopen(make_machines_name->string_mb, "r")) == NULL) {
if (!default_make_machines) {
/* Error opening .make.machines file. */
fatal(gettext("Open of %s failed: %s"),
make_machines_name->string_mb,
errmsg(errno));
} else {
/*
* No $(HOME)/.make.machines file.
* Return 0 for PMake max jobs.
*/
return(0);
}
/* Stat the .make.machines file to get the size of the file. */
} else if (fstat(fileno(make_machines_file), &make_machines_buf) < 0) {
/* Error stat'ing .make.machines file. */
fatal(gettext("Stat of %s failed: %s"),
make_machines_name->string_mb,
errmsg(errno));
} else {
/* Allocate memory for "MAKE_MACHINES=<contents of .m.m>" */
make_machines_list_mb =
(char *) getmem((int) (strlen(MAKE_MACHINES->string_mb) +
2 +
make_machines_buf.st_size));
sprintf(make_machines_list_mb,
"%s=",
MAKE_MACHINES->string_mb);
/* Read in the .make.machines file. */
if (fread(make_machines_list_mb + strlen(MAKE_MACHINES->string_mb) + 1,
sizeof(char),
(int) make_machines_buf.st_size,
make_machines_file) != make_machines_buf.st_size) {
/*
* Error reading .make.machines file.
* Return 0 for PMake max jobs.
*/
warning(gettext("Unable to read %s"),
make_machines_name->string_mb);
(void) fclose(make_machines_file);
retmem_mb((caddr_t) make_machines_list_mb);
return(0);
} else {
(void) fclose(make_machines_file);
/* putenv "MAKE_MACHINES=<contents of .m.m>" */
*(make_machines_list_mb +
strlen(MAKE_MACHINES->string_mb) +
1 +
make_machines_buf.st_size) = (int) nul_char;
if (putenv(make_machines_list_mb) != 0) {
warning(gettext("Couldn't put contents of %s in environment"),
make_machines_name->string_mb);
} else {
make_machines_list_mb += strlen(MAKE_MACHINES->string_mb) + 1;
make_machines_list = ALLOC_WC(strlen(make_machines_list_mb) + 1);
(void) mbstowcs(make_machines_list,
make_machines_list_mb,
(strlen(make_machines_list_mb) + 1));
}
}
}
uname(&uts_info);
strcpy(local_host_mb, &uts_info.nodename[0]);
MBSTOWCS(local_host, local_host_mb);
local_host_wslen = wcslen(local_host);
// There is no getdomainname() function on Solaris.
// And netname2host() function does not work on Linux.
// So we have to use different APIs.
if (host2netname(mbs_buffer, NULL, NULL) &&
netname2host(mbs_buffer, mbs_buffer2, MAXNETNAMELEN+1)) {
MBSTOWCS(full_host, mbs_buffer2);
full_host_wslen = wcslen(full_host);
}
for (ms = make_machines_list;
(ms) && (*ms );
) {
/*
* Skip white space and comments till you reach
* a machine name.
*/
pskip_till_next_word(&ms);
/*
* If we haven't reached the end of file, process the
* machine name.
*/
if (*ms) {
/*
* If invalid machine name decrement counter
* and skip line.
*/
mp = ms;
SKIPWORD(ms);
c = *ms;
*ms++ = '\0'; /* Append null to machine name. */
/*
* If this was the beginning of a comment
* (we overwrote a # sign) and it's not
* end of line yet, shift the # sign.
*/
if ((c == '#') && (*ms != '\n') && (*ms)) {
*ms = '#';
}
WCSTOMBS(mbs_buffer, mp);
/*
* Print "Ignoring unknown host" if:
* 1) hostname is longer than MAX_HOSTNAMELEN, or
* 2) hostname is unknown
*/
if ((wcslen(mp) > MAX_HOSTNAMELEN) ||
((hp = gethostbyname(mbs_buffer)) == NULL)) {
warning(gettext("Ignoring unknown host %s"),
mbs_buffer);
SKIPTOEND(ms);
/* Increment ptr if not end of file. */
if (*ms) {
ms++;
}
} else {
/* Compare current hostname with local_host. */
if (wcslen(mp) == local_host_wslen &&
IS_WEQUALN(mp, local_host, local_host_wslen)) {
/*
* Bingo, local_host is in .make.machines.
* Continue reading.
*/
pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
/* Compare current hostname with full_host. */
} else if (wcslen(mp) == full_host_wslen &&
IS_WEQUALN(mp, full_host, full_host_wslen)) {
/*
* Bingo, full_host is in .make.machines.
* Continue reading.
*/
pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
} else {
if (c != '\n') {
SKIPTOEND(ms);
if (*ms) {
ms++;
}
}
continue;
}
/* If we get here, local_host is in .make.machines. */
if (c != '\n') {
/* Now look for keyword 'max'. */
MBSTOWCS(wcs_buffer, "max");
SKIPSPACE(ms);
while ((*ms != '\n') && (*ms)) {
if (*ms == '#') {
pskip_comment(&ms);
} else if (IS_WEQUALN(ms, wcs_buffer, 3)) {
/* Skip "max". */
ms += 3;
pmake_max_jobs = get_max(&ms, mp);
SKIPSPACE(ms);
} else {
warning(gettext("unknown option for host %s"), mbs_buffer);
SKIPTOEND(ms);
break;
}
}
}
break; /* out of outermost for() loop. */
}
}
}
retmem(make_machines_list);
return(pmake_max_jobs);
}
/*
* pskip_till_next_word(cp)
*
* Parameters:
* cp the address of the string pointer.
*
* On return:
* cp points to beginning of machine name.
*
*/
static void
pskip_till_next_word(wchar_t **cp)
{
/*
* Keep recursing until all combinations of white spaces
* and comments have been skipped.
*/
if (pskip_white_space(cp) || pskip_comment(cp)) {
pskip_till_next_word(cp);
}
}
/*
* pskip_white_space(cp_address)
*
* Advances the string pointer so that it points to the first
* non white character (space/tab/linefeed).
*
* Parameters:
* cp_address the address of the string pointer.
*
* Return Value:
* True if the pointer was changed.
*
*/
static Boolean
pskip_white_space(wchar_t **cp_address)
{
wchar_t *cp = *cp_address;
while (*cp && iswspace(*cp)) {
cp++;
}
/* Have we skipped any characters? */
if (cp != *cp_address) {
*cp_address = cp;
return(true);
} else {
return(false);
}
}
/*
* pskip_comment(cp_address)
*
* If cp_address is pointing to '#' (the beginning of a comment),
* increment the pointer till you reach end of line.
*
* Parameters:
* cp_address the address of the string pointer.
*
* Return Value:
* True if the pointer was changed.
*
*/
static Boolean
pskip_comment(wchar_t **cp_address)
{
wchar_t *cp = *cp_address;
/* Is this the beginning of a comment? Skip till end of line. */
if (*cp == '#') {
SKIPTOEND(cp);
}
/* Have we skipped a comment line? */
if (cp != *cp_address) {
*cp_address = cp;
return(true);
} else {
return(false);
}
}
static int
get_max(wchar_t **ms_address, wchar_t *hostname)
{
wchar_t *ms = *ms_address;
int limit = PMAKE_DEF_MAX_JOBS; /* Default setting. */
WCSTOMBS(mbs_buffer, hostname);
/* Look for `='. */
SKIPSPACE(ms);
if ((!*ms) || (*ms == '\n') || (*ms != '=')) {
SKIPTOEND(ms);
warning(gettext("expected `=' after max, ignoring rest of line for host %s"),
mbs_buffer);
*ms_address = ms;
return((int) limit);
} else {
ms++;
SKIPSPACE(ms);
if ((*ms != '\n') && (*ms != '\0')) {
/* We've found, hopefully, a valid "max" value. */
limit = (int) wcstol(ms, &ms, 10);
if (limit < 1) {
limit = PMAKE_DEF_MAX_JOBS;
warning(gettext("max value cannot be less than or equal to zero for host %s"), mbs_buffer);
}
} else {
/* No "max" value after "max=". */
warning(gettext("no max value specified for host %s"), mbs_buffer);
}
*ms_address = ms;
return(limit);
}
}

2148
bin/read.cc Normal file

File diff suppressed because it is too large Load diff

1898
bin/read2.cc Normal file

File diff suppressed because it is too large Load diff

394
bin/rep.cc Normal file
View file

@ -0,0 +1,394 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* rep.c
*
* This file handles the .nse_depinfo file
*/
/*
* Included files
*/
#include <mk/defs.h>
#include <mksh/misc.h> /* retmem() */
#include <vroot/report.h> /* NSE_DEPINFO */
/*
* Static variables
*/
static Recursive_make recursive_list;
static Recursive_make *bpatch = &recursive_list;
static Boolean changed;
/*
* File table of contents
*/
/*
* report_recursive_init()
*
* Read the .nse_depinfo file and make a list of all the
* .RECURSIVE entries.
*
* Parameters:
*
* Static variables used:
* bpatch Points to slot where next cell should be added
*
* Global variables used:
* recursive_name The Name ".RECURSIVE", compared against
*/
void
report_recursive_init(void)
{
char *search_dir;
char nse_depinfo[MAXPATHLEN];
FILE *fp;
int line_size, line_index;
wchar_t *line;
wchar_t *bigger_line;
wchar_t *colon;
wchar_t *dollar;
Recursive_make rp;
/*
* This routine can be called more than once, don't do
* anything after the first time.
*/
if (depinfo_already_read) {
return;
} else {
depinfo_already_read = true;
}
search_dir = getenv("NSE_DEP");
if (search_dir == NULL) {
return;
}
(void) sprintf(nse_depinfo, "%s/%s", search_dir, NSE_DEPINFO);
fp = fopen(nse_depinfo, "r");
if (fp == NULL) {
return;
}
line_size = MAXPATHLEN;
line_index = line_size - 1;
line = ALLOC_WC(line_size);
Wstring rns(recursive_name);
wchar_t * wcb = rns.get_string();
while (fgetws(line, line_size, fp) != NULL) {
while (wcslen(line) == line_index) {
if (line[wcslen(line) - 1] == '\n') {
continue;
}
bigger_line = ALLOC_WC(2 * line_size);
wcscpy(bigger_line, line);
retmem(line);
line = bigger_line;
if (fgetws(&line[line_index], line_size, fp) == NULL)
continue;
line_index = 2 * line_index;
line_size = 2 * line_size;
}
colon = (wchar_t *) wcschr(line, (int) colon_char);
if (colon == NULL) {
continue;
}
dollar = (wchar_t *) wcschr(line, (int) dollar_char);
line[wcslen(line) - 1] = (int) nul_char;
if (IS_WEQUALN(&colon[2], wcb,
(int) recursive_name->hash.length)) {
/*
* If this entry is an old entry, ignore it
*/
MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
if (dollar == NULL ||
!IS_WEQUALN(wcs_buffer, (dollar+1) - VER_LEN, VER_LEN)){
continue;
}
rp = ALLOC(Recursive_make);
(void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
/*
* set conditional_macro_string if string is present
*/
rp->oldline = (wchar_t *) wcsdup(line);
if ( dollar != NULL ){
rp->cond_macrostring =
(wchar_t *) wcsdup(dollar - VER_LEN + 1);
}
/*
* get target name into recursive struct
*/
*colon = (int) nul_char;
rp->target = (wchar_t *) wcsdup(line);
*bpatch = rp;
bpatch = &rp->next;
}
}
(void) fclose(fp);
}
/*
* report_recursive_dep(target, line)
*
* Report a target as recursive.
*
* Parameters:
* line Dependency line reported
*
* Static variables used:
* bpatch Points to slot where next cell should be added
* changed Written if report set changed
*/
void
report_recursive_dep(Name target, wchar_t *line)
{
Recursive_make rp;
wchar_t rec_buf[STRING_BUFFER_LENGTH];
String_rec string;
INIT_STRING_FROM_STACK(string, rec_buf);
cond_macros_into_string(target, &string);
/*
* find an applicable recursive entry, if there isn't one, create it
*/
rp = find_recursive_target(target);
if (rp == NULL) {
rp = ALLOC(Recursive_make);
(void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
wchar_t * wcb = get_wstring(target->string_mb); // XXX Tolik: needs retmem
rp->target = wcb;
rp->newline = (wchar_t *) wcsdup(line);
rp->cond_macrostring = (wchar_t *) wcsdup(rec_buf);
*bpatch = rp;
bpatch = &rp->next;
changed = true;
} else {
if ((rp->oldline != NULL) && !IS_WEQUAL(rp->oldline, line)) {
rp->newline = (wchar_t *) wcsdup(line);
changed = true;
}
rp->removed = false;
}
}
/*
* find_recursive_target(target)
*
* Search the list for a given target.
*
* Return value:
* The target cell
*
* Parameters:
* target The target we need
* top_level_target more info used to determinde the
* target we need
*
* Static variables used:
* recursive_list The list of targets
*/
Recursive_make
find_recursive_target(Name target)
{
Recursive_make rp;
String_rec string;
wchar_t rec_buf[STRING_BUFFER_LENGTH];
INIT_STRING_FROM_STACK(string, rec_buf);
cond_macros_into_string(target, &string);
Wstring tstr(target);
wchar_t * wcb = tstr.get_string();
for (rp = recursive_list; rp != NULL; rp = rp->next) {
/*
* If this entry has already been removed, ignore it.
*/
if (rp->removed)
continue;
/*
* If this target, and the target on the list are the same
* and if one of them contains conditional macro info, while
* the other doesn't, remove this entry from the list of
* recursive entries. This can only happen if the Makefile
* has changed to no longer contain conditional macros.
*/
if (IS_WEQUAL(rp->target, wcb)) {
if (rp->cond_macrostring[VER_LEN] == '\0' &&
string.buffer.start[VER_LEN] != '\0'){
rp->removed = true;
continue;
} else if (rp->cond_macrostring[VER_LEN] != '\0' &&
string.buffer.start[VER_LEN] == '\0'){
rp->removed = true;
continue;
}
}
/*
* If this is not a VERS2 entry, only need to match
* the target name. toptarg information from VERS1 entries
* are ignored.
*/
MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
if (IS_WEQUALN(wcs_buffer, string.buffer.start, VER_LEN)) {
if (IS_WEQUAL(rp->cond_macrostring,
string.buffer.start) &&
IS_WEQUAL(rp->target, wcb)) {
return rp;
}
} else {
if (IS_WEQUAL(rp->target, wcb)) {
return rp;
}
}
}
return NULL;
}
/*
* remove_recursive_dep(target, top_level_target)
*
* Mark a target as no longer recursive.
*
* Parameters:
* target The target we want to remove
* top_level_target target we want to remove must be built from
* the same top level target
*
* Static variables used:
* changed Written if report set changed
*/
void
remove_recursive_dep(Name target)
{
Recursive_make rp;
rp = find_recursive_target(target);
if ( rp != NULL ) {
rp->removed = true;
changed = true;
if(rp->target) {
retmem(rp->target);
rp->target = NULL;
}
if(rp->newline) {
retmem(rp->newline);
rp->newline = NULL;
}
if(rp->oldline) {
retmem(rp->oldline);
rp->oldline = NULL;
}
if(rp->cond_macrostring) {
retmem(rp->cond_macrostring);
rp->cond_macrostring = NULL;
}
}
}
/* gather_recursive_deps()
*
* Create or update list of recursive targets.
*/
void
gather_recursive_deps(void)
{
Name_set::iterator np, e;
String_rec rec;
wchar_t rec_buf[STRING_BUFFER_LENGTH];
register Property lines;
Boolean has_recursive;
Dependency dp;
report_recursive_init();
/* Go thru all targets and dump recursive dependencies */
for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
if (np->has_recursive_dependency){
has_recursive = false;
/*
* start .RECURSIVE line with target:
*/
INIT_STRING_FROM_STACK(rec, rec_buf);
APPEND_NAME(np, &rec, FIND_LENGTH);
append_char((int) colon_char, &rec);
append_char((int) space_char, &rec);
for (lines = get_prop(np->prop,recursive_prop);
lines != NULL;
lines = get_prop(lines->next, recursive_prop)) {
/*
* if entry is already in depinfo
* file or entry was not built, ignore it
*/
if (lines->body.recursive.in_depinfo)
continue;
if (!lines->body.recursive.has_built)
continue;
has_recursive = true;
lines->body.recursive.in_depinfo=true;
/*
* Write the remainder of the
* .RECURSIVE line
*/
APPEND_NAME(recursive_name, &rec,
FIND_LENGTH);
append_char((int) space_char, &rec);
APPEND_NAME(lines->body.recursive.directory,
&rec, FIND_LENGTH);
append_char((int) space_char, &rec);
APPEND_NAME(lines->body.recursive.target,
&rec, FIND_LENGTH);
append_char((int) space_char, &rec);
/* Complete list of makefiles used */
for (dp = lines->body.recursive.makefiles;
dp != NULL;
dp = dp->next) {
APPEND_NAME(dp->name, &rec, FIND_LENGTH);
append_char((int) space_char, &rec);
}
}
/*
* dump list of conditional targets,
* and report recursive entry, if needed
*/
cond_macros_into_string(np, &rec);
if (has_recursive){
report_recursive_dep(np, rec.buffer.start);
}
} else if ( np->has_built ) {
remove_recursive_dep(np);
}
}
}

444
bin/state.cc Normal file
View file

@ -0,0 +1,444 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* state.c
*
* This file contains the routines that write the .make.state file
*/
/*
* Included files
*/
#include <mk/defs.h>
#include <mksh/misc.h> /* errmsg() */
#include <setjmp.h> /* setjmp() */
#include <unistd.h> /* getpid() */
#include <errno.h> /* errno */
#include <locale.h> /* MB_CUR_MAX */
/*
* Defined macros
*/
#define LONGJUMP_VALUE 17
#define XFWRITE(string, length, fd) {if (fwrite(string, 1, length, fd) == 0) \
longjmp(long_jump, LONGJUMP_VALUE);}
#define XPUTC(ch, fd) { \
if (putc((int) ch, fd) == EOF) \
longjmp(long_jump, LONGJUMP_VALUE); \
}
#define XFPUTS(string, fd) fputs(string, fd)
/*
* typedefs & structs
*/
/*
* Static variables
*/
/*
* File table of contents
*/
static char * escape_target_name(Name np)
{
if(np->dollar) {
int len = strlen(np->string_mb);
char * buff = (char*)malloc(2 * len);
int pos = 0;
wchar_t wc;
int pp = 0;
while(pos < len) {
int n = mbtowc(&wc, np->string_mb + pos, MB_CUR_MAX);
if(n < 0) { // error - this shouldn't happen
(void)free(buff);
return strdup(np->string_mb);
}
if(wc == dollar_char) {
buff[pp] = '\\'; pp++;
buff[pp] = '$'; pp++;
} else {
for(int j=0;j<n;j++) {
buff[pp] = np->string_mb[pos+j]; pp++;
}
}
pos += n;
}
buff[pp] = '\0';
return buff;
} else {
return strdup(np->string_mb);
}
}
static void print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump);
/*
* write_state_file(report_recursive, exiting)
*
* Write a new version of .make.state
*
* Parameters:
* report_recursive Should only be done at end of run
* exiting true if called from the exit handler
*
* Global variables used:
* built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
* command_changed If no command changed we do not need to write
* current_make_version The Name "<current version>", written
* do_not_exec_rule If -n is on we do not write statefile
* hashtab The hashtable that contains all names
* keep_state If .KEEP_STATE is no on we do not write file
* make_state The Name ".make.state", used for opening file
* make_version The Name ".MAKE_VERSION", written
* recursive_name The Name ".RECURSIVE", written
* rewrite_statefile Indicates that something changed
*/
void
write_state_file(int, Boolean exiting)
{
register FILE *fd;
int lock_err;
char buffer[MAXPATHLEN];
char make_state_tempfile[MAXPATHLEN];
jmp_buf long_jump;
register int attempts = 0;
Name_set::iterator np, e;
register Property lines;
register int m;
Dependency dependency;
register Boolean name_printed;
Boolean built_this_run = false;
char *target_name;
int line_length;
register Cmd_line cp;
if (!rewrite_statefile ||
!command_changed ||
!keep_state ||
do_not_exec_rule ||
(report_dependencies_level > 0)) {
return;
}
/* Lock the file for writing. */
make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(".lock") + 1);
(void) sprintf(make_state_lockfile,
"%s.lock",
make_state->string_mb);
if (lock_err = file_lock(make_state->string_mb,
make_state_lockfile,
(int *) &make_state_locked, 0)) {
retmem_mb(make_state_lockfile);
make_state_lockfile = NULL;
/*
* We need to make sure that we are not being
* called by the exit handler so we don't call
* it again.
*/
if (exiting) {
(void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid());
report_pwd = true;
warning(gettext("Writing to %s"), buffer);
int fdes = mkstemp(buffer);
if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
fprintf(stderr,
gettext("Could not open statefile `%s': %s"),
buffer,
errmsg(errno));
return;
}
} else {
report_pwd = true;
fatal(gettext("Can't lock .make.state"));
}
}
(void) sprintf(make_state_tempfile,
"%s.tmp",
make_state->string_mb);
/* Delete old temporary statefile (in case it exists) */
(void) unlink(make_state_tempfile);
if ((fd = fopen(make_state_tempfile, "w")) == NULL) {
lock_err = errno; /* Save it! unlink() can change errno */
(void) unlink(make_state_lockfile);
retmem_mb(make_state_lockfile);
make_state_lockfile = NULL;
make_state_locked = false;
fatal(gettext("Could not open temporary statefile `%s': %s"),
make_state_tempfile,
errmsg(lock_err));
}
/*
* Set a trap for failed writes. If a write fails, the routine
* will try saving the .make.state file under another name in /tmp.
*/
if (setjmp(long_jump)) {
(void) fclose(fd);
if (attempts++ > 5) {
if ((make_state_lockfile != NULL) &&
make_state_locked) {
(void) unlink(make_state_lockfile);
retmem_mb(make_state_lockfile);
make_state_lockfile = NULL;
make_state_locked = false;
}
fatal(gettext("Giving up on writing statefile"));
}
sleep(10);
(void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid());
int fdes = mkstemp(buffer);
if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
fatal(gettext("Could not open statefile `%s': %s"),
buffer,
errmsg(errno));
}
warning(gettext("Initial write of statefile failed. Trying again on %s"),
buffer);
}
/* Write the version stamp. */
XFWRITE(make_version->string_mb,
strlen(make_version->string_mb),
fd);
XPUTC(colon_char, fd);
XPUTC(tab_char, fd);
XFWRITE(current_make_version->string_mb,
strlen(current_make_version->string_mb),
fd);
XPUTC(newline_char, fd);
/*
* Go through all the targets, dump their dependencies and
* command used.
*/
for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
/*
* If the target has no command used nor dependencies,
* we can go to the next one.
*/
if ((lines = get_prop(np->prop, line_prop)) == NULL) {
continue;
}
/* If this target is a special target, don't print. */
if (np->special_reader != no_special) {
continue;
}
/*
* Find out if any of the targets dependencies should
* be written to .make.state.
*/
for (m = 0, dependency = lines->body.line.dependencies;
dependency != NULL;
dependency = dependency->next) {
if (m = !dependency->stale
&& (dependency->name != force)
#ifndef PRINT_EXPLICIT_DEPEN
&& dependency->automatic
#endif
) {
break;
}
}
/* Only print if dependencies listed. */
if (m || (lines->body.line.command_used != NULL)) {
name_printed = false;
/*
* If this target was built during this make run,
* we mark it.
*/
built_this_run = false;
if (np->has_built) {
built_this_run = true;
XFWRITE(built_last_make_run->string_mb,
strlen(built_last_make_run->string_mb),
fd);
XPUTC(colon_char, fd);
XPUTC(newline_char, fd);
}
/* If the target has dependencies, we dump them. */
target_name = escape_target_name(np);
if (np->has_long_member_name) {
target_name =
get_prop(np->prop, long_member_name_prop)
->body.long_member_name.member_name->
string_mb;
}
if (m) {
XFPUTS(target_name, fd);
XPUTC(colon_char, fd);
XFPUTS("\t", fd);
name_printed = true;
line_length = 0;
for (dependency =
lines->body.line.dependencies;
dependency != NULL;
dependency = dependency->next) {
print_auto_depes(dependency,
fd,
built_this_run,
&line_length,
target_name,
long_jump);
}
XFPUTS("\n", fd);
}
/* If there is a command used, we dump it. */
if (lines->body.line.command_used != NULL) {
/*
* Only write the target name if it
* wasn't done for the dependencies.
*/
if (!name_printed) {
XFPUTS(target_name, fd);
XPUTC(colon_char, fd);
XPUTC(newline_char, fd);
}
/*
* Write the command lines.
* Prefix each textual line with a tab.
*/
for (cp = lines->body.line.command_used;
cp != NULL;
cp = cp->next) {
char *csp;
int n;
XPUTC(tab_char, fd);
if (cp->command_line != NULL) {
for (csp = cp->
command_line->
string_mb,
n = strlen(cp->
command_line->
string_mb);
n > 0;
n--, csp++) {
XPUTC(*csp, fd);
if (*csp ==
(int) newline_char) {
XPUTC(tab_char,
fd);
}
}
}
XPUTC(newline_char, fd);
}
}
(void)free(target_name);
}
}
if (fclose(fd) == EOF) {
longjmp(long_jump, LONGJUMP_VALUE);
}
if (attempts == 0) {
if (unlink(make_state->string_mb) != 0 && errno != ENOENT) {
lock_err = errno; /* Save it! unlink() can change errno */
/* Delete temporary statefile */
(void) unlink(make_state_tempfile);
(void) unlink(make_state_lockfile);
retmem_mb(make_state_lockfile);
make_state_lockfile = NULL;
make_state_locked = false;
fatal(gettext("Could not delete old statefile `%s': %s"),
make_state->string_mb,
errmsg(lock_err));
}
if (rename(make_state_tempfile, make_state->string_mb) != 0) {
lock_err = errno; /* Save it! unlink() can change errno */
/* Delete temporary statefile */
(void) unlink(make_state_tempfile);
(void) unlink(make_state_lockfile);
retmem_mb(make_state_lockfile);
make_state_lockfile = NULL;
make_state_locked = false;
fatal(gettext("Could not rename `%s' to `%s': %s"),
make_state_tempfile,
make_state->string_mb,
errmsg(lock_err));
}
}
if ((make_state_lockfile != NULL) && make_state_locked) {
(void) unlink(make_state_lockfile);
retmem_mb(make_state_lockfile);
make_state_lockfile = NULL;
make_state_locked = false;
}
}
/*
* print_auto_depes(dependency, fd, built_this_run,
* line_length, target_name, long_jump)
*
* Will print a dependency list for automatic entries.
*
* Parameters:
* dependency The dependency to print
* fd The file to print it to
* built_this_run If on we prefix each line with .BUILT_THIS...
* line_length Pointer to line length var that we update
* target_name We need this when we restart line
* long_jump setjmp/longjmp buffer used for IO error action
*
* Global variables used:
* built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
* force The Name " FORCE", compared against
*/
static void
print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump)
{
if (!dependency->automatic ||
dependency->stale ||
(dependency->name == force)) {
return;
}
XFWRITE(dependency->name->string_mb,
strlen(dependency->name->string_mb),
fd);
/*
* Check if the dependency line is too long.
* If so, break it and start a new one.
*/
if ((*line_length += (int) strlen(dependency->name->string_mb) + 1) > 450) {
*line_length = 0;
XPUTC(newline_char, fd);
if (built_this_run) {
XFPUTS(built_last_make_run->string_mb, fd);
XPUTC(colon_char, fd);
XPUTC(newline_char, fd);
}
XFPUTS(target_name, fd);
XPUTC(colon_char, fd);
XPUTC(tab_char, fd);
} else {
XFPUTS(" ", fd);
}
return;
}

241
bin/svr4.make.rules.file Normal file
View file

@ -0,0 +1,241 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 1994 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
.SUFFIXES: .o .c .c~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~ .f .f~ \
.C .C~ .Y .Y~ .L .L~
MAKE=make
BUILD=build
AR=ar
ARFLAGS=rv
AS=as
ASFLAGS=
CC=cc
CFLAGS=-O
F77=f77
FFLAGS=-O
GET=get
GFLAGS=
LD=ld
LDFLAGS=
LEX=lex
LFLAGS=
YACC=yacc
YFLAGS=
C++C=CC
C++FLAGS=-O
.c:
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
.c~:
$(GET) $(GFLAGS) $<
$(CC) $(CFLAGS) $*.c -o $@ $(LDFLAGS)
-rm -f $*.c
.f:
$(F77) $(FFLAGS) $< -o $@ $(LDFLAGS)
.f~:
$(GET) $(GFLAGS) $<
$(F77) $(FFLAGS) $*.f -o $@ $(LDFLAGS)
-rm -f $*.f
.s:
$(AS) $(ASFLAGS) $< -o $@ $(LDFLAGS)
.s~:
$(GET) $(GFLAGS) $<
$(AS) $(ASFLAGS) $*.s -o $* $(LDFLAGS)
-rm -f $*.s
.sh:
cp $< $@; chmod 0777 $@
.sh~:
$(GET) $(GFLAGS) $<
cp $*.sh $*; chmod 0777 $@
-rm -f $*.sh
.C:
$(C++C) $(C++FLAGS) $< -o $@ $(LDFLAGS)
.C~:
$(GET) $(GFLAGS) $<
$(C++C) $(C++FLAGS) $*.C -o $@ $(LDFLAGS)
-rm -f $*.C
.c.a:
$(CC) $(CFLAGS) -c $<
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.o
.c.o:
$(CC) $(CFLAGS) -c $<
.c~.a:
$(GET) $(GFLAGS) $<
$(CC) $(CFLAGS) -c $*.c
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.[co]
.c~.c:
$(GET) $(GFLAGS) $<
.c~.o:
$(GET) $(GFLAGS) $<
$(CC) $(CFLAGS) -c $*.c
-rm -f $*.c
.f.a:
$(F77) $(FFLAGS) -c $*.f
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.o
.f.o:
$(F77) $(FFLAGS) -c $*.f
.f~.a:
$(GET) $(GFLAGS) $<
$(F77) $(FFLAGS) -c $*.f
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.[fo]
.f~.f:
$(GET) $(GFLAGS) $<
.f~.o:
$(GET) $(GFLAGS) $<
$(F77) $(FFLAGS) -c $*.f
-rm -f $*.f
.h~.h:
$(GET) $(GFLAGS) $<
.l.c:
$(LEX) $(LFLAGS) $<
mv lex.yy.c $@
.l.o:
$(LEX) $(LFLAGS) $<
$(CC) $(CFLAGS) -c lex.yy.c
-rm lex.yy.c; mv lex.yy.o $@
.l~.c:
$(GET) $(GFLAGS) $<
$(LEX) $(LFLAGS) $*.l
mv lex.yy.c $@
-rm -f $*.l
.l~.l:
$(GET) $(GFLAGS) $<
.l~.o:
$(GET) $(GFLAGS) $<
$(LEX) $(LFLAGS) $*.l
$(CC) $(CFLAGS) -c lex.yy.c
-rm -f lex.yy.c $*.l
mv lex.yy.o $@
.s.a:
$(AS) $(ASFLAGS) -o $*.o $*.s
$(AR) $(ARFLAGS) $@ $*.o
.s.o:
$(AS) $(ASFLAGS) -o $@ $<
.s~.a:
$(GET) $(GFLAGS) $<
$(AS) $(ASFLAGS) -o $*.o $*.s
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.[so]
.s~.o:
$(GET) $(GFLAGS) $<
$(AS) $(ASFLAGS) -o $*.o $*.s
-rm -f $*.s
.s~.s:
$(GET) $(GFLAGS) $<
.sh~.sh:
$(GET) $(GFLAGS) $<
.y.c:
$(YACC) $(YFLAGS) $<
mv y.tab.c $@
.y.o:
$(YACC) $(YFLAGS) $<
$(CC) $(CFLAGS) -c y.tab.c
-rm y.tab.c
mv y.tab.o $@
.y~.c:
$(GET) $(GFLAGS) $<
$(YACC) $(YFLAGS) $*.y
mv y.tab.c $*.c
-rm -f $*.y
.y~.o:
$(GET) $(GFLAGS) $<
$(YACC) $(YFLAGS) $*.y
$(CC) $(CFLAGS) -c y.tab.c
-rm -f y.tab.c $*.y
mv y.tab.o $*.o
.y~.y :
$(GET) $(GFLAGS) $<
.C.a:
$(C++C) $(C++FLAGS) -c $<
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.o
.C.o:
$(C++C) $(C++FLAGS) -c $<
.C~.a:
$(GET) $(GFLAGS) $<
$(C++C) $(C++FLAGS) -c $*.C
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.[Co]
.C~.C:
$(GET) $(GFLAGS) $<
.C~.o:
$(GET) $(GFLAGS) $<
$(C++C) $(C++FLAGS) -c $*.C
-rm -f $*.C
.L.C:
$(LEX) $(LFLAGS) $<
mv lex.yy.c $@
.L.o:
$(LEX) $(LFLAGS) $<
$(C++C) $(C++FLAGS) -c lex.yy.c
-rm lex.yy.c; mv lex.yy.o $@
.L~.C:
$(GET) $(GFLAGS) $<
$(LEX) $(LFLAGS) $*.L
mv lex.yy.c $@
-rm -f $*.L
.L~.L:
$(GET) $(GFLAGS) $<
.L~.o:
$(GET) $(GFLAGS) $<
$(LEX) $(LFLAGS) $*.L
$(C++C) $(C++FLAGS) -c lex.yy.c
-rm -f lex.yy.c $*.L
mv lex.yy.c $@
.Y.C:
$(YACC) $(YFLAGS) $<
mv y.tab.c $@
.Y.o:
$(YACC) $(YFLAGS) $<
$(C++C) $(C++FLAGS) -c y.tab.c
-rm y.tab.c
mv y.tab.o $@
.Y~.C:
$(GET) $(GFLAGS) $<
$(YACC) $(YFLAGS) $*.Y
mv y.tab.c $*.C
-rm -f $*.Y
.Y~.o:
$(GET) $(GFLAGS) $<
$(YACC) $(YFLAGS) $*.Y
$(C++C) $(C++FLAGS) -c y.tab.c
-rm -f y.tab.c $*.Y
mv y.tab.o $*.o
.Y~.Y :
$(GET) $(GFLAGS) $<
markfile.o: markfile
echo "static char _sccsid[] = \"`grep @'(#)' markfile`\";" > markfile.c
$(CC) -c markfile.c
-rm -f markfile.c
.SCCS_GET:
$(GET) $(GFLAGS) s.$@

47
include/bsd/bsd.h Normal file
View file

@ -0,0 +1,47 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* bsd/bsd.h: Interface definitions to BSD compatibility functions for SVR4.
*/
#ifndef _BSD_BSD_H
#define _BSD_BSD_H
#include <signal.h>
#ifndef __cplusplus
typedef void (*SIG_PF) (int);
#endif
#ifdef __cplusplus
extern "C" SIG_PF bsd_signal(int a, SIG_PF b);
#else
extern void (*bsd_signal(int, void (*) (int))) (int);
#endif
extern void bsd_signals(void);
#endif

396
include/mk/defs.h Normal file
View file

@ -0,0 +1,396 @@
#ifndef _MK_DEFS_H
#define _MK_DEFS_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Included files
*/
#include <mksh/defs.h>
/*
* Defined macros
*/
#define SKIPSPACE(x) while (*x && \
((*x == (int) space_char) || \
(*x == (int) tab_char) || \
(*x == (int) comma_char))) { \
x++; \
}
#define SKIPWORD(x) while (*x && \
(*x != (int) space_char) && \
(*x != (int) tab_char) && \
(*x != (int) newline_char) && \
(*x != (int) comma_char) && \
(*x != (int) equal_char)) { \
x++; \
}
#define SKIPTOEND(x) while (*x && \
(*x != (int) newline_char)) { \
x++; \
}
#define PMAKE_DEF_MAX_JOBS 2 /* Default number of parallel jobs. */
#define OUT_OF_DATE(a,b) \
(((a) < (b)) || (((a) == file_doesnt_exist) && ((b) == file_doesnt_exist)))
#define OUT_OF_DATE_SEC(a,b) \
(((a).tv_sec < (b).tv_sec) || (((a).tv_sec == file_doesnt_exist.tv_sec) && ((b).tv_sec == file_doesnt_exist.tv_sec)))
#define SETVAR(name, value, append) \
setvar_daemon(name, value, append, no_daemon, \
true, debug_level)
#define MAX(a,b) (((a)>(b))?(a):(b))
/*
* New feature added to SUN5_0 make, invoke the vanilla svr4 make when
* the USE_SVR4_MAKE environment variable is set.
*/
#define SVR4_MAKE "/usr/ccs/lib/svr4.make"
#define USE_SVR4_MAKE "USE_SVR4_MAKE"
/*
* The standard MAXHOSTNAMELEN is 64. We want 32.
*/
#define MAX_HOSTNAMELEN 32
/*
* typedefs & structs
*/
typedef enum {
no_state,
scan_name_state,
scan_command_state,
enter_dependencies_state,
enter_conditional_state,
enter_equal_state,
illegal_bytes_state,
illegal_eoln_state,
poorly_formed_macro_state,
exit_state
} Reader_state;
struct _Name_vector {
struct _Name *names[64];
struct _Chain *target_group[64];
short used;
struct _Name_vector *next;
};
struct _Running {
struct _Running *next;
Doname state;
struct _Name *target;
struct _Name *true_target;
struct _Property *command;
struct _Name *sprodep_value;
char *sprodep_env;
int recursion_level;
Boolean do_get;
Boolean implicit;
Boolean redo;
int auto_count;
struct _Name **automatics;
pid_t pid;
int job_msg_id;
char *stdout_file;
char *stderr_file;
struct _Name *temp_file;
int conditional_cnt;
struct _Name **conditional_targets;
Boolean make_refd;
};
typedef enum {
serial_mode,
parallel_mode
} DMake_mode;
typedef enum {
txt1_mode,
txt2_mode,
html1_mode
} DMake_output_mode;
struct _Recursive_make {
struct _Recursive_make *next; /* Linked list */
wchar_t *target;/* Name of target */
wchar_t *oldline;/* Original line in .nse_depinfo */
wchar_t *newline;/* New line in .nse_depinfo */
wchar_t *cond_macrostring;
/* string built from value of
* conditional macros used by
* this target
*/
Boolean removed;/* This target is no longer recursive*/
};
struct _Dyntarget {
struct _Dyntarget *next;
struct _Name *name;
};
/*
* Typedefs for all structs
*/
typedef struct _Cmd_line *Cmd_line, Cmd_line_rec;
typedef struct _Dependency *Dependency, Dependency_rec;
typedef struct _Macro *Macro, Macro_rec;
typedef struct _Name_vector *Name_vector, Name_vector_rec;
typedef struct _Percent *Percent, Percent_rec;
typedef struct _Dyntarget *Dyntarget;
typedef struct _Recursive_make *Recursive_make, Recursive_make_rec;
typedef struct _Running *Running, Running_rec;
/*
* extern declarations for all global variables.
* The actual declarations are in globals.cc
*/
extern Boolean allrules_read;
extern Name posix_name;
extern Name svr4_name;
extern Boolean sdot_target;
extern Boolean all_parallel;
extern Boolean assign_done;
extern Boolean build_failed_seen;
extern Name built_last_make_run;
extern Name c_at;
extern Boolean command_changed;
extern Boolean commands_done;
extern Chain conditional_targets;
extern Name conditionals;
extern Boolean continue_after_error;
extern Property current_line;
extern Name current_make_version;
extern Name current_target;
extern short debug_level;
extern Cmd_line default_rule;
extern Name default_rule_name;
extern Name default_target_to_build;
extern Boolean depinfo_already_read;
extern Name dmake_group;
extern Name dmake_max_jobs;
extern Name dmake_mode;
extern DMake_mode dmake_mode_type;
extern Name dmake_output_mode;
extern DMake_output_mode output_mode;
extern Name dmake_odir;
extern Name dmake_rcfile;
extern Name done;
extern Name dot;
extern Name dot_keep_state;
extern Name dot_keep_state_file;
extern Name empty_name;
extern Boolean fatal_in_progress;
extern int file_number;
extern Name force;
extern Name ignore_name;
extern Boolean ignore_errors;
extern Boolean ignore_errors_all;
extern Name init;
extern int job_msg_id;
extern Boolean keep_state;
extern Name make_state;
extern timestruc_t make_state_before;
extern Boolean make_state_locked;
extern Dependency makefiles_used;
extern Name makeflags;
extern Name make_version;
extern char mbs_buffer2[];
extern char *mbs_ptr;
extern char *mbs_ptr2;
extern Boolean no_action_was_taken;
extern Boolean no_parallel;
extern Name no_parallel_name;
extern Name not_auto;
extern Boolean only_parallel;
extern Boolean parallel;
extern Name parallel_name;
extern Name localhost_name;
extern int parallel_process_cnt;
extern Percent percent_list;
extern Dyntarget dyntarget_list;
extern Name plus;
extern Name pmake_machinesfile;
extern Name precious;
extern Name primary_makefile;
extern Boolean quest;
extern short read_trace_level;
extern Boolean reading_dependencies;
extern int recursion_level;
extern Name recursive_name;
extern short report_dependencies_level;
extern Boolean report_pwd;
extern Boolean rewrite_statefile;
extern Running running_list;
extern char *sccs_dir_path;
extern Name sccs_get_name;
extern Name sccs_get_posix_name;
extern Cmd_line sccs_get_rule;
extern Cmd_line sccs_get_org_rule;
extern Cmd_line sccs_get_posix_rule;
extern Name get_name;
extern Name get_posix_name;
extern Cmd_line get_rule;
extern Cmd_line get_posix_rule;
extern Boolean all_precious;
extern Boolean report_cwd;
extern Boolean silent_all;
extern Boolean silent;
extern Name silent_name;
extern char *stderr_file;
extern char *stdout_file;
extern Boolean stdout_stderr_same;
extern Dependency suffixes;
extern Name suffixes_name;
extern Name sunpro_dependencies;
extern Boolean target_variants;
extern const char *tmpdir;
extern const char *temp_file_directory;
extern Name temp_file_name;
extern short temp_file_number;
extern wchar_t *top_level_target;
extern Boolean touch;
extern Boolean trace_reader;
extern Boolean build_unconditional;
extern pathpt vroot_path;
extern Name wait_name;
extern wchar_t wcs_buffer2[];
extern wchar_t *wcs_ptr;
extern wchar_t *wcs_ptr2;
extern long int hostid;
/*
* Declarations of system defined variables
*/
/* On linux this variable is defined in 'signal.h' */
extern char *sys_siglist[];
/*
* Declarations of system supplied functions
*/
extern int file_lock(char *, char *, int *, int);
/*
* Declarations of functions declared and used by make
*/
extern void add_pending(Name target, int recursion_level, Boolean do_get, Boolean implicit, Boolean redo);
extern void add_running(Name target, Name true_target, Property command, int recursion_level, int auto_count, Name *automatics, Boolean do_get, Boolean implicit);
extern void add_serial(Name target, int recursion_level, Boolean do_get, Boolean implicit);
extern void add_subtree(Name target, int recursion_level, Boolean do_get, Boolean implicit);
extern void append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro);
extern void await_parallel(Boolean waitflg);
extern void build_suffix_list(Name target_suffix);
extern Boolean check_auto_dependencies(Name target, int auto_count, Name *automatics);
extern void check_state(Name temp_file_name);
extern void cond_macros_into_string(Name np, String_rec *buffer);
extern void construct_target_string();
extern void create_xdrs_ptr(void);
extern void depvar_add_to_list (Name name, Boolean cmdline);
extern Doname doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic = false);
extern Doname doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
extern Doname doname_parallel(Name target, Boolean do_get, Boolean implicit);
extern Doname dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target);
extern void dump_make_state(void);
extern void dump_target_list(void);
extern void enter_conditional(register Name target, Name name, Name value, register Boolean append);
extern void enter_dependencies(register Name target, Chain target_group, register Name_vector depes, register Cmd_line command, register Separator separator);
extern void enter_dependency(Property line, register Name depe, Boolean automatic);
extern void enter_equal(Name name, Name value, register Boolean append);
extern Percent enter_percent(register Name target, Chain target_group, register Name_vector depes, Cmd_line command);
extern Dyntarget enter_dyntarget(register Name target);
extern Name_vector enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen);
extern Boolean exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error);
extern Doname execute_parallel(Property line, Boolean waitflg, Boolean local = false);
extern Doname execute_serial(Property line);
extern timestruc_t& exists(register Name target);
extern void fatal(const char *, ...);
extern void fatal_reader(char *, ...);
extern Doname find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking);
extern Doname find_double_suffix_rule(register Name target, Property *command, Boolean rechecking);
extern Doname find_percent_rule(register Name target, Property *command, Boolean rechecking);
extern int find_run_directory (char *cmd, char *cwd, char *dir, char **pgm, char **run, char *path);
extern Doname find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking);
extern Chain find_target_groups(register Name_vector target_list, register int i, Boolean reset);
extern void finish_children(Boolean docheck);
extern void finish_running(void);
extern void free_chain(Name_vector ptr);
extern void gather_recursive_deps(void);
extern char *get_current_path(void);
extern int get_job_msg_id(void);
extern wchar_t *getmem_wc(register int size);
/* On linux getwd(char *) is defined in 'unistd.h' */
#ifdef __cplusplus
extern "C" {
#endif
extern char *getwd(char *);
#ifdef __cplusplus
}
#endif
extern void handle_interrupt(int);
extern Boolean is_running(Name target);
extern void load_cached_names(void);
extern Boolean parallel_ok(Name target, Boolean line_prop_must_exists);
extern void print_dependencies(register Name target, register Property line);
extern void send_job_start_msg(Property line);
extern void send_rsrc_info_msg(int max_jobs, char *hostname, char *username);
extern void print_value(register Name value, Daemon daemon);
extern timestruc_t& read_archive(register Name target);
extern int read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library);
extern void read_directory_of_file(register Name file);
extern int read_make_machines(Name make_machines_name);
extern Boolean read_simple_file(register Name makefile_name, register Boolean chase_path, register Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile);
extern void remove_recursive_dep(Name target);
extern void report_recursive_dep(Name target, char *line);
extern void report_recursive_done(void);
extern void report_recursive_init(void);
extern Recursive_make find_recursive_target(Name target);
extern void reset_locals(register Name target, register Property old_locals, register Property conditional, register int index);
extern void set_locals(register Name target, register Property old_locals);
extern void setvar_append(register Name name, register Name value);
extern void setvar_envvar(void);
extern void special_reader(Name target, register Name_vector depes, Cmd_line command);
extern void startup_rxm();
extern Doname target_can_be_built(register Name target);
extern char *time_to_string(const timestruc_t &time);
extern void update_target(Property line, Doname result);
extern void warning(char *, ...);
extern void write_state_file(int report_recursive, Boolean exiting);
extern Name vpath_translation(register Name cmd);
extern char *make_install_prefix(void);
#define DEPINFO_FMT_VERSION "VERS2$"
#define VER_LEN strlen(DEPINFO_FMT_VERSION)
#endif

945
include/mksh/defs.h Normal file
View file

@ -0,0 +1,945 @@
#ifndef _MKSH_DEFS_H
#define _MKSH_DEFS_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <limits.h> /* MB_LEN_MAX */
#include <stdio.h>
#include <stdlib.h> /* wchar_t */
#include <string.h> /* strcmp() */
#include <sys/param.h> /* MAXPATHLEN */
#include <sys/types.h> /* time_t, caddr_t */
#include <vroot/vroot.h> /* pathpt */
#include <sys/time.h> /* timestruc_t */
#include <errno.h> /* errno */
#include <wctype.h>
/*
* A type and some utilities for boolean values
*/
#define false BOOLEAN_false
#define true BOOLEAN_true
typedef enum {
false = 0,
true = 1,
failed = 0,
succeeded = 1
} Boolean;
#define BOOLEAN(expr) ((expr) ? true : false)
/*
* Some random constants (in an enum so dbx knows their values)
*/
enum {
update_delay = 30, /* time between rstat checks */
ar_member_name_len = 1024,
hashsize = 2048 /* size of hash table */
};
/*
* Symbols that defines all the different char constants make uses
*/
enum {
ampersand_char = '&',
asterisk_char = '*',
at_char = '@',
backquote_char = '`',
backslash_char = '\\',
bar_char = '|',
braceleft_char = '{',
braceright_char = '}',
bracketleft_char = '[',
bracketright_char = ']',
colon_char = ':',
comma_char = ',',
dollar_char = '$',
doublequote_char = '"',
equal_char = '=',
exclam_char = '!',
greater_char = '>',
hat_char = '^',
hyphen_char = '-',
less_char = '<',
newline_char = '\n',
nul_char = '\0',
numbersign_char = '#',
parenleft_char = '(',
parenright_char = ')',
percent_char = '%',
period_char = '.',
plus_char = '+',
question_char = '?',
quote_char = '\'',
semicolon_char = ';',
slash_char = '/',
space_char = ' ',
tab_char = '\t',
tilde_char = '~'
};
/*
* For make i18n. Codeset independent.
* Setup character semantics by identifying all the special characters
* of make, and assigning each an entry in the char_semantics[] vector.
*/
enum {
ampersand_char_entry = 0, /* 0 */
asterisk_char_entry, /* 1 */
at_char_entry, /* 2 */
backquote_char_entry, /* 3 */
backslash_char_entry, /* 4 */
bar_char_entry, /* 5 */
bracketleft_char_entry, /* 6 */
bracketright_char_entry, /* 7 */
colon_char_entry, /* 8 */
dollar_char_entry, /* 9 */
doublequote_char_entry, /* 10 */
equal_char_entry, /* 11 */
exclam_char_entry, /* 12 */
greater_char_entry, /* 13 */
hat_char_entry, /* 14 */
hyphen_char_entry, /* 15 */
less_char_entry, /* 16 */
newline_char_entry, /* 17 */
numbersign_char_entry, /* 18 */
parenleft_char_entry, /* 19 */
parenright_char_entry, /* 20 */
percent_char_entry, /* 21 */
plus_char_entry, /* 22 */
question_char_entry, /* 23 */
quote_char_entry, /* 24 */
semicolon_char_entry, /* 25 */
no_semantics_entry /* 26 */
};
/*
* CHAR_SEMANTICS_ENTRIES should be the number of entries above.
* The last entry in char_semantics[] should be blank.
*/
#define CHAR_SEMANTICS_ENTRIES 27
/*
#define CHAR_SEMANTICS_STRING "&*@`\\|[]:$=!>-\n#()%+?;^<'\""
*/
/*
* Some utility macros
*/
#define ALLOC(x) ((struct _##x *)getmem(sizeof (struct _##x)))
#define ALLOC_WC(x) ((wchar_t *)getmem((x) * SIZEOFWCHAR_T))
#define FIND_LENGTH -1
#define GETNAME(a,b) getname_fn((a), (b), false)
#define IS_EQUAL(a,b) (!strcmp((a), (b)))
#define IS_EQUALN(a,b,n) (!strncmp((a), (b), (n)))
#define IS_WEQUAL(a,b) (!wcscmp((a), (b)))
#define IS_WEQUALN(a,b,n) (!wcsncmp((a), (b), (n)))
#define MBLEN(a) mblen((a), MB_LEN_MAX)
#define MBSTOWCS(a,b) (void) mbstowcs_with_check((a), (b), MAXPATHLEN)
#define MBTOWC(a,b) mbtowc((a), (b), MB_LEN_MAX)
#define SIZEOFWCHAR_T (sizeof (wchar_t))
#define VSIZEOF(v) (sizeof (v) / sizeof ((v)[0]))
#define WCSTOMBS(a,b) (void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX))
#define WCTOMB(a,b) (void) wctomb((a), (b))
#define HASH(v, c) (v = (v)*31 + (unsigned int)(c))
extern void mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n);
/*
* Bits stored in funny vector to classify chars
*/
enum {
dollar_sem = 0001,
meta_sem = 0002,
percent_sem = 0004,
wildcard_sem = 0010,
command_prefix_sem = 0020,
special_macro_sem = 0040,
colon_sem = 0100,
parenleft_sem = 0200
};
/*
* Type returned from doname class functions
*/
typedef enum {
build_dont_know = 0,
build_failed,
build_ok,
build_in_progress,
build_running, /* PARALLEL & DISTRIBUTED */
build_pending, /* PARALLEL & DISTRIBUTED */
build_serial, /* PARALLEL & DISTRIBUTED */
build_subtree /* PARALLEL & DISTRIBUTED */
} Doname;
/*
* The String struct defines a string with the following layout
* "xxxxxxxxxxxxxxxCxxxxxxxxxxxxxxx________"
* ^ ^ ^ ^
* | | | |
* buffer.start text.p text.end buffer.end
* text.p points to the next char to read/write.
*/
struct _String {
struct Text {
wchar_t *p; /* Read/Write pointer */
wchar_t *end; /* Read limit pointer */
} text;
struct Physical_buffer {
wchar_t *start; /* Points to start of buffer */
wchar_t *end; /* End of physical buffer */
} buffer;
Boolean free_after_use:1;
};
#define STRING_BUFFER_LENGTH 1024
#define INIT_STRING_FROM_STACK(str, buf) { \
str.buffer.start = (buf); \
str.text.p = (buf); \
str.text.end = NULL; \
str.buffer.end = (buf) \
+ (sizeof (buf)/SIZEOFWCHAR_T); \
str.free_after_use = false; \
}
#define APPEND_NAME(np, dest, len) append_string((np)->string_mb, (dest), (len));
class Wstring {
public:
struct _String string;
wchar_t string_buf[STRING_BUFFER_LENGTH];
public:
Wstring();
Wstring(struct _Name * name);
~Wstring();
void init(struct _Name * name);
void init(wchar_t * name, unsigned length);
unsigned length() {
return wcslen(string.buffer.start);
};
void append_to_str(struct _String * str, unsigned off, unsigned length);
wchar_t * get_string() {
return string.buffer.start;
};
wchar_t * get_string(unsigned off) {
return string.buffer.start + off;
};
Boolean equaln(wchar_t * str, unsigned length);
Boolean equal(wchar_t * str);
Boolean equal(wchar_t * str, unsigned off);
Boolean equal(wchar_t * str, unsigned off, unsigned length);
Boolean equaln(Wstring * str, unsigned length);
Boolean equal(Wstring * str);
Boolean equal(Wstring * str, unsigned off);
Boolean equal(Wstring * str, unsigned off, unsigned length);
};
/*
* Used for storing the $? list and also for the "target + target:"
* construct.
*/
struct _Chain {
struct _Chain *next;
struct _Name *name;
struct _Percent *percent_member;
};
/*
* Stores one command line for a rule
*/
struct _Cmd_line {
struct _Cmd_line *next;
struct _Name *command_line;
Boolean make_refd:1; /* $(MAKE) referenced? */
/*
* Remember any command line prefixes given
*/
Boolean ignore_command_dependency:1; /* `?' */
Boolean assign:1; /* `=' */
Boolean ignore_error:1; /* `-' */
Boolean silent:1; /* `@' */
Boolean always_exec:1; /* `+' */
};
/*
* Linked list of targets/files
*/
struct _Dependency {
struct _Dependency *next;
struct _Name *name;
Boolean automatic:1;
Boolean stale:1;
Boolean built:1;
};
/*
* The specials are markers for targets that the reader should special case
*/
typedef enum {
no_special,
built_last_make_run_special,
default_special,
get_posix_special,
get_special,
ignore_special,
keep_state_file_special,
keep_state_special,
make_version_special,
no_parallel_special,
parallel_special,
posix_special,
precious_special,
sccs_get_posix_special,
sccs_get_special,
silent_special,
suffixes_special,
svr4_special,
localhost_special
} Special;
typedef enum {
no_colon,
one_colon,
two_colon,
equal_seen,
conditional_seen,
none_seen
} Separator;
/*
* Magic values for the timestamp stored with each name object
*/
extern const timestruc_t file_no_time;
extern const timestruc_t file_doesnt_exist;
extern const timestruc_t file_is_dir;
extern const timestruc_t file_min_time;
extern const timestruc_t file_max_time;
/*
* Each Name has a list of properties
* The properties are used to store information that only
* a subset of the Names need
*/
typedef enum {
no_prop,
conditional_prop,
line_prop,
macro_prop,
makefile_prop,
member_prop,
recursive_prop,
sccs_prop,
suffix_prop,
target_prop,
time_prop,
vpath_alias_prop,
long_member_name_prop,
macro_append_prop,
env_mem_prop
} Property_id;
typedef enum {
no_daemon = 0,
chain_daemon
} Daemon;
struct _Env_mem {
char *value;
};
struct _Macro_appendix {
struct _Name *value;
struct _Name *value_to_append;
};
struct _Macro {
/*
* For "ABC = xyz" constructs
* Name "ABC" get one macro prop
*/
struct _Name *value;
Boolean exported:1;
Boolean read_only:1;
/*
* This macro is defined conditionally
*/
Boolean is_conditional:1;
/*
* The list for $? is stored as a structured list that
* is translated into a string iff it is referenced.
* This is why some macro values need a daemon.
*/
Daemon daemon:2;
};
struct _Macro_list {
struct _Macro_list *next;
char *macro_name;
char *value;
};
enum sccs_stat {
DONT_KNOW_SCCS = 0,
NO_SCCS,
HAS_SCCS
};
struct _Name {
struct _Property *prop; /* List of properties */
char *string_mb; /* Multi-byte name string */
struct {
unsigned int length;
} hash;
struct {
timestruc_t time; /* Modification */
int stat_errno; /* error from "stat" */
off_t size; /* Of file */
mode_t mode; /* Of file */
Boolean is_file:1;
Boolean is_dir:1;
Boolean is_sym_link:1;
Boolean is_precious:1;
enum sccs_stat has_sccs:2;
} stat;
/*
* Count instances of :: definitions for this target
*/
short colon_splits;
/*
* We only clear the automatic depes once per target per report
*/
short temp_file_number;
/*
* Count how many conditional macros this target has defined
*/
short conditional_cnt;
/*
* A conditional macro was used when building this target
*/
Boolean depends_on_conditional:1;
/*
* Pointer to list of conditional macros which were used to build
* this target
*/
struct _Macro_list *conditional_macro_list;
Boolean has_member_depe:1;
Boolean is_member:1;
/*
* This target is a directory that has been read
*/
Boolean has_read_dir:1;
/*
* This name is a macro that is now being expanded
*/
Boolean being_expanded:1;
/*
* This name is a magic name that the reader must know about
*/
Special special_reader:5;
Doname state:3;
Separator colons:3;
Boolean has_depe_list_expanded:1;
Boolean suffix_scan_done:1;
Boolean has_complained:1; /* For sccs */
/*
* This target has been built during this make run
*/
Boolean ran_command:1;
Boolean with_squiggle:1; /* for .SUFFIXES */
Boolean without_squiggle:1; /* for .SUFFIXES */
Boolean has_read_suffixes:1; /* Suffix list cached*/
Boolean has_suffixes:1;
Boolean has_target_prop:1;
Boolean has_vpath_alias_prop:1;
Boolean dependency_printed:1; /* For dump_make_state() */
Boolean dollar:1; /* In namestring */
Boolean meta:1; /* In namestring */
Boolean percent:1; /* In namestring */
Boolean wildcard:1; /* In namestring */
Boolean has_parent:1;
Boolean is_target:1;
Boolean has_built:1;
Boolean colon:1; /* In namestring */
Boolean parenleft:1; /* In namestring */
Boolean has_recursive_dependency:1;
Boolean has_regular_dependency:1;
Boolean is_double_colon:1;
Boolean is_double_colon_parent:1;
Boolean has_long_member_name:1;
/*
* allowed to run in parallel
*/
Boolean parallel:1;
/*
* not allowed to run in parallel
*/
Boolean no_parallel:1;
/*
* used in dependency_conflict
*/
Boolean checking_subtree:1;
Boolean added_pattern_conditionals:1;
/*
* rechecking target for possible rebuild
*/
Boolean rechecking_target:1;
/*
* build this target in silent mode
*/
Boolean silent_mode:1;
/*
* build this target in ignore error mode
*/
Boolean ignore_error_mode:1;
Boolean dont_activate_cond_values:1;
/*
* allowed to run serially on local host
*/
Boolean localhost:1;
};
/*
* Stores the % matched default rules
*/
struct _Percent {
struct _Percent *next;
struct _Name **patterns;
struct _Name *name;
struct _Percent *dependencies;
struct _Cmd_line *command_template;
struct _Chain *target_group;
int patterns_total;
Boolean being_expanded;
};
struct Conditional {
/*
* For "foo := ABC [+]= xyz" constructs
* Name "foo" gets one conditional prop
*/
struct _Name *target;
struct _Name *name;
struct _Name *value;
int sequence;
Boolean append:1;
};
struct Line {
/*
* For "target : dependencies" constructs
* Name "target" gets one line prop
*/
struct _Cmd_line *command_template;
struct _Cmd_line *command_used;
struct _Dependency *dependencies;
timestruc_t dependency_time;
struct _Chain *target_group;
Boolean is_out_of_date:1;
Boolean sccs_command:1;
Boolean command_template_redefined:1;
Boolean dont_rebuild_command_used:1;
/*
* Values for the dynamic macros
*/
struct _Name *target;
struct _Name *star;
struct _Name *less;
struct _Name *percent;
struct _Chain *query;
};
struct Makefile {
/*
* Names that reference makefiles gets one prop
*/
wchar_t *contents;
off_t size;
};
struct Member {
/*
* For "lib(member)" and "lib((entry))" constructs
* Name "lib(member)" gets one member prop
* Name "lib((entry))" gets one member prop
* The member field is filled in when the prop is refd
*/
struct _Name *library;
struct _Name *entry;
struct _Name *member;
};
struct Recursive {
/*
* For "target: .RECURSIVE dir makefiles" constructs
* Used to keep track of recursive calls to make
* Name "target" gets one recursive prop
*/
struct _Name *directory;
struct _Name *target;
struct _Dependency *makefiles;
Boolean has_built;
Boolean in_depinfo;
};
struct Sccs {
/*
* Each file that has a SCCS s. file gets one prop
*/
struct _Name *file;
};
struct Suffix {
/*
* Cached list of suffixes that can build this target
* suffix is built from .SUFFIXES
*/
struct _Name *suffix;
struct _Cmd_line *command_template;
};
struct Target {
/*
* For "target:: dependencies" constructs
* The "::" construct is handled by converting it to
* "foo: 1@foo" + "1@foo: dependecies"
* "1@foo" gets one target prop
* This target prop cause $@ to be bound to "foo"
* not "1@foo" when the rule is evaluated
*/
struct _Name *target;
};
struct STime {
/*
* Save the original time for :: targets
*/
timestruc_t time;
};
struct Vpath_alias {
/*
* If a file was found using the VPATH it gets
* a vpath_alias prop
*/
struct _Name *alias;
};
struct Long_member_name {
/*
* Targets with a truncated member name carries
* the full lib(member) name for the state file
*/
struct _Name *member_name;
};
union Body {
struct _Macro macro;
struct Conditional conditional;
struct Line line;
struct Makefile makefile;
struct Member member;
struct Recursive recursive;
struct Sccs sccs;
struct Suffix suffix;
struct Target target;
struct STime time;
struct Vpath_alias vpath_alias;
struct Long_member_name long_member_name;
struct _Macro_appendix macro_appendix;
struct _Env_mem env_mem;
};
#define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body))
struct _Property {
struct _Property *next;
Property_id type:4;
union Body body;
};
/* Structure for dynamic "ascii" arrays */
struct ASCII_Dyn_Array {
char *start;
size_t size;
};
struct _Envvar {
struct _Name *name;
struct _Name *value;
struct _Envvar *next;
char *env_string;
Boolean already_put:1;
};
/*
* Macros for the reader
*/
#define GOTO_STATE(new_state) { \
SET_STATE(new_state); \
goto enter_state; \
}
#define SET_STATE(new_state) state = (new_state)
#define UNCACHE_SOURCE() if (source != NULL) { \
source->string.text.p = source_p; \
}
#define CACHE_SOURCE(comp) if (source != NULL) { \
source_p = source->string.text.p - \
(comp); \
source_end = source->string.text.end; \
}
#define GET_NEXT_BLOCK_NOCHK(source) { UNCACHE_SOURCE(); \
source = get_next_block_fn(source); \
CACHE_SOURCE(0) \
}
#define GET_NEXT_BLOCK(source) { GET_NEXT_BLOCK_NOCHK(source); \
if (source != NULL && source->error_converting) { \
GOTO_STATE(illegal_bytes_state); \
} \
}
#define GET_CHAR() ((source == NULL) || \
(source_p >= source_end) ? 0 : *source_p)
struct _Source {
struct _String string;
struct _Source *previous;
off_t bytes_left_in_file;
short fd;
Boolean already_expanded:1;
Boolean error_converting:1;
char *inp_buf;
char *inp_buf_end;
char *inp_buf_ptr;
};
typedef enum {
reading_nothing,
reading_makefile,
reading_statefile,
rereading_statefile,
reading_cpp_file
} Makefile_type;
/*
* Typedefs for all structs
*/
typedef struct _Chain *Chain, Chain_rec;
typedef struct _Envvar *Envvar, Envvar_rec;
typedef struct _Macro_list *Macro_list, Macro_list_rec;
typedef struct _Name *Name, Name_rec;
typedef struct _Property *Property, Property_rec;
typedef struct _Source *Source, Source_rec;
typedef struct _String *String, String_rec;
/*
* name records hash table.
*/
struct Name_set {
private:
// single node in a tree
struct entry {
entry(Name name_, entry *parent_) :
name(name_),
parent(parent_),
left(0),
right(0),
depth(1)
{}
Name name;
entry *parent;
entry *left;
entry *right;
unsigned depth;
void setup_depth() {
unsigned rdepth = (right != 0) ? right->depth : 0;
unsigned ldepth = (left != 0) ? left->depth : 0;
depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth);
}
};
public:
// make iterator a friend of Name_set to have access to struct entry
struct iterator;
friend struct Name_set::iterator;
// iterator over tree nodes
struct iterator {
public:
// constructors
iterator() : node(0) {}
iterator(entry *node_) : node(node_) {}
// dereference operator
Name operator->() const { return node->name; }
// conversion operator
operator Name() { return node->name; }
// assignment operator
iterator& operator=(const iterator &o) { node = o.node; return *this; }
// equality/inequality operators
int operator==(const iterator &o) const { return (node == o.node); }
int operator!=(const iterator &o) const { return (node != o.node); }
// pre/post increment operators
iterator& operator++();
iterator operator++(int) { iterator it = *this; ++*this; return it; }
private:
// the node iterator points to
entry *node;
};
public:
// constructor
Name_set() : root(0) {}
// lookup, insert and remove operations
Name lookup(const char *key);
Name insert(const char *key, Boolean &found);
void insert(Name name);
// begin/end iterators
iterator begin() const;
iterator end() const { return iterator(); }
private:
// rebalance given node
void rebalance(entry *node);
private:
// tree root
entry *root;
};
/*
* extern declarations for all global variables.
* The actual declarations are in globals.cc
*/
extern char char_semantics[];
extern wchar_t char_semantics_char[];
extern Macro_list cond_macro_list;
extern Boolean conditional_macro_used;
extern Boolean do_not_exec_rule; /* `-n' */
extern Boolean dollarget_seen;
extern Boolean dollarless_flag;
extern Name dollarless_value;
extern char **environ;
extern Envvar envvar;
extern int exit_status;
extern wchar_t *file_being_read;
/* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
extern Boolean gnu_style;
extern Name_set hashtab;
extern Name host_arch;
extern Name host_mach;
extern int line_number;
extern char *make_state_lockfile;
extern Boolean make_word_mentioned;
extern Makefile_type makefile_type;
extern char mbs_buffer[];
extern Name path_name;
extern Boolean posix;
extern Name query;
extern Boolean query_mentioned;
extern Name hat;
extern Boolean reading_environment;
extern Name shell_name;
extern Boolean svr4;
extern Name target_arch;
extern Name target_mach;
extern Boolean tilde_rule;
extern wchar_t wcs_buffer[];
extern Boolean working_on_targets;
extern Name virtual_root;
extern Boolean vpath_defined;
extern Name vpath_name;
extern Boolean make_state_locked;
extern Boolean out_err_same;
extern pid_t childPid;
/*
* RFE 1257407: make does not use fine granularity time info available from stat.
* High resolution time comparison.
*/
inline int
operator==(const timestruc_t &t1, const timestruc_t &t2) {
return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec));
}
inline int
operator!=(const timestruc_t &t1, const timestruc_t &t2) {
return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec));
}
inline int
operator>(const timestruc_t &t1, const timestruc_t &t2) {
if (t1.tv_sec == t2.tv_sec) {
return (t1.tv_nsec > t2.tv_nsec);
}
return (t1.tv_sec > t2.tv_sec);
}
inline int
operator>=(const timestruc_t &t1, const timestruc_t &t2) {
if (t1.tv_sec == t2.tv_sec) {
return (t1.tv_nsec >= t2.tv_nsec);
}
return (t1.tv_sec > t2.tv_sec);
}
inline int
operator<(const timestruc_t &t1, const timestruc_t &t2) {
if (t1.tv_sec == t2.tv_sec) {
return (t1.tv_nsec < t2.tv_nsec);
}
return (t1.tv_sec < t2.tv_sec);
}
inline int
operator<=(const timestruc_t &t1, const timestruc_t &t2) {
if (t1.tv_sec == t2.tv_sec) {
return (t1.tv_nsec <= t2.tv_nsec);
}
return (t1.tv_sec < t2.tv_sec);
}
#endif

37
include/mksh/dosys.h Normal file
View file

@ -0,0 +1,37 @@
#ifndef _MKSH_DOSYS_H
#define _MKSH_DOSYS_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mksh/defs.h>
#include <vroot/vroot.h>
extern Boolean await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, void *xdrs, int job_msg_id);
extern int doexec(register wchar_t *command, register Boolean ignore_error, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio);
extern int doshell(wchar_t *command, register Boolean ignore_error, char *stdout_file, char *stderr_file, int nice_prio);
extern void redirect_io(char *stdout_file, char *stderr_file);
extern void sh_command2string(register String command, register String destination);
#endif

30
include/mksh/globals.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef _MKSH_GLOBALS_H
#define _MKSH_GLOBALS_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1994 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mksh/defs.h>
#endif

33
include/mksh/i18n.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef _MKSH_I18N_H
#define _MKSH_I18N_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1994 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mksh/defs.h>
extern int get_char_semantics_entry(wchar_t ch);
extern char get_char_semantics_value(wchar_t ch);
#endif

View file

@ -0,0 +1,31 @@
#ifndef _MKSH_INIT_H
#define _MKSH_INIT_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1995 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
int libmksh_init()
void libmksh_fini();
#endif

36
include/mksh/macro.h Normal file
View file

@ -0,0 +1,36 @@
#ifndef _MKSH_MACRO_H
#define _MKSH_MACRO_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mksh/defs.h>
extern void expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd);
extern void expand_value(Name value, register String destination, Boolean cmd);
extern Name getvar(register Name name);
extern Property setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level);
#endif

55
include/mksh/misc.h Normal file
View file

@ -0,0 +1,55 @@
#ifndef _MKSH_MISC_H
#define _MKSH_MISC_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mksh/defs.h>
extern void append_char(wchar_t from, register String to);
extern Property append_prop(register Name target, register Property_id type);
extern void append_string(register wchar_t *from, register String to, register int length);
extern void enable_interrupt(register void (*handler) (int));
extern char *errmsg(int errnum);
extern void fatal_mksh(const char *message, ...);
extern void fatal_reader_mksh(const char *pattern, ...);
extern char *get_current_path_mksh(void);
extern Property get_prop(register Property start, register Property_id type);
extern char *getmem(register int size);
extern Name getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp = NULL);
extern void store_name(Name name);
extern void free_name(Name name);
extern void handle_interrupt_mksh(int);
extern Property maybe_append_prop(register Name target, register Property_id type);
extern void retmem(wchar_t *p);
extern void retmem_mb(caddr_t p);
extern void setup_char_semantics(void);
extern void setup_interrupt(register void (*handler) (int));
extern void warning_mksh(char * message, ...);
extern void append_string(register char *from, register String to, register int length);
extern wchar_t *get_wstring(char * from);
#endif

37
include/mksh/mksh.h Normal file
View file

@ -0,0 +1,37 @@
#ifndef _MKSH_MKSH_H
#define _MKSH_MKSH_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Included files
*/
#include <mksh/defs.h>
#include <unistd.h>
#endif

33
include/mksh/read.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef _MKSH_READ_H
#define _MKSH_READ_H
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1994 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mksh/defs.h>
extern Source get_next_block_fn(register Source source);
#endif

63
include/vroot/args.h Normal file
View file

@ -0,0 +1,63 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1999 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _ARGS_H_
#define _ARGS_H_
#include <sys/syscall.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/param.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
typedef enum { rw_read, rw_write} rwt, *rwpt;
extern void translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw);
union Args {
struct { int mode;} access;
struct { int mode;} chmod;
struct { int user; int group;} chown;
struct { int mode;} creat;
struct { char **argv; char **environ;} execve;
struct { struct stat *buffer;} lstat;
struct { int mode;} mkdir;
struct { char *name; int mode;} mount;
struct { int flags; int mode;} open;
struct { char *buffer; int buffer_size;} readlink;
struct { struct stat *buffer;} stat;
struct { int length;} truncate;
struct { struct timeval *time;} utimes;
};
extern union Args vroot_args;
extern int vroot_result;
#endif

48
include/vroot/report.h Normal file
View file

@ -0,0 +1,48 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1994 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _REPORT_H_
#define _REPORT_H_
#include <stdio.h>
extern FILE *get_report_file(void);
extern char *get_target_being_reported_for(void);
extern void report_dependency(const char *name);
extern int file_lock(char *name, char *lockname, int *file_locked, int timeout);
#define SUNPRO_DEPENDENCIES "SUNPRO_DEPENDENCIES"
#define LD "LD"
#define COMP "COMP"
/*
* These relate to Sun's ancient source control system that predated TeamWare,
* named NSE. They appear to be used regardless of its presence, however, and
* so linger.
*/
#define NSE_DEPINFO ".nse_depinfo"
#define NSE_DEPINFO_LOCK ".nse_depinfo.lock"
#endif

61
include/vroot/vroot.h Normal file
View file

@ -0,0 +1,61 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _VROOT_H_
#define _VROOT_H_
#include <stdio.h>
#include <nl_types.h>
#define VROOT_DEFAULT ((pathpt)-1)
typedef struct {
char *path;
short length;
} pathcellt, *pathcellpt, patht;
typedef patht *pathpt;
extern void add_dir_to_path(const char *path, register pathpt *pointer, register int position);
extern void flush_path_cache(void);
extern void flush_vroot_cache(void);
extern const char *get_path_name(void);
extern char *get_vroot_path(register char **vroot, register char **path, register char **filename);
extern const char *get_vroot_name(void);
extern int open_vroot(char *path, int flags, int mode, pathpt vroot_path, pathpt vroot_vroot);
extern pathpt parse_path_string(register char *string, register int remove_slash);
extern void scan_path_first(void);
extern void scan_vroot_first(void);
extern void set_path_style(int style);
extern int access_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot);
extern int execve_vroot(char *path, char **argv, char **environ, pathpt vroot_path, pathpt vroot_vroot);
extern int lstat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot);
extern int stat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot);
extern int readlink_vroot(char *path, char *buffer, int buffer_size, pathpt vroot_path, pathpt vroot_vroot);
#endif

73
lib/bsd/bsd.cc Normal file
View file

@ -0,0 +1,73 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <signal.h>
#include <bsd/bsd.h>
/* External references.
*/
/* Forward references.
*/
/* Static data.
*/
extern SIG_PF
bsd_signal (int Signal, SIG_PF Handler)
{
auto SIG_PF previous_handler;
#ifdef sun
previous_handler = sigset (Signal, Handler);
#else
auto struct sigaction new_action;
auto struct sigaction old_action;
new_action.sa_flags = SA_SIGINFO;
new_action.sa_handler = (void (*) ()) Handler;
(void) sigemptyset (&new_action.sa_mask);
(void) sigaddset (&new_action.sa_mask, Signal);
(void) sigaction (Signal, &new_action, &old_action);
previous_handler = (SIG_PF) old_action.sa_handler;
#endif
return previous_handler;
}
extern void
bsd_signals (void)
{
static int initialized = 0;
if (initialized == 0)
{
initialized = 1;
}
return;
}

188
lib/makestate/ld_file.c Normal file
View file

@ -0,0 +1,188 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1998 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma init(ld_support_init)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <libelf.h>
#include <sys/param.h>
#include <link.h>
#define SUNPRO_DEPENDENCIES "SUNPRO_DEPENDENCIES"
/*
* Linked list of strings - used to keep lists of names
* of directories or files.
*/
struct Stritem {
char * str;
void * next;
};
typedef struct Stritem Stritem;
static char * depend_file = NULL;
static Stritem * list = NULL;
void mk_state_init()
{
depend_file = getenv(SUNPRO_DEPENDENCIES);
} /* mk_state_init() */
static void
prepend_str(Stritem **list, const char * str)
{
Stritem * new;
char * newstr;
if (!(new = calloc(1, sizeof (Stritem)))) {
perror("libmakestate.so");
return;
} /* if */
if (!(newstr = malloc(strlen(str) + 1))) {
perror("libmakestate.so");
return;
} /* if */
new->str = strcpy(newstr, str);
new->next = *list;
*list = new;
} /* prepend_str() */
void
mk_state_collect_dep(const char * file)
{
/*
* SUNPRO_DEPENDENCIES wasn't set, we don't collect .make.state
* information.
*/
if (!depend_file)
return;
prepend_str(&list, file);
} /* mk_state_collect_dep() */
void
mk_state_update_exit()
{
Stritem * cur;
char lockfile[MAXPATHLEN], * err, * space, * target;
FILE * ofp;
extern char * file_lock(char *, char *, int);
if (!depend_file)
return;
if ((space = strchr(depend_file, ' ')) == NULL)
return;
*space = '\0';
target = &space[1];
(void) sprintf(lockfile, "%s.lock", depend_file);
if ((err = file_lock(depend_file, lockfile, 0))) {
(void) fprintf(stderr, "%s\n", err);
return;
} /* if */
if (!(ofp = fopen(depend_file, "a")))
return;
if (list)
(void) fprintf(ofp, "%s: ", target);
for (cur = list; cur; cur = cur->next)
(void) fprintf(ofp, " %s", cur->str);
(void) fputc('\n', ofp);
(void) fclose(ofp);
(void) unlink(lockfile);
*space = ' ';
} /* mk_state_update_exit() */
static void
/* LINTED static unused */
ld_support_init()
{
mk_state_init();
} /* ld_support_init() */
/* ARGSUSED */
void
ld_file(const char * file, const Elf_Kind ekind, int flags, Elf *elf)
{
if(! ((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED)))
return;
mk_state_collect_dep(file);
} /* ld_file */
void
ld_atexit(int exit_code)
{
if (exit_code)
return;
mk_state_update_exit();
} /* ld_atexit() */
/*
* Supporting 64-bit objects
*/
void
ld_file64(const char * file, const Elf_Kind ekind, int flags, Elf *elf)
{
if(! ((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED)))
return;
mk_state_collect_dep(file);
} /* ld_file64 */
void
ld_atexit64(int exit_code)
{
if (exit_code)
return;
mk_state_update_exit();
} /* ld_atexit64() */

172
lib/makestate/lock.c Normal file
View file

@ -0,0 +1,172 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <errno.h> /* errno */
#if defined(_LP64)
/*
* The symbols _sys_errlist and _sys_nerr are not visible in the
* LP64 libc. Use strerror(3C) instead.
*/
#else /* #_LP64 */
extern char * sys_errlist[];
extern int sys_nerr;
#endif /* #_LP64 */
static void file_lock_error();
/*
* This code stolen from the NSE library and changed to not depend
* upon any NSE routines or header files.
*
* Simple file locking.
* Create a symlink to a file. The "test and set" will be
* atomic as creating the symlink provides both functions.
*
* The timeout value specifies how long to wait for stale locks
* to disappear. If the lock is more than 'timeout' seconds old
* then it is ok to blow it away. This part has a small window
* of vunerability as the operations of testing the time,
* removing the lock and creating a new one are not atomic.
* It would be possible for two processes to both decide to blow
* away the lock and then have process A remove the lock and establish
* its own, and then then have process B remove the lock which accidentily
* removes A's lock rather than the stale one.
*
* A further complication is with the NFS. If the file in question is
* being served by an NFS server, then its time is set by that server.
* We can not use the time on the client machine to check for a stale
* lock. Therefore, a temp file on the server is created to get
* the servers current time.
*
* Returns an error message. NULL return means the lock was obtained.
*
*/
char *
file_lock(char * name, char * lockname, int timeout)
{
int r;
int fd;
struct stat statb;
struct stat fs_statb;
char tmpname[MAXPATHLEN];
static char msg[MAXPATHLEN];
if (timeout <= 0) {
timeout = 15;
}
for (;;) {
r = symlink(name, lockname);
if (r == 0) {
return (NULL);
}
if (errno != EEXIST) {
file_lock_error(msg, name,
(const char *)"symlink(%s, %s)", name, lockname);
return (msg);
}
for (;;) {
(void) sleep(1);
r = lstat(lockname, &statb);
if (r == -1) {
/*
* The lock must have just gone away - try
* again.
*/
break;
}
/*
* With the NFS the time given a file is the time on
* the file server. This time may vary from the
* client's time. Therefore, we create a tmpfile in
* the same directory to establish the time on the
* server and use this time to see if the lock has
* expired.
*/
(void) sprintf(tmpname, "%s.XXXXXX", lockname);
(void) mktemp(tmpname);
fd = creat(tmpname, 0666);
if (fd != -1) {
(void) close(fd);
} else {
file_lock_error(msg, name,
(const char *)"creat(%s)", tmpname);
return (msg);
}
if (stat(tmpname, &fs_statb) == -1) {
file_lock_error(msg, name,
(const char *)"stat(%s)", tmpname);
return (msg);
}
(void) unlink(tmpname);
if (statb.st_mtime + timeout < fs_statb.st_mtime) {
/*
* The lock has expired - blow it away.
*/
(void) unlink(lockname);
break;
}
}
}
/* NOTREACHED */
}
/*
* Format a message telling why the lock could not be created.
*/
/* VARARGS4 */
static void
file_lock_error(char * msg, char * file, const char * str, char * arg1,
char * arg2)
{
int len;
(void) sprintf(msg, "Could not lock file `%s'; ", file);
len = strlen(msg);
(void) sprintf(&msg[len], str, arg1, arg2);
(void) strcat(msg, " failed - ");
#if defined(_LP64)
/* Needs to be changed to use strerror(3C) instead. */
len = strlen(msg);
(void) sprintf(&msg[len], "errno %d", errno);
#else /* #_LP64 */
if (errno < sys_nerr) {
(void) strcat(msg, sys_errlist[errno]);
} else {
len = strlen(msg);
(void) sprintf(&msg[len], "errno %d", errno);
}
#endif /* #_LP64 */
}

577
lib/mksh/dosys.cc Normal file
View file

@ -0,0 +1,577 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright 2015, Joyent, Inc.
*/
/*
* dosys.cc
*
* Execute one commandline
*/
/*
* Included files
*/
#include <sys/wait.h> /* WIFEXITED(status) */
#include <alloca.h> /* alloca() */
#include <stdio.h> /* errno */
#include <errno.h> /* errno */
#include <fcntl.h> /* open() */
#include <mksh/dosys.h>
#include <mksh/macro.h> /* getvar() */
#include <mksh/misc.h> /* getmem(), fatal_mksh(), errmsg() */
#include <sys/signal.h> /* SIG_DFL */
#include <sys/stat.h> /* open() */
#include <sys/wait.h> /* wait() */
#include <ulimit.h> /* ulimit() */
#include <unistd.h> /* close(), dup2() */
#include <stdlib.h> /* closefrom() */
#include <libintl.h>
/*
* typedefs & structs
*/
/*
* Static variables
*/
/*
* File table of contents
*/
static Boolean exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path);
/*
* Workaround for NFS bug. Sometimes, when running 'open' on a remote
* dmake server, it fails with "Stale NFS file handle" error.
* The second attempt seems to work.
*/
int
my_open(const char *path, int oflag, mode_t mode) {
int res = open(path, oflag, mode);
if (res < 0 && (errno == ESTALE || errno == EAGAIN)) {
/* Stale NFS file handle. Try again */
res = open(path, oflag, mode);
}
return res;
}
/*
* void
* redirect_io(char *stdout_file, char *stderr_file)
*
* Redirects stdout and stderr for a child mksh process.
*/
void
redirect_io(char *stdout_file, char *stderr_file)
{
int i;
(void) closefrom(3);
if ((i = my_open(stdout_file,
O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
S_IREAD | S_IWRITE)) < 0) {
fatal_mksh(gettext("Couldn't open standard out temp file `%s': %s"),
stdout_file,
errmsg(errno));
} else {
if (dup2(i, 1) == -1) {
fatal_mksh("*** Error: dup2(3, 1) failed: %s",
errmsg(errno));
}
close(i);
}
if (stderr_file == NULL) {
if (dup2(1, 2) == -1) {
fatal_mksh("*** Error: dup2(1, 2) failed: %s",
errmsg(errno));
}
} else if ((i = my_open(stderr_file,
O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
S_IREAD | S_IWRITE)) < 0) {
fatal_mksh(gettext("Couldn't open standard error temp file `%s': %s"),
stderr_file,
errmsg(errno));
} else {
if (dup2(i, 2) == -1) {
fatal_mksh("*** Error: dup2(3, 2) failed: %s",
errmsg(errno));
}
close(i);
}
}
/*
* doshell(command, ignore_error)
*
* Used to run command lines that include shell meta-characters.
* The make macro SHELL is supposed to contain a path to the shell.
*
* Return value:
* The pid of the process we started
*
* Parameters:
* command The command to run
* ignore_error Should we abort on error?
*
* Global variables used:
* filter_stderr If -X is on we redirect stderr
* shell_name The Name "SHELL", used to get the path to shell
*/
int
doshell(wchar_t *command, register Boolean ignore_error, char *stdout_file, char *stderr_file, int nice_prio)
{
char *argv[6];
int argv_index = 0;
int cmd_argv_index;
int length;
char nice_prio_buf[MAXPATHLEN];
register Name shell = getvar(shell_name);
register char *shellname;
char *tmp_mbs_buffer;
if (IS_EQUAL(shell->string_mb, "")) {
shell = shell_name;
}
if ((shellname = strrchr(shell->string_mb, (int) slash_char)) == NULL) {
shellname = shell->string_mb;
} else {
shellname++;
}
/*
* Only prepend the /usr/bin/nice command to the original command
* if the nice priority, nice_prio, is NOT zero (0).
* Nice priorities can be a positive or a negative number.
*/
if (nice_prio != 0) {
argv[argv_index++] = (char *)"nice";
(void) sprintf(nice_prio_buf, "-%d", nice_prio);
argv[argv_index++] = strdup(nice_prio_buf);
}
argv[argv_index++] = shellname;
argv[argv_index++] = (char*)(ignore_error ? "-c" : "-ce");
if ((length = wcslen(command)) >= MAXPATHLEN) {
tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
(void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
cmd_argv_index = argv_index;
argv[argv_index++] = strdup(tmp_mbs_buffer);
retmem_mb(tmp_mbs_buffer);
} else {
WCSTOMBS(mbs_buffer, command);
cmd_argv_index = argv_index;
argv[argv_index++] = strdup(mbs_buffer);
}
argv[argv_index] = NULL;
(void) fflush(stdout);
if ((childPid = fork()) == 0) {
enable_interrupt((void (*) (int)) SIG_DFL);
#if 0
if (filter_stderr) {
redirect_stderr();
}
#endif
if (nice_prio != 0) {
(void) execve("/usr/bin/nice", argv, environ);
fatal_mksh(gettext("Could not load `/usr/bin/nice': %s"),
errmsg(errno));
} else {
(void) execve(shell->string_mb, argv, environ);
fatal_mksh(gettext("Could not load Shell from `%s': %s"),
shell->string_mb,
errmsg(errno));
}
}
if (childPid == -1) {
fatal_mksh(gettext("fork failed: %s"),
errmsg(errno));
}
retmem_mb(argv[cmd_argv_index]);
return childPid;
}
/*
* exec_vp(name, argv, envp, ignore_error)
*
* Like execve, but does path search.
* This starts command when make invokes it directly (without a shell).
*
* Return value:
* Returns false if the exec failed
*
* Parameters:
* name The name of the command to run
* argv Arguments for the command
* envp The environment for it
* ignore_error Should we abort on error?
*
* Global variables used:
* shell_name The Name "SHELL", used to get the path to shell
* vroot_path The path used by the vroot package
*/
static Boolean
exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path)
{
register Name shell = getvar(shell_name);
register char *shellname;
char *shargv[4];
Name tmp_shell;
if (IS_EQUAL(shell->string_mb, "")) {
shell = shell_name;
}
for (int i = 0; i < 5; i++) {
(void) execve_vroot(name,
argv + 1,
envp,
vroot_path,
VROOT_DEFAULT);
switch (errno) {
case ENOEXEC:
case ENOENT:
/* That failed. Let the shell handle it */
shellname = strrchr(shell->string_mb, (int) slash_char);
if (shellname == NULL) {
shellname = shell->string_mb;
} else {
shellname++;
}
shargv[0] = shellname;
shargv[1] = (char*)(ignore_error ? "-c" : "-ce");
shargv[2] = argv[0];
shargv[3] = NULL;
tmp_shell = getvar(shell_name);
if (IS_EQUAL(tmp_shell->string_mb, "")) {
tmp_shell = shell_name;
}
(void) execve_vroot(tmp_shell->string_mb,
shargv,
envp,
vroot_path,
VROOT_DEFAULT);
return failed;
case ETXTBSY:
/*
* The program is busy (debugged?).
* Wait and then try again.
*/
(void) sleep((unsigned) i);
case EAGAIN:
break;
default:
return failed;
}
}
return failed;
}
/*
* doexec(command, ignore_error)
*
* Will scan an argument string and split it into words
* thus building an argument list that can be passed to exec_ve()
*
* Return value:
* The pid of the process started here
*
* Parameters:
* command The command to run
* ignore_error Should we abort on error?
*
* Global variables used:
* filter_stderr If -X is on we redirect stderr
*/
int
doexec(register wchar_t *command, register Boolean ignore_error, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
{
int arg_count = 5;
char **argv;
int length;
char nice_prio_buf[MAXPATHLEN];
register char **p;
wchar_t *q;
register wchar_t *t;
char *tmp_mbs_buffer;
/*
* Only prepend the /usr/bin/nice command to the original command
* if the nice priority, nice_prio, is NOT zero (0).
* Nice priorities can be a positive or a negative number.
*/
if (nice_prio != 0) {
arg_count += 2;
}
for (t = command; *t != (int) nul_char; t++) {
if (iswspace(*t)) {
arg_count++;
}
}
argv = (char **)alloca(arg_count * (sizeof(char *)));
/*
* Reserve argv[0] for sh in case of exec_vp failure.
* Don't worry about prepending /usr/bin/nice command to argv[0].
* In fact, doing it may cause the sh command to fail!
*/
p = &argv[1];
if ((length = wcslen(command)) >= MAXPATHLEN) {
tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
(void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
argv[0] = strdup(tmp_mbs_buffer);
retmem_mb(tmp_mbs_buffer);
} else {
WCSTOMBS(mbs_buffer, command);
argv[0] = strdup(mbs_buffer);
}
if (nice_prio != 0) {
*p++ = strdup("/usr/bin/nice");
(void) sprintf(nice_prio_buf, "-%d", nice_prio);
*p++ = strdup(nice_prio_buf);
}
/* Build list of argument words. */
for (t = command; *t;) {
if (p >= &argv[arg_count]) {
/* This should never happen, right? */
WCSTOMBS(mbs_buffer, command);
fatal_mksh(gettext("Command `%s' has more than %d arguments"),
mbs_buffer,
arg_count);
}
q = t;
while (!iswspace(*t) && (*t != (int) nul_char)) {
t++;
}
if (*t) {
for (*t++ = (int) nul_char; iswspace(*t); t++);
}
if ((length = wcslen(q)) >= MAXPATHLEN) {
tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
(void) wcstombs(tmp_mbs_buffer, q, (length * MB_LEN_MAX) + 1);
*p++ = strdup(tmp_mbs_buffer);
retmem_mb(tmp_mbs_buffer);
} else {
WCSTOMBS(mbs_buffer, q);
*p++ = strdup(mbs_buffer);
}
}
*p = NULL;
/* Then exec the command with that argument list. */
(void) fflush(stdout);
if ((childPid = fork()) == 0) {
enable_interrupt((void (*) (int)) SIG_DFL);
#if 0
if (filter_stderr) {
redirect_stderr();
}
#endif
(void) exec_vp(argv[1], argv, environ, ignore_error, vroot_path);
fatal_mksh(gettext("Cannot load command `%s': %s"), argv[1], errmsg(errno));
}
if (childPid == -1) {
fatal_mksh(gettext("fork failed: %s"),
errmsg(errno));
}
for (int i = 0; argv[i] != NULL; i++) {
retmem_mb(argv[i]);
}
return childPid;
}
/*
* await(ignore_error, silent_error, target, command, running_pid)
*
* Wait for one child process and analyzes
* the returned status when the child process terminates.
*
* Return value:
* Returns true if commands ran OK
*
* Parameters:
* ignore_error Should we abort on error?
* silent_error Should error messages be suppressed for dmake?
* target The target we are building, for error msgs
* command The command we ran, for error msgs
* running_pid The pid of the process we are waiting for
*
* Static variables used:
* filter_file The fd for the filter file
* filter_file_name The name of the filter file
*
* Global variables used:
* filter_stderr Set if -X is on
*/
Boolean
await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, void *xdrs_p, int job_msg_id)
{
int status;
char *buffer;
int core_dumped;
int exit_status;
FILE *outfp;
register pid_t pid;
struct stat stat_buff;
int termination_signal;
char tmp_buf[MAXPATHLEN];
while ((pid = wait(&status)) != running_pid) {
if (pid == -1) {
fatal_mksh(gettext("wait() failed: %s"), errmsg(errno));
}
}
(void) fflush(stdout);
(void) fflush(stderr);
if (status == 0) {
#ifdef PRINT_EXIT_STATUS
warning_mksh("I'm in await(), and status is 0.");
#endif
return succeeded;
}
#ifdef PRINT_EXIT_STATUS
warning_mksh("I'm in await(), and status is *NOT* 0.");
#endif
exit_status = WEXITSTATUS(status);
#ifdef PRINT_EXIT_STATUS
warning_mksh("I'm in await(), and exit_status is %d.", exit_status);
#endif
termination_signal = WTERMSIG(status);
core_dumped = WCOREDUMP(status);
/*
* If the child returned an error, we now try to print a
* nice message about it.
*/
tmp_buf[0] = (int) nul_char;
if (!silent_error) {
if (exit_status != 0) {
(void) fprintf(stdout,
gettext("*** Error code %d"),
exit_status);
} else {
(void) fprintf(stdout,
gettext("*** Signal %d"),
termination_signal);
if (core_dumped) {
(void) fprintf(stdout,
gettext(" - core dumped"));
}
}
if (ignore_error) {
(void) fprintf(stdout,
gettext(" (ignored)"));
}
(void) fprintf(stdout, "\n");
(void) fflush(stdout);
}
#ifdef PRINT_EXIT_STATUS
warning_mksh("I'm in await(), returning failed.");
#endif
return failed;
}
/*
* sh_command2string(command, destination)
*
* Run one sh command and capture the output from it.
*
* Return value:
*
* Parameters:
* command The command to run
* destination Where to deposit the output from the command
*
* Static variables used:
*
* Global variables used:
*/
void
sh_command2string(register String command, register String destination)
{
register FILE *fd;
register int chr;
int status;
Boolean command_generated_output = false;
command->text.p = (int) nul_char;
WCSTOMBS(mbs_buffer, command->buffer.start);
if ((fd = popen(mbs_buffer, "r")) == NULL) {
WCSTOMBS(mbs_buffer, command->buffer.start);
fatal_mksh(gettext("Could not run command `%s' for :sh transformation"),
mbs_buffer);
}
while ((chr = getc(fd)) != EOF) {
if (chr == (int) newline_char) {
chr = (int) space_char;
}
command_generated_output = true;
append_char(chr, destination);
}
/*
* We don't want to keep the last LINE_FEED since usually
* the output of the 'sh:' command is used to evaluate
* some MACRO. ( /bin/sh and other shell add a line feed
* to the output so that the prompt appear in the right place.
* We don't need that
*/
if (command_generated_output){
if ( *(destination->text.p-1) == (int) space_char) {
* (-- destination->text.p) = '\0';
}
} else {
/*
* If the command didn't generate any output,
* set the buffer to a null string.
*/
*(destination->text.p) = '\0';
}
status = pclose(fd);
if (status != 0) {
WCSTOMBS(mbs_buffer, command->buffer.start);
fatal_mksh(gettext("The command `%s' returned status `%d'"),
mbs_buffer,
WEXITSTATUS(status));
}
}

128
lib/mksh/globals.cc Normal file
View file

@ -0,0 +1,128 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* globals.cc
*
* This declares all global variables
*/
/*
* Included files
*/
#include <mksh/globals.h>
/*
* Defined macros
*/
/*
* typedefs & structs
*/
/*
* Global variables
*/
char char_semantics[CHAR_SEMANTICS_ENTRIES];
wchar_t char_semantics_char[] = {
ampersand_char,
asterisk_char,
at_char,
backquote_char,
backslash_char,
bar_char,
bracketleft_char,
bracketright_char,
colon_char,
dollar_char,
doublequote_char,
equal_char,
exclam_char,
greater_char,
hat_char,
hyphen_char,
less_char,
newline_char,
numbersign_char,
parenleft_char,
parenright_char,
percent_char,
plus_char,
question_char,
quote_char,
semicolon_char,
nul_char
};
Macro_list cond_macro_list;
Boolean conditional_macro_used;
Boolean do_not_exec_rule; /* `-n' */
Boolean dollarget_seen;
Boolean dollarless_flag;
Name dollarless_value;
Envvar envvar;
#ifdef lint
char **environ;
#endif
int exit_status;
wchar_t *file_being_read;
/* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
Boolean gnu_style = false;
Name_set hashtab;
Name host_arch;
Name host_mach;
int line_number;
char *make_state_lockfile;
Boolean make_word_mentioned;
Makefile_type makefile_type = reading_nothing;
char mbs_buffer[(MAXPATHLEN * MB_LEN_MAX)];
Name path_name;
Boolean posix = true;
Name hat;
Name query;
Boolean query_mentioned;
Boolean reading_environment;
Name shell_name;
Boolean svr4 = false;
Name target_arch;
Name target_mach;
Boolean tilde_rule;
Name virtual_root;
Boolean vpath_defined;
Name vpath_name;
wchar_t wcs_buffer[MAXPATHLEN];
Boolean working_on_targets;
Boolean out_err_same;
pid_t childPid = -1; // This variable is used for killing child's process
// Such as qrsh, running command, etc.
/*
* timestamps defined in defs.h
*/
const timestruc_t file_no_time = { -1, 0 };
const timestruc_t file_doesnt_exist = { 0, 0 };
const timestruc_t file_is_dir = { 1, 0 };
const timestruc_t file_min_time = { 2, 0 };
const timestruc_t file_max_time = { INT_MAX, 0 };

91
lib/mksh/i18n.cc Normal file
View file

@ -0,0 +1,91 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* i18n.cc
*
* Deal with internationalization conversions
*/
/*
* Included files
*/
#include <mksh/i18n.h>
#include <mksh/misc.h> /* setup_char_semantics() */
/*
* get_char_semantics_value(ch)
*
* Return value:
* The character semantics of ch.
*
* Parameters:
* ch character we want semantics for.
*
*/
char
get_char_semantics_value(wchar_t ch)
{
static Boolean char_semantics_setup;
if (!char_semantics_setup) {
setup_char_semantics();
char_semantics_setup = true;
}
return char_semantics[get_char_semantics_entry(ch)];
}
/*
* get_char_semantics_entry(ch)
*
* Return value:
* The slot number in the array for special make chars,
* else the slot number of the last array entry.
*
* Parameters:
* ch The wide character
*
* Global variables used:
* char_semantics_char[] array of special wchar_t chars
* "&*@`\\|[]:$=!>-\n#()%?;^<'\""
*/
int
get_char_semantics_entry(wchar_t ch)
{
wchar_t *char_sem_char;
char_sem_char = (wchar_t *) wcschr(char_semantics_char, ch);
if (char_sem_char == NULL) {
/*
* Return the integer entry for the last slot,
* whose content is empty.
*/
return (CHAR_SEMANTICS_ENTRIES - 1);
} else {
return (char_sem_char - char_semantics_char);
}
}

1335
lib/mksh/macro.cc Normal file

File diff suppressed because it is too large Load diff

1113
lib/mksh/misc.cc Normal file

File diff suppressed because it is too large Load diff

131
lib/mksh/mksh.cc Normal file
View file

@ -0,0 +1,131 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* mksh.cc
*
* Execute the command(s) of one Make or DMake rule
*/
/*
* Included files
*/
#include <mksh/dosys.h> /* redirect_io() */
#include <mksh/misc.h> /* retmem() */
#include <mksh/mksh.h>
#include <errno.h>
#include <signal.h>
/*
* Workaround for NFS bug. Sometimes, when running 'chdir' on a remote
* dmake server, it fails with "Stale NFS file handle" error.
* The second attempt seems to work.
*/
int
my_chdir(char * dir) {
int res = chdir(dir);
if (res != 0 && (errno == ESTALE || errno == EAGAIN)) {
/* Stale NFS file handle. Try again */
res = chdir(dir);
}
return res;
}
/*
* File table of contents
*/
static void change_sunpro_dependencies_value(char *oldpath, char *newpath);
static void init_mksh_globals(char *shell);
static void set_env_vars(char *env_list[]);
static void
set_env_vars(char *env_list[])
{
char **env_list_p;
for (env_list_p = env_list;
*env_list_p != (char *) NULL;
env_list_p++) {
putenv(*env_list_p);
}
}
static void
init_mksh_globals(char *shell)
{
/*
MBSTOWCS(wcs_buffer, "SHELL");
shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
MBSTOWCS(wcs_buffer, shell);
(void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
*/
char * dmake_shell;
if ((dmake_shell = getenv("DMAKE_SHELL")) == NULL) {
dmake_shell = shell;
}
MBSTOWCS(wcs_buffer, dmake_shell);
shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
}
/*
* Change the pathname in the value of the SUNPRO_DEPENDENCIES env variable
* from oldpath to newpath.
*/
static void
change_sunpro_dependencies_value(char *oldpath, char *newpath)
{
char buf[MAXPATHLEN];
static char *env;
int length;
int oldpathlen;
char *sp_dep_value;
/* check if SUNPRO_DEPENDENCIES is set in the environment */
if ((sp_dep_value = getenv("SUNPRO_DEPENDENCIES")) != NULL) {
oldpathlen = strlen(oldpath);
/* check if oldpath is indeed in the value of SUNPRO_DEPENDENCIES */
if (strncmp(oldpath, sp_dep_value, oldpathlen) == 0) {
(void) sprintf(buf,
"%s%s",
newpath,
sp_dep_value + oldpathlen);
length = 2 +
strlen("SUNPRO_DEPENDENCIES") +
strlen(buf);
env = getmem(length);
(void) sprintf(env,
"%s=%s",
"SUNPRO_DEPENDENCIES",
buf);
(void) putenv(env);
}
}
}

170
lib/mksh/read.cc Normal file
View file

@ -0,0 +1,170 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* read.c
*
* This file contains the makefile reader.
*/
/*
* Included files
*/
#include <mksh/misc.h> /* retmem() */
#include <mksh/read.h>
#include <sys/uio.h> /* read() */
#include <unistd.h> /* close(), unlink(), read() */
#include <libintl.h>
#define STRING_LEN_TO_CONVERT (8*1024)
/*
* get_next_block_fn(source)
*
* Will get the next block of text to read either
* by popping one source bVSIZEOFlock of the stack of Sources
* or by reading some more from the makefile.
*
* Return value:
* The new source block to read from
*
* Parameters:
* source The old source block
*
* Global variables used:
* file_being_read The name of the current file, error msg
*/
Boolean make_state_locked;
Source
get_next_block_fn(register Source source)
{
register off_t to_read;
register int length;
register size_t num_wc_chars;
char ch_save;
char *ptr;
if (source == NULL) {
return NULL;
}
if ((source->fd < 0) ||
((source->bytes_left_in_file <= 0) &&
(source->inp_buf_ptr >= source->inp_buf_end))) {
/* We can't read from the makefile, so pop the source block */
if (source->fd > 2) {
(void) close(source->fd);
if (make_state_lockfile != NULL) {
(void) unlink(make_state_lockfile);
retmem_mb(make_state_lockfile);
make_state_lockfile = NULL;
make_state_locked = false;
}
}
if (source->string.free_after_use &&
(source->string.buffer.start != NULL)) {
retmem(source->string.buffer.start);
source->string.buffer.start = NULL;
}
if (source->inp_buf != NULL) {
retmem_mb(source->inp_buf);
source->inp_buf = NULL;
}
source = source->previous;
if (source != NULL) {
source->error_converting = false;
}
return source;
}
if (source->bytes_left_in_file > 0) {
/*
* Read the whole makefile.
* Hopefully the kernel managed to prefetch the stuff.
*/
to_read = source->bytes_left_in_file;
source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1);
source->inp_buf_end = source->inp_buf + to_read;
length = read(source->fd, source->inp_buf, (unsigned int) to_read);
if (length != to_read) {
WCSTOMBS(mbs_buffer, file_being_read);
if (length == 0) {
fatal_mksh(gettext("Error reading `%s': Premature EOF"),
mbs_buffer);
} else {
fatal_mksh(gettext("Error reading `%s': %s"),
mbs_buffer,
errmsg(errno));
}
}
*source->inp_buf_end = nul_char;
source->bytes_left_in_file = 0;
}
/*
* Try to convert the next piece.
*/
ptr = source->inp_buf_ptr + STRING_LEN_TO_CONVERT;
if (ptr > source->inp_buf_end) {
ptr = source->inp_buf_end;
}
for (num_wc_chars = 0; ptr > source->inp_buf_ptr; ptr--) {
ch_save = *ptr;
*ptr = nul_char;
num_wc_chars = mbstowcs(source->string.text.end,
source->inp_buf_ptr,
STRING_LEN_TO_CONVERT);
*ptr = ch_save;
if (num_wc_chars != (size_t)-1) {
break;
}
}
if ((int) num_wc_chars == (size_t)-1) {
source->error_converting = true;
return source;
}
source->error_converting = false;
source->inp_buf_ptr = ptr;
source->string.text.end += num_wc_chars;
*source->string.text.end = 0;
if (source->inp_buf_ptr >= source->inp_buf_end) {
if (*(source->string.text.end - 1) != (int) newline_char) {
WCSTOMBS(mbs_buffer, file_being_read);
warning_mksh(gettext("newline is not last character in file %s"),
mbs_buffer);
*source->string.text.end++ = (int) newline_char;
*source->string.text.end = (int) nul_char;
*source->string.buffer.end++;
}
if (source->inp_buf != NULL) {
retmem_mb(source->inp_buf);
source->inp_buf = NULL;
}
}
return source;
}

42
lib/vroot/access.cc Normal file
View file

@ -0,0 +1,42 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
#include <vroot/vroot.h>
#include <vroot/args.h>
static int access_thunk(char *path)
{
vroot_result= access(path, vroot_args.access.mode);
return((vroot_result == 0) || (errno != ENOENT));
}
int access_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.access.mode= mode;
translate_with_thunk(path, access_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

31
lib/vroot/args.cc Normal file
View file

@ -0,0 +1,31 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <vroot/vroot.h>
#include <vroot/args.h>
union Args vroot_args;
int vroot_result;

41
lib/vroot/chdir.cc Normal file
View file

@ -0,0 +1,41 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
#include <vroot/vroot.h>
#include <vroot/args.h>
static int chdir_thunk(char *path)
{
vroot_result= chdir(path);
return(vroot_result == 0);
}
int chdir_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
{
translate_with_thunk(path, chdir_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

46
lib/vroot/chmod.cc Normal file
View file

@ -0,0 +1,46 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/stat.h>
extern int chmod(const char *path, mode_t mode);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int chmod_thunk(char *path)
{
vroot_result= chmod(path, vroot_args.chmod.mode);
return(vroot_result == 0);
}
int chmod_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.chmod.mode= mode;
translate_with_thunk(path, chmod_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

47
lib/vroot/chown.cc Normal file
View file

@ -0,0 +1,47 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
#include <sys/types.h>
extern int chown(const char *path, uid_t owner, gid_t group);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int chown_thunk(char *path)
{
vroot_result= chown(path, vroot_args.chown.user, vroot_args.chown.group);
return(vroot_result == 0);
}
int chown_vroot(char *path, int user, int group, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.chown.user= user;
vroot_args.chown.group= group;
translate_with_thunk(path, chown_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

44
lib/vroot/chroot.cc Normal file
View file

@ -0,0 +1,44 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
extern int chroot(const char *path);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int chroot_thunk(char *path)
{
vroot_result= chroot(path);
return(vroot_result == 0);
}
int chroot_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
{
translate_with_thunk(path, chroot_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

47
lib/vroot/creat.cc Normal file
View file

@ -0,0 +1,47 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
extern int creat(const char *path, mode_t mode);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int creat_thunk(char *path)
{
vroot_result= creat(path, vroot_args.creat.mode);
return(vroot_result >= 0);
}
int creat_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.creat.mode= mode;
translate_with_thunk(path, creat_thunk, vroot_path, vroot_vroot, rw_write);
return(vroot_result);
}

50
lib/vroot/execve.cc Normal file
View file

@ -0,0 +1,50 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
extern int execve (const char *path, char *const argv[], char *const envp[]);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int execve_thunk(char *path)
{
execve(path, vroot_args.execve.argv, vroot_args.execve.environ);
switch (errno) {
case ETXTBSY:
case ENOEXEC: return 1;
default: return 0;
}
}
int execve_vroot(char *path, char **argv, char **environ, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.execve.argv= argv;
vroot_args.execve.environ= environ;
translate_with_thunk(path, execve_thunk, vroot_path, vroot_vroot, rw_read);
return(-1);
}

175
lib/vroot/lock.cc Normal file
View file

@ -0,0 +1,175 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <vroot/vroot.h>
#include <signal.h>
#include <errno.h> /* errno */
#include <libintl.h>
extern char *sys_errlist[];
extern int sys_nerr;
static void file_lock_error(char *msg, char *file, char *str, int arg1, int arg2);
#define BLOCK_INTERUPTS sigfillset(&newset) ; \
sigprocmask(SIG_SETMASK, &newset, &oldset)
#define UNBLOCK_INTERUPTS \
sigprocmask(SIG_SETMASK, &oldset, &newset)
/*
* This code stolen from the NSE library and changed to not depend
* upon any NSE routines or header files.
*
* Simple file locking.
* Create a symlink to a file. The "test and set" will be
* atomic as creating the symlink provides both functions.
*
* The timeout value specifies how long to wait for stale locks
* to disappear. If the lock is more than 'timeout' seconds old
* then it is ok to blow it away. This part has a small window
* of vunerability as the operations of testing the time,
* removing the lock and creating a new one are not atomic.
* It would be possible for two processes to both decide to blow
* away the lock and then have process A remove the lock and establish
* its own, and then then have process B remove the lock which accidentily
* removes A's lock rather than the stale one.
*
* A further complication is with the NFS. If the file in question is
* being served by an NFS server, then its time is set by that server.
* We can not use the time on the client machine to check for a stale
* lock. Therefore, a temp file on the server is created to get
* the servers current time.
*
* Returns an error message. NULL return means the lock was obtained.
*
* 12/6/91 Added the parameter "file_locked". Before this parameter
* was added, the calling procedure would have to wait for file_lock()
* to return before it sets the flag. If the user interrupted "make"
* between the time the lock was acquired and the time file_lock()
* returns, make wouldn't know that the file has been locked, and therefore
* it wouldn' remove the lock. Setting the flag right after locking the file
* makes this window much smaller.
*/
int
file_lock(char *name, char *lockname, int *file_locked, int timeout)
{
int counter = 0;
static char msg[MAXPATHLEN+1];
int printed_warning = 0;
int r;
struct stat statb;
sigset_t newset;
sigset_t oldset;
*file_locked = 0;
if (timeout <= 0) {
timeout = 120;
}
for (;;) {
BLOCK_INTERUPTS;
r = symlink(name, lockname);
if (r == 0) {
*file_locked = 1;
UNBLOCK_INTERUPTS;
return 0; /* success */
}
UNBLOCK_INTERUPTS;
if (errno != EEXIST) {
file_lock_error(msg, name, (char *)"symlink(%s, %s)",
(int) name, (int) lockname);
fprintf(stderr, "%s", msg);
return errno;
}
counter = 0;
for (;;) {
sleep(1);
r = lstat(lockname, &statb);
if (r == -1) {
/*
* The lock must have just gone away - try
* again.
*/
break;
}
if ((counter > 5) && (!printed_warning)) {
/* Print waiting message after 5 secs */
(void) getcwd(msg, MAXPATHLEN);
fprintf(stderr,
gettext("file_lock: file %s is already locked.\n"),
name);
fprintf(stderr,
gettext("file_lock: will periodically check the lockfile %s for two minutes.\n"),
lockname);
fprintf(stderr,
gettext("Current working directory %s\n"),
msg);
printed_warning = 1;
}
if (++counter > timeout ) {
/*
* Waited enough - return an error..
*/
return EEXIST;
}
}
}
/* NOTREACHED */
}
/*
* Format a message telling why the lock could not be created.
*/
static void
file_lock_error(char *msg, char *file, char *str, int arg1, int arg2)
{
int len;
sprintf(msg, gettext("Could not lock file `%s'; "), file);
len = strlen(msg);
sprintf(&msg[len], str, arg1, arg2);
strcat(msg, gettext(" failed - "));
if (errno < sys_nerr) {
strcat(msg, strerror(errno));
} else {
len = strlen(msg);
sprintf(&msg[len], "errno %d", errno);
}
}

46
lib/vroot/lstat.cc Normal file
View file

@ -0,0 +1,46 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1998 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/stat.h>
extern int lstat(const char *path, struct stat *buf);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int lstat_thunk(char *path)
{
vroot_result= lstat(path, vroot_args.lstat.buffer);
return(vroot_result == 0);
}
int lstat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.lstat.buffer= buffer;
translate_with_thunk(path, lstat_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

46
lib/vroot/mkdir.cc Normal file
View file

@ -0,0 +1,46 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/stat.h>
extern int mkdir(const char *path, mode_t mode);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int mkdir_thunk(char *path)
{
vroot_result= mkdir(path, vroot_args.mkdir.mode);
return(vroot_result == 0);
}
int mkdir_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.mkdir.mode= mode;
translate_with_thunk(path, mkdir_thunk, vroot_path, vroot_vroot, rw_write);
return(vroot_result);
}

47
lib/vroot/mount.cc Normal file
View file

@ -0,0 +1,47 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1995 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/mount.h>
extern int mount(const char *spec, const char *dir, int mflag, ...);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int mount_thunk(char *path)
{
vroot_result= mount(path, vroot_args.mount.name, vroot_args.mount.mode);
return(vroot_result == 0);
}
int mount_vroot(char *target, char *name, int mode, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.mount.name= name;
vroot_args.mount.mode= mode;
translate_with_thunk(target, mount_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

49
lib/vroot/open.cc Normal file
View file

@ -0,0 +1,49 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
extern int open(const char *path, int oflag, ...);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int open_thunk(char *path)
{
vroot_result= open(path, vroot_args.open.flags, vroot_args.open.mode);
return(vroot_result >= 0);
}
int open_vroot(char *path, int flags, int mode, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.open.flags= flags;
vroot_args.open.mode= mode;
translate_with_thunk(path, open_thunk, vroot_path, vroot_vroot,
((flags & (O_CREAT|O_APPEND)) != 0) ? rw_write : rw_read);
return(vroot_result);
}

46
lib/vroot/readlink.cc Normal file
View file

@ -0,0 +1,46 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
extern int readlink(const char *path, void *buf, size_t bufsiz);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int readlink_thunk(char *path)
{
vroot_result= readlink(path, vroot_args.readlink.buffer, vroot_args.readlink.buffer_size);
return(vroot_result >= 0);
}
int readlink_vroot(char *path, char *buffer, int buffer_size, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.readlink.buffer= buffer;
vroot_args.readlink.buffer_size= buffer_size;
translate_with_thunk(path, readlink_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

333
lib/vroot/report.cc Normal file
View file

@ -0,0 +1,333 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <unistd.h>
#include <libintl.h>
#include <vroot/report.h>
#include <vroot/vroot.h>
#include <mk/defs.h> /* for tmpdir */
static FILE *report_file;
static FILE *command_output_fp;
static char *target_being_reported_for;
static char *search_dir;
static char command_output_tmpfile[30];
static int is_path = 0;
static char sfile[MAXPATHLEN];
extern "C" {
static void (*warning_ptr) (char *, ...) = (void (*) (char *, ...)) NULL;
}
FILE *
get_report_file(void)
{
return(report_file);
}
char *
get_target_being_reported_for(void)
{
return(target_being_reported_for);
}
extern "C" {
static void
close_report_file(void)
{
(void)fputs("\n", report_file);
(void)fclose(report_file);
}
} // extern "C"
static void
clean_up(FILE *nse_depinfo_fp, FILE *merge_fp, char *nse_depinfo_file, char *merge_file, int unlinkf)
{
fclose(nse_depinfo_fp);
fclose(merge_fp);
fclose(command_output_fp);
unlink(command_output_tmpfile);
if (unlinkf)
unlink(merge_file);
else
rename(merge_file, nse_depinfo_file);
}
/*
* Update the file, if necessary. We don't want to rewrite
* the file if we don't have to because we don't want the time of the file
* to change in that case.
*/
extern "C" {
static void
close_file(void)
{
char line[MAXPATHLEN+2];
char buf[MAXPATHLEN+2];
FILE *nse_depinfo_fp;
FILE *merge_fp;
char nse_depinfo_file[MAXPATHLEN];
char merge_file[MAXPATHLEN];
char lock_file[MAXPATHLEN];
int err;
int len;
int changed = 0;
int file_locked;
fprintf(command_output_fp, "\n");
fclose(command_output_fp);
if ((command_output_fp = fopen(command_output_tmpfile, "r")) == NULL) {
return;
}
sprintf(nse_depinfo_file, "%s/%s", search_dir, NSE_DEPINFO);
sprintf(merge_file, "%s/.tmp%s.%d", search_dir, NSE_DEPINFO, getpid());
sprintf(lock_file, "%s/%s", search_dir, NSE_DEPINFO_LOCK);
err = file_lock(nse_depinfo_file, lock_file, &file_locked, 0);
if (err) {
if (warning_ptr != (void (*) (char *, ...)) NULL) {
(*warning_ptr)(gettext("Couldn't write to %s"), nse_depinfo_file);
}
unlink(command_output_tmpfile);
return;
}
/* If .nse_depinfo file doesn't exist */
if ((nse_depinfo_fp = fopen(nse_depinfo_file, "r+")) == NULL) {
if (is_path) {
if ((nse_depinfo_fp =
fopen(nse_depinfo_file, "w")) == NULL) {
fprintf(stderr, gettext("Cannot open `%s' for writing\n"),
nse_depinfo_file);
unlink(command_output_tmpfile);
unlink(lock_file);
return;
}
while (fgets(line, MAXPATHLEN+2, command_output_fp)
!= NULL) {
fprintf(nse_depinfo_fp, "%s", line);
}
fclose(command_output_fp);
}
fclose(nse_depinfo_fp);
if (file_locked) {
unlink(lock_file);
}
unlink(command_output_tmpfile);
return;
}
if ((merge_fp = fopen(merge_file, "w")) == NULL) {
fprintf(stderr, gettext("Cannot open %s for writing\n"), merge_file);
if (file_locked) {
unlink(lock_file);
}
unlink(command_output_tmpfile);
return;
}
len = strlen(sfile);
while (fgets(line, MAXPATHLEN+2, nse_depinfo_fp) != NULL) {
if (strncmp(line, sfile, len) == 0 && line[len] == ':') {
while (fgets(buf, MAXPATHLEN+2, command_output_fp)
!= NULL) {
if (is_path) {
fprintf(merge_fp, "%s", buf);
if (strcmp(line, buf)) {
/* changed */
changed = 1;
}
}
if (buf[strlen(buf)-1] == '\n') {
break;
}
}
if (changed || !is_path) {
while (fgets(line, MAXPATHLEN, nse_depinfo_fp)
!= NULL) {
fputs(line, merge_fp);
}
clean_up(nse_depinfo_fp, merge_fp,
nse_depinfo_file, merge_file, 0);
} else {
clean_up(nse_depinfo_fp, merge_fp,
nse_depinfo_file, merge_file, 1);
}
if (file_locked) {
unlink(lock_file);
}
unlink(command_output_tmpfile);
return;
} /* entry found */
fputs(line, merge_fp);
}
/* Entry never found. Add it if there is a search path */
if (is_path) {
while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) {
fprintf(nse_depinfo_fp, "%s", line);
}
}
clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 1);
if (file_locked) {
unlink(lock_file);
}
}
} // extern "C"
static void
report_dep(char *iflag, char *filename)
{
if (command_output_fp == NULL) {
sprintf(command_output_tmpfile,
"%s/%s.%d.XXXXXX", tmpdir, NSE_DEPINFO, getpid());
int fd = mkstemp(command_output_tmpfile);
if ((fd < 0) || (command_output_fp = fdopen(fd, "w")) == NULL) {
return;
}
if ((search_dir = getenv("NSE_DEP")) == NULL) {
return;
}
atexit(close_file);
strcpy(sfile, filename);
if (iflag == NULL || *iflag == '\0') {
return;
}
fprintf(command_output_fp, "%s:", sfile);
}
fprintf(command_output_fp, " ");
fprintf(command_output_fp, iflag);
if (iflag != NULL) {
is_path = 1;
}
}
void
report_libdep(char *lib, char *flag)
{
char *ptr;
char filename[MAXPATHLEN];
char *p;
if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
return;
}
ptr = strchr(p, ' ');
if(ptr) {
sprintf(filename, "%s-%s", ptr+1, flag);
is_path = 1;
report_dep(lib, filename);
}
}
void
report_search_path(char *iflag)
{
char curdir[MAXPATHLEN];
char *sdir;
char *newiflag;
char filename[MAXPATHLEN];
char *p, *ptr;
if ((sdir = getenv("NSE_DEP")) == NULL) {
return;
}
if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
return;
}
ptr = strchr(p, ' ');
if( ! ptr ) {
return;
}
sprintf(filename, "%s-CPP", ptr+1);
getcwd(curdir, sizeof(curdir));
if (strcmp(curdir, sdir) != 0 && strlen(iflag) > 2 &&
iflag[2] != '/') {
/* Makefile must have had an "cd xx; cc ..." */
/* Modify the -I path to be relative to the cd */
newiflag = (char *)malloc(strlen(iflag) + strlen(curdir) + 2);
sprintf(newiflag, "-%c%s/%s", iflag[1], curdir, &iflag[2]);
report_dep(newiflag, filename);
} else {
report_dep(iflag, filename);
}
}
void
report_dependency(const char *name)
{
register char *filename;
char buffer[MAXPATHLEN+1];
register char *p;
register char *p2;
char nse_depinfo_file[MAXPATHLEN];
if (report_file == NULL) {
if ((filename= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
report_file = (FILE *)-1;
return;
}
if (strlen(filename) == 0) {
report_file = (FILE *)-1;
return;
}
(void)strcpy(buffer, name);
name = buffer;
p = strchr(filename, ' ');
if(p) {
*p= 0;
} else {
report_file = (FILE *)-1;
return;
}
if ((report_file= fopen(filename, "a")) == NULL) {
if ((report_file= fopen(filename, "w")) == NULL) {
report_file= (FILE *)-1;
return;
}
}
atexit(close_report_file);
if ((p2= strchr(p+1, ' ')) != NULL)
*p2= 0;
target_being_reported_for= (char *)malloc((unsigned)(strlen(p+1)+1));
(void)strcpy(target_being_reported_for, p+1);
(void)fputs(p+1, report_file);
(void)fputs(":", report_file);
*p= ' ';
if (p2 != NULL)
*p2= ' ';
}
if (report_file == (FILE *)-1)
return;
(void)fputs(name, report_file);
(void)fputs(" ", report_file);
}

44
lib/vroot/rmdir.cc Normal file
View file

@ -0,0 +1,44 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
extern int rmdir(const char *path);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int rmdir_thunk(char *path)
{
vroot_result= rmdir(path);
return(vroot_result == 0);
}
int rmdir_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
{
translate_with_thunk(path, rmdir_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

61
lib/vroot/setenv.cc Normal file
View file

@ -0,0 +1,61 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1994 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
extern char **environ;
static short setenv_made_new_vector= 0;
char *setenv(char *name, char *value)
{ char *p= NULL, **q;
int length= 0, vl;
if ((p= getenv(name)) == NULL) { /* Allocate new vector */
for (q= environ; *q != NULL; q++, length++);
q= (char **)malloc((unsigned)(sizeof(char *)*(length+2)));
memcpy(((char *)q)+sizeof(char *), (char *)environ, sizeof(char *)*(length+1));
if (setenv_made_new_vector++)
free((char *)environ);
length= strlen(name);
environ= q;}
else { /* Find old slot */
length= strlen(name);
for (q= environ; *q != NULL; q++)
if (!strncmp(*q, name, length))
break;};
vl= strlen(value);
if (!p || (length+vl+1 > strlen(p)))
*q= p= (char *) malloc((unsigned)(length+vl+2));
else
p= *q;
(void)strcpy(p, name); p+= length;
*p++= '=';
(void)strcpy(p, value);
return(value);
}

46
lib/vroot/stat.cc Normal file
View file

@ -0,0 +1,46 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1998 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/stat.h>
extern int stat(const char *path, struct stat *buf);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int stat_thunk(char *path)
{
vroot_result= stat(path, vroot_args.stat.buffer);
return(vroot_result == 0);
}
int stat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.stat.buffer= buffer;
translate_with_thunk(path, stat_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

45
lib/vroot/truncate.cc Normal file
View file

@ -0,0 +1,45 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
extern int truncate(const char *path, off_t length);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int truncate_thunk(char *path)
{
vroot_result= truncate(path, vroot_args.truncate.length);
return(vroot_result == 0);
}
int truncate_vroot(char *path, int length, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.truncate.length= length;
translate_with_thunk(path, truncate_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

44
lib/vroot/unlink.cc Normal file
View file

@ -0,0 +1,44 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
extern int unlink(const char *path);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int unlink_thunk(char *path)
{
vroot_result= unlink(path);
return(vroot_result == 0);
}
int unlink_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
{
translate_with_thunk(path, unlink_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

46
lib/vroot/utimes.cc Normal file
View file

@ -0,0 +1,46 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/time.h>
extern int utimes(char *file, struct timeval *tvp);
#include <vroot/vroot.h>
#include <vroot/args.h>
static int utimes_thunk(char *path)
{
vroot_result= utimes(path, vroot_args.utimes.time);
return(vroot_result == 0);
}
int utimes_vroot(char *path, struct timeval *time, pathpt vroot_path, pathpt vroot_vroot)
{
vroot_args.utimes.time= time;
translate_with_thunk(path, utimes_thunk, vroot_path, vroot_vroot, rw_read);
return(vroot_result);
}

338
lib/vroot/vroot.cc Normal file
View file

@ -0,0 +1,338 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdlib.h>
#include <string.h>
#include <vroot/vroot.h>
#include <vroot/args.h>
#include <string.h>
#include <sys/param.h>
#include <sys/file.h>
typedef struct {
short init;
pathpt vector;
const char *env_var;
} vroot_patht;
typedef struct {
vroot_patht vroot;
vroot_patht path;
char full_path[MAXPATHLEN+1];
char *vroot_start;
char *path_start;
char *filename_start;
int scan_vroot_first;
int cpp_style_path;
} vroot_datat, *vroot_datapt;
static vroot_datat vroot_data= {
{ 0, NULL, "VIRTUAL_ROOT"},
{ 0, NULL, "PATH"},
"", NULL, NULL, NULL, 0, 1};
void
add_dir_to_path(const char *path, register pathpt *pointer, register int position)
{
register int size= 0;
register int length;
register char *name;
register pathcellpt p;
pathpt new_path;
if (*pointer != NULL) {
for (p= &((*pointer)[0]); p->path != NULL; p++, size++);
if (position < 0)
position= size;}
else
if (position < 0)
position= 0;
if (position >= size) {
new_path= (pathpt)calloc((unsigned)(position+2), sizeof(pathcellt));
if (*pointer != NULL) {
memcpy((char *)new_path,(char *)(*pointer), size*sizeof(pathcellt));
free((char *)(*pointer));};
*pointer= new_path;};
length= strlen(path);
name= (char *)malloc((unsigned)(length+1));
(void)strcpy(name, path);
if ((*pointer)[position].path != NULL)
free((*pointer)[position].path);
(*pointer)[position].path= name;
(*pointer)[position].length= length;
}
pathpt
parse_path_string(register char *string, register int remove_slash)
{
register char *p;
pathpt result= NULL;
if (string != NULL)
for (; 1; string= p+1) {
if (p= strchr(string, ':')) *p= 0;
if ((remove_slash == 1) && !strcmp(string, "/"))
add_dir_to_path("", &result, -1);
else
add_dir_to_path(string, &result, -1);
if (p) *p= ':';
else return(result);};
return((pathpt)NULL);
}
const char *
get_vroot_name(void)
{
return(vroot_data.vroot.env_var);
}
const char *
get_path_name(void)
{
return(vroot_data.path.env_var);
}
void
flush_path_cache(void)
{
vroot_data.path.init= 0;
}
void
flush_vroot_cache(void)
{
vroot_data.vroot.init= 0;
}
void
scan_path_first(void)
{
vroot_data.scan_vroot_first= 0;
}
void
scan_vroot_first(void)
{
vroot_data.scan_vroot_first= 1;
}
void
set_path_style(int style)
{
vroot_data.cpp_style_path= style;
}
char *
get_vroot_path(register char **vroot, register char **path, register char **filename)
{
if (vroot != NULL) {
if ((*vroot= vroot_data.vroot_start) == NULL)
if ((*vroot= vroot_data.path_start) == NULL)
*vroot= vroot_data.filename_start;};
if (path != NULL) {
if ((*path= vroot_data.path_start) == NULL)
*path= vroot_data.filename_start;};
if (filename != NULL)
*filename= vroot_data.filename_start;
return(vroot_data.full_path);
}
void
translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw)
{
register pathcellt *vp;
pathcellt *pp;
register pathcellt *pp1;
register char *p;
int flags[256];
/* Setup path to use */
if (rw == rw_write)
pp1= NULL; /* Do not use path when writing */
else {
if (path_vector == VROOT_DEFAULT) {
if (!vroot_data.path.init) {
vroot_data.path.init= 1;
vroot_data.path.vector= parse_path_string(getenv(vroot_data.path.env_var), 0);};
path_vector= vroot_data.path.vector;};
pp1= path_vector == NULL ? NULL : &(path_vector)[0];};
/* Setup vroot to use */
if (vroot_vector == VROOT_DEFAULT) {
if (!vroot_data.vroot.init) {
vroot_data.vroot.init= 1;
vroot_data.vroot.vector= parse_path_string(getenv(vroot_data.vroot.env_var), 1);};
vroot_vector= vroot_data.vroot.vector;};
vp= vroot_vector == NULL ? NULL : &(vroot_vector)[0];
/* Setup to remember pieces */
vroot_data.vroot_start= NULL;
vroot_data.path_start= NULL;
vroot_data.filename_start= NULL;
int flen = strlen(filename);
if(flen >= MAXPATHLEN) {
errno = ENAMETOOLONG;
return;
}
switch ((vp ?1:0) + (pp1 ? 2:0)) {
case 0: /* No path. No vroot. */
use_name:
(void)strcpy(vroot_data.full_path, filename);
vroot_data.filename_start= vroot_data.full_path;
(void)(*thunk)(vroot_data.full_path);
return;
case 1: /* No path. Vroot */
if (filename[0] != '/') goto use_name;
for (; vp->path != NULL; vp++) {
if((1 + flen + vp->length) >= MAXPATHLEN) {
errno = ENAMETOOLONG;
continue;
}
p= vroot_data.full_path;
(void)strcpy(vroot_data.vroot_start= p, vp->path);
p+= vp->length;
(void)strcpy(vroot_data.filename_start= p, filename);
if ((*thunk)(vroot_data.full_path)) return;};
(void)strcpy(vroot_data.full_path, filename);
return;
case 2: /* Path. No vroot. */
if (vroot_data.cpp_style_path) {
if (filename[0] == '/') goto use_name;
} else {
if (strchr(filename, '/') != NULL) goto use_name;
};
for (; pp1->path != NULL; pp1++) {
p= vroot_data.full_path;
if((1 + flen + pp1->length) >= MAXPATHLEN) {
errno = ENAMETOOLONG;
continue;
}
if (vroot_data.cpp_style_path) {
(void)strcpy(vroot_data.path_start= p, pp1->path);
p+= pp1->length;
*p++= '/';
} else {
if (pp1->length != 0) {
(void)strcpy(vroot_data.path_start= p,
pp1->path);
p+= pp1->length;
*p++= '/';
};
};
(void)strcpy(vroot_data.filename_start= p, filename);
if ((*thunk)(vroot_data.full_path)) return;};
(void)strcpy(vroot_data.full_path, filename);
return;
case 3: { /* Path. Vroot. */
int *rel_path, path_len= 1;
if (vroot_data.scan_vroot_first == 0) {
for (pp= pp1; pp->path != NULL; pp++) path_len++;
rel_path= flags;
for (path_len-= 2; path_len >= 0; path_len--) rel_path[path_len]= 0;
for (; vp->path != NULL; vp++)
for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++) {
int len = 0;
if (rel_path[path_len] == 1) continue;
if (pp->path[0] != '/') rel_path[path_len]= 1;
p= vroot_data.full_path;
if ((filename[0] == '/') || (pp->path[0] == '/')) {
if(vp->length >= MAXPATHLEN) {
errno = ENAMETOOLONG;
continue;
}
(void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length;
len += vp->length;
};
if (vroot_data.cpp_style_path) {
if (filename[0] != '/') {
if(1 + len + pp->length >= MAXPATHLEN) {
errno = ENAMETOOLONG;
continue;
}
(void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
*p++= '/';
len += 1 + pp->length;
};
} else {
if (strchr(filename, '/') == NULL) {
if (pp->length != 0) {
if(1 + len + pp->length >= MAXPATHLEN) {
errno = ENAMETOOLONG;
continue;
}
(void)strcpy(vroot_data.path_start= p,
pp->path);
p+= pp->length;
*p++= '/';
len += 1 + pp->length;
}
}
};
(void)strcpy(vroot_data.filename_start= p, filename);
if ((*thunk)(vroot_data.full_path)) return;};}
else { pathcellt *vp1= vp;
for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++)
for (vp= vp1; vp->path != NULL; vp++) {
int len = 0;
p= vroot_data.full_path;
if ((filename[0] == '/') || (pp->path[0] == '/')) {
if(vp->length >= MAXPATHLEN) {
errno = ENAMETOOLONG;
continue;
}
(void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length;
len += vp->length;
}
if (vroot_data.cpp_style_path) {
if (filename[0] != '/') {
if(1 + len + pp->length >= MAXPATHLEN) {
errno = ENAMETOOLONG;
continue;
}
(void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
*p++= '/';
len += 1 + pp->length;
}
} else {
if (strchr(filename, '/') == NULL) {
if(1 + len + pp->length >= MAXPATHLEN) {
errno = ENAMETOOLONG;
continue;
}
(void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
*p++= '/';
len += 1 + pp->length;
}
}
(void)strcpy(vroot_data.filename_start= p, filename);
if ((*thunk)(vroot_data.full_path)) return;};};
(void)strcpy(vroot_data.full_path, filename);
return;};};
}

2788
man/man1/make.1 Normal file

File diff suppressed because it is too large Load diff