diff options
| author | Igor Pashev <igor.pashev@nexenta.com> | 2012-06-29 14:36:07 +0400 | 
|---|---|---|
| committer | Igor Pashev <igor.pashev@nexenta.com> | 2012-06-29 14:36:07 +0400 | 
| commit | e0463df9c3d2ee6155221cc443c571d5da47098a (patch) | |
| tree | 5c6b99e64c1b65d986e2722728c74f202a578be6 /usr/src/make_src/Make/lib | |
| download | sunmake-orig.tar.gz | |
Initial import of DevPro make sourcesorig
Downloaded from http://dlc.sun.com/osol/devpro/downloads/current/
Licensed under CDDL http://www.opensource.org/licenses/CDDL-1.0
Diffstat (limited to 'usr/src/make_src/Make/lib')
56 files changed, 7751 insertions, 0 deletions
| diff --git a/usr/src/make_src/Make/lib/Lib.mk b/usr/src/make_src/Make/lib/Lib.mk new file mode 100644 index 0000000..2bf2147 --- /dev/null +++ b/usr/src/make_src/Make/lib/Lib.mk @@ -0,0 +1,67 @@ +# +# 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 2001 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Lib.mk 1.13 06/12/12 +# + +# Definitions of the libraries supplied by make/dmake. +# You must correctly define TOP before including this file! + +MAKE_TOP	= $(TOP)/Make + +LIBBSD_DIR	= $(MAKE_TOP)/lib/bsd +LIBBSD		= $(LIBBSD_DIR)/$(VARIANT)/libbsd.a + +LIBDMRXM_DIR	= $(MAKE_TOP)/lib/dmrxm +LIBDMRXM	= $(LIBDMRXM_DIR)/$(VARIANT)/libdmrxm.a + +LIBDMRXS_DIR	= $(MAKE_TOP)/lib/dmrxs +LIBDMRXS	= $(LIBDMRXS_DIR)/$(VARIANT)/libdmrxs.a + +LIBMAKESTATE_DIR = $(MAKE_TOP)/lib/makestate +LIBMAKESTATE	= $(LIBMAKESTATE_DIR)/$(VARIANT)/libmakestate.a + +LIBMKSDMSI18N_DIR = $(MAKE_TOP)/lib/mksdmsi18n +LIBMKSDMSI18N	= $(LIBMKSDMSI18N_DIR)/$(VARIANT)/libmksdmsi18n.a + +LIBMKSH_DIR	= $(MAKE_TOP)/lib/mksh +LIBMKSH		= $(LIBMKSH_DIR)/$(VARIANT)/libmksh.a + +LIBVROOT_DIR	= $(MAKE_TOP)/lib/vroot +LIBVROOT	= $(LIBVROOT_DIR)/$(VARIANT)/libvroot.a + +LIBDM_DIR	= $(MAKE_TOP)/lib/dm +LIBDM		= $(LIBDM_DIR)/$(VARIANT)/libdm.a + +LIBDMCONF_DIR	= $(MAKE_TOP)/lib/dmconf +LIBDMCONF	= $(LIBDMCONF_DIR)/$(VARIANT)/libdmconf.a + +LIBDMRC_DIR	= $(MAKE_TOP)/lib/dmrc +LIBDMRC		= $(LIBDMRC_DIR)/$(VARIANT)/libdmrc.a + +LIBDMTHREAD_DIR	= $(MAKE_TOP)/lib/dmthread +LIBDMTHREAD	= $(LIBDMTHREAD_DIR)/$(VARIANT)/libdmthread.a + +LIBRX_DIR	= $(MAKE_TOP)/lib/rx +LIBRX		= $(LIBRX_DIR)/$(VARIANT)/librx.a + diff --git a/usr/src/make_src/Make/lib/Makefile b/usr/src/make_src/Make/lib/Makefile new file mode 100644 index 0000000..0e0d489 --- /dev/null +++ b/usr/src/make_src/Make/lib/Makefile @@ -0,0 +1,39 @@ +# +# 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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.8 06/12/12 +# +# @(#)Makefile	1.4	96/03/16 SMI + +TOP =	../.. + +SUBDIRS =	\ +		makestate \ +		bsd \ +		dmrxm \ +		dmrxs \ +		mksdmsi18n \ +		mksh \ +		vroot + +include $(TOP)/rules/recurse.mk diff --git a/usr/src/make_src/Make/lib/bsd/Makefile b/usr/src/make_src/Make/lib/bsd/Makefile new file mode 100644 index 0000000..fd663cd --- /dev/null +++ b/usr/src/make_src/Make/lib/bsd/Makefile @@ -0,0 +1,29 @@ +# +# 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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.5 06/12/12 +# + +TOP =		../../.. +include $(TOP)/rules/variant.mk +include $(TOP)/rules/derived.mk diff --git a/usr/src/make_src/Make/lib/bsd/src/Makefile b/usr/src/make_src/Make/lib/bsd/src/Makefile new file mode 100644 index 0000000..299c46d --- /dev/null +++ b/usr/src/make_src/Make/lib/bsd/src/Makefile @@ -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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.3 06/12/12 +# + +# Generic makefile for use in src directories.  Knows how to make common things +# in the right $(VARIANT) directory. + +include $(TOP)/rules/variant.mk + +all :=		TARG = all  +install :=		TARG = install  +clean :=		TARG = clean  +test :=		TARG = test +l10n_install :=	TARG = l10n_install +i18n_install :=	TARG = i18n_install + +SRC =		../src +MFLAGS += 	SRC=$(SRC) + +# See $(TOP)/rules/master.mk for how these are built. +%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC +	@ if [ ! -d ../$(VARIANT) ]; then \ +		mkdir ../$(VARIANT) ; \ +	fi +	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@ + +FRC: diff --git a/usr/src/make_src/Make/lib/bsd/src/Variant.mk b/usr/src/make_src/Make/lib/bsd/src/Variant.mk new file mode 100644 index 0000000..650ee3e --- /dev/null +++ b/usr/src/make_src/Make/lib/bsd/src/Variant.mk @@ -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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Variant.mk 1.13 06/12/12 +# + +TOP =		 ../../../.. +include ${TOP}/rules/master.mk + +PKG_TOP =	 $(TOP)/Make +CPPFLAGS +=	 -I${PKG_TOP}/include +MSG_FILE = libbsd.msg +I18N_DIRS = $(SRC) + +CCSRCS =		bsd.cc +CSRCS = + +HDRS_DIR =	 ${PKG_TOP}/include/bsd + +.INIT: ${HDRS_DIR}/bsd.h + +LIBNAME =	 libbsd.a + +include ${TOP}/rules/lib.mk + diff --git a/usr/src/make_src/Make/lib/bsd/src/bsd.cc b/usr/src/make_src/Make/lib/bsd/src/bsd.cc new file mode 100644 index 0000000..c61bca2 --- /dev/null +++ b/usr/src/make_src/Make/lib/bsd/src/bsd.cc @@ -0,0 +1,182 @@ +/* + * 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. + */ +/* + * @(#)bsd.cc 1.6 06/12/12 + */ + +#pragma	ident	"@(#)bsd.cc	1.6	06/12/12" + +#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 SUN5_0 +#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 +#elif defined(linux) +  previous_handler = sigset (Signal, Handler); +#else +  previous_handler = signal (Signal, Handler); +#endif +  return previous_handler; +} + +extern void +bsd_signals (void) +{ +  static int                    initialized = 0; + +  if (initialized == 0) +    { +      initialized = 1; +#if !defined(SUN5_0) && !defined(linux) +#if defined(SIGHUP) +      (void) bsd_signal (SIGHUP, SIG_DFL); +#endif +#if defined(SIGINT) +      (void) bsd_signal (SIGINT, SIG_DFL); +#endif +#if defined(SIGQUIT) +      (void) bsd_signal (SIGQUIT, SIG_DFL); +#endif +#if defined(SIGILL) +      (void) bsd_signal (SIGILL, SIG_DFL); +#endif +#if defined(SIGTRAP) +      (void) bsd_signal (SIGTRAP, SIG_DFL); +#endif +#if defined(SIGIOT) +      (void) bsd_signal (SIGIOT, SIG_DFL); +#endif +#if defined(SIGABRT) +      (void) bsd_signal (SIGABRT, SIG_DFL); +#endif +#if defined(SIGEMT) +      (void) bsd_signal (SIGEMT, SIG_DFL); +#endif +#if defined(SIGFPE) +      (void) bsd_signal (SIGFPE, SIG_DFL); +#endif +#if defined(SIGBUS) +      (void) bsd_signal (SIGBUS, SIG_DFL); +#endif +#if defined(SIGSEGV) +      (void) bsd_signal (SIGSEGV, SIG_DFL); +#endif +#if defined(SIGSYS) +      (void) bsd_signal (SIGSYS, SIG_DFL); +#endif +#if defined(SIGPIPE) +      (void) bsd_signal (SIGPIPE, SIG_DFL); +#endif +#if defined(SIGALRM) +      (void) bsd_signal (SIGALRM, SIG_DFL); +#endif +#if defined(SIGTERM) +      (void) bsd_signal (SIGTERM, SIG_DFL); +#endif +#if defined(SIGUSR1) +      (void) bsd_signal (SIGUSR1, SIG_DFL); +#endif +#if defined(SIGUSR2) +      (void) bsd_signal (SIGUSR2, SIG_DFL); +#endif +#if defined(SIGCLD) +      (void) bsd_signal (SIGCLD, SIG_DFL); +#endif +#if defined(SIGCHLD) +      (void) bsd_signal (SIGCHLD, SIG_DFL); +#endif +#if defined(SIGPWR) +      (void) bsd_signal (SIGPWR, SIG_DFL); +#endif +#if defined(SIGWINCH) +      (void) bsd_signal (SIGWINCH, SIG_DFL); +#endif +#if defined(SIGURG) +      (void) bsd_signal (SIGURG, SIG_DFL); +#endif +#if defined(SIGIO) +      (void) bsd_signal (SIGIO, SIG_DFL); +#else +#if defined(SIGPOLL) +      (void) bsd_signal (SIGPOLL, SIG_DFL); +#endif +#endif +#if defined(SIGTSTP) +      (void) bsd_signal (SIGTSTP, SIG_DFL); +#endif +#if defined(SIGCONT) +      (void) bsd_signal (SIGCONT, SIG_DFL); +#endif +#if defined(SIGTTIN) +      (void) bsd_signal (SIGTTIN, SIG_DFL); +#endif +#if defined(SIGTTOU) +      (void) bsd_signal (SIGTTOU, SIG_DFL); +#endif +#if defined(SIGVTALRM) +      (void) bsd_signal (SIGVTALRM, SIG_DFL); +#endif +#if defined(SIGPROF) +      (void) bsd_signal (SIGPROF, SIG_DFL); +#endif +#if defined(SIGXCPU) +      (void) bsd_signal (SIGXCPU, SIG_DFL); +#endif +#if defined(SIGXFSZ) +      (void) bsd_signal (SIGXFSZ, SIG_DFL); +#endif +#endif +    } + +  return; +} diff --git a/usr/src/make_src/Make/lib/makestate/Makefile b/usr/src/make_src/Make/lib/makestate/Makefile new file mode 100644 index 0000000..9c1ddf0 --- /dev/null +++ b/usr/src/make_src/Make/lib/makestate/Makefile @@ -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 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.7 06/12/12 +# + +TOP =		../../.. +include $(TOP)/rules/variant.mk + +V9_VARIANT :sh= \ +if [ -x /usr/bin/isalist ] ; \ +then \ +    for f in `/usr/bin/isalist` ; \ +    do \ +	if [ "$f" = sparcv9 ] ; \ +	then \ +	    echo sparcv9 ; \ +	    break ; \ +	fi ; \ +	if [ "$f" = amd64 ] ; \ +	then \ +	    echo amd64-S2 ; \ +	    break ; \ +	fi ; \ +    done ; \ +fi + +include $(TOP)/rules/derived.mk diff --git a/usr/src/make_src/Make/lib/makestate/src/Makefile b/usr/src/make_src/Make/lib/makestate/src/Makefile new file mode 100644 index 0000000..21e239d --- /dev/null +++ b/usr/src/make_src/Make/lib/makestate/src/Makefile @@ -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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.5 06/12/12 +# +# @(#)Makefile	1.1	96/03/11 SMI + +# Generic makefile for use in src directories.  Knows how to make common things +# in the right $(VARIANT) directory. + +include $(TOP)/rules/variant.mk + +all :=		TARG = all  +install :=		TARG = install  +clean :=		TARG = clean  +test :=		TARG = test +l10n_install :=	TARG = l10n_install +i18n_install :=	TARG = i18n_install + +SRC =		../src +MFLAGS += 	SRC=$(SRC) + +# See $(TOP)/rules/master.mk for how these are built. +%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC +	@ if [ ! -d ../$(VARIANT) ]; then \ +		mkdir ../$(VARIANT) ; \ +	fi +	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@ + +FRC: diff --git a/usr/src/make_src/Make/lib/makestate/src/Variant.mk b/usr/src/make_src/Make/lib/makestate/src/Variant.mk new file mode 100644 index 0000000..26971d5 --- /dev/null +++ b/usr/src/make_src/Make/lib/makestate/src/Variant.mk @@ -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 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Variant.mk 1.12 06/12/12 +# + +TOP =		../../../.. + +%.o: $(SRC)/%.c +	$(COMPILE.c) $(OUTPUT_OPTION) $< + +include $(TOP)/rules/master.mk + +PKG_TOP =	$(TOP)/Make + +CSRCS =	\ +		ld_file.c \ +		lock.c + +LIBNAME =	libmakestate.a +DLIBNAME =	libmakestate.so.1 +MSG_FILE = libmakestate.msg +I18N_DIRS = $(SRC) + +CFLAGS += $(V9FLAGS) -KPIC -DTEXT_DOMAIN=\"SUNW_OST_OSLIB\" +CPPFLAGS= + +#include $(TOP)/Make/lib/Lib.mk +include $(TOP)/rules/lib.mk + +POUND_SIGN:sh=	echo \# +RELEASE=	5.11 +VERSION=	$(RELEASE_VER) +PATCHID=	$(VERSION) +DATE:sh		= date '+%B %Y' +RELEASE_DATE=	$(DATE) +PATCH_DATE=	$(RELEASE_DATE) +RELEASE_CM=	"@($(POUND_SIGN))RELEASE VERSION SunOS $(RELEASE) $(PATCHID) $(PATCH_DATE)" + +PROCESS_COMMENT=	mcs -a $(RELEASE_CM) +POST_PROCESS_SO=	$(PROCESS_COMMENT) $@ + +$(DLIBNAME) : $(LIBNAME) +	$(CC) $(V9FLAGS) -o $@ -dy -G -ztext -h $@ ld_file.o lock.o -lelf +	mcs -d $@ +	${POST_PROCESS_SO} + +all: $(DLIBNAME) + +install: all +	${INSTALL} -d ${DESTDIR}/usr/lib$(VAR_DIR) +	${RM} ${DESTDIR}/usr/lib$(VAR_DIR)/$(DLIBNAME) +	${INSTALL} $(DLIBNAME) ${DESTDIR}/usr/lib$(VAR_DIR) diff --git a/usr/src/make_src/Make/lib/makestate/src/ld_file.c b/usr/src/make_src/Make/lib/makestate/src/ld_file.c new file mode 100644 index 0000000..b80ea68 --- /dev/null +++ b/usr/src/make_src/Make/lib/makestate/src/ld_file.c @@ -0,0 +1,192 @@ +/* + * 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. + */ +/* + * @(#)ld_file.c 1.7 06/12/12 + */ +#pragma ident	"@(#)ld_file.c	1.7	06/12/12" + +#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() */ diff --git a/usr/src/make_src/Make/lib/makestate/src/lock.c b/usr/src/make_src/Make/lib/makestate/src/lock.c new file mode 100644 index 0000000..7646059 --- /dev/null +++ b/usr/src/make_src/Make/lib/makestate/src/lock.c @@ -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. + */ +/* + * @(#)lock.c 1.5 06/12/12 + */ + +#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 */ +} diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/Makefile b/usr/src/make_src/Make/lib/mksdmsi18n/Makefile new file mode 100644 index 0000000..c9d8161 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksdmsi18n/Makefile @@ -0,0 +1,30 @@ +# +# 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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.5 06/12/12 +# + +TOP		= ../../.. +include $(TOP)/rules/variant.mk +include $(TOP)/rules/derived.mk + diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/Makefile b/usr/src/make_src/Make/lib/mksdmsi18n/src/Makefile new file mode 100644 index 0000000..f27801b --- /dev/null +++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/Makefile @@ -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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.10 06/12/12 +# + +TOP =		../../../.. +include $(TOP)/rules/master.mk + +SUBDIRS =	lib +include $(TOP)/rules/recurse.mk +include $(SRC)/lib/version.mk + +PKG_TOP =	$(TOP)/Make +CPPFLAGS +=	-I$(PKG_TOP)/include + +CCSRCS =		libmksdmsi18n_init.cc + +LIBNAME =	libmksdmsi18n.a + +# +# Pass in the version number for the i18n message catalog. +# +libmksdmsi18n_init.o :=	CPPFLAGS += -DI18N_VERSION=$(VERSION) + +include $(TOP)/rules/lib.mk diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/Variant.mk b/usr/src/make_src/Make/lib/mksdmsi18n/src/Variant.mk new file mode 100644 index 0000000..1faef99 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/Variant.mk @@ -0,0 +1,52 @@ +# +# 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 1997 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Variant.mk 1.4 06/12/12 +# + +TOP =		../../../.. +include $(TOP)/rules/master.mk +#include $(TOP)/rules/dmake.mk + +#SUBDIRS =	$(SRC)/lib +#include $(TOP)/rules/recurse.mk + +CCSRCS = \ +		libmksdmsi18n_init.cc  + +CSRCS = + +include $(SRC)/lib/version.mk + +libmksdmsi18n_init.o := CPPFLAGS += -DI18N_VERSION=$(VERSION) + +#PKG_TOP =	$(TOP)/Make +#CPPFLAGS +=	-I$(PKG_TOP)/include + +LIBNAME =	libmksdmsi18n.a +MSG_FILE = libmksdmsi18n.msg +I18N_DIRS = $(SRC) + +include $(TOP)/Make/lib/Lib.mk +include $(TOP)/rules/lib.mk + diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/Makefile b/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/Makefile new file mode 100644 index 0000000..73399b1 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/Makefile @@ -0,0 +1,54 @@ +# +# 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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.7 06/12/12 +# + +include version.mk + +TOP		= ../../../../.. +PKG_TOP		= $(TOP)/Make +PKG_LIB_TOP	= $(PKG_TOP)/lib +I18N_LIBS	= bsd dmrxm dmrxs mksh vroot +I18N_DIRS	= $(I18N_LIBS:%=$(PKG_LIB_TOP)/%/src) +SRC		= . +APPPATH		= . +LIBNAME		= libmksdmsi18n +TEXTDOMAIN	= $(LIBNAME)_$(VERSION) +MSG_FILE	= $(TEXTDOMAIN).msg + +all clean: +install: catalogs .WAIT i18n_install + +# +# This is a hack until the top level makefiles for i18n/l10n message catalogs +# are better organized and written. +# This "catalogs" target was cp'ed from $(TOP)/rules/lib.mk +# +catalogs: +	$(GENMSG) -l $(SRC)/genmsg.project -o $(MSG_FILE) `find $(I18N_DIRS) \( -name '*.cc' -o -name '*.c' -o -name '*.y' \) -print | grep -v /SCCS/` +	rm -f *.cc.new + +include $(PKG_TOP)/prodver.mk +include $(TOP)/rules/i18n-install.mk + diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/version.mk b/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/version.mk new file mode 100644 index 0000000..aaad8d8 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/version.mk @@ -0,0 +1,30 @@ +# +# 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. +# +# @(#)version.mk 1.2 06/12/12 +# + +# A version number is needed to version the i18n catalog file + +VERSION = 1 + diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/libmksdmsi18n_init.cc b/usr/src/make_src/Make/lib/mksdmsi18n/src/libmksdmsi18n_init.cc new file mode 100644 index 0000000..e234125 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/libmksdmsi18n_init.cc @@ -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 1996 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * @(#)libmksdmsi18n_init.cc 1.5 06/12/12 + */ + +#pragma	ident	"@(#)libmksdmsi18n_init.cc	1.5	06/12/12" + +#include <avo/intl.h> +#include <stdio.h> +#include <stdlib.h> + +nl_catd libmksdmsi18n_catd; +  +/* + * Open the catalog file for libmksdmsi18n.  Users of this library must set + * NSLPATH first.  See avo_18n_init(). + */ +int +libmksdmsi18n_init() +{ +	char		name[20]; + +	if (getenv(NOCATGETS("NLSPATH")) == NULL) { +		fprintf(stderr, NOCATGETS("Internal error: Set NLSPATH before opening catalogue file\n")); +		return 1; +	} +	sprintf(name, NOCATGETS("libmksdmsi18n_%d"), I18N_VERSION); +	libmksdmsi18n_catd = catopen(name, NL_CAT_LOCALE); +	return 0; +} +  +/* + * Close the catalog file for libmksdmsi18n + */ +void +libmksdmsi18n_fini() +{ +	catclose(libmksdmsi18n_catd); +} + diff --git a/usr/src/make_src/Make/lib/mksh/Makefile b/usr/src/make_src/Make/lib/mksh/Makefile new file mode 100644 index 0000000..fd663cd --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/Makefile @@ -0,0 +1,29 @@ +# +# 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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.5 06/12/12 +# + +TOP =		../../.. +include $(TOP)/rules/variant.mk +include $(TOP)/rules/derived.mk diff --git a/usr/src/make_src/Make/lib/mksh/src/Makefile b/usr/src/make_src/Make/lib/mksh/src/Makefile new file mode 100644 index 0000000..ebed78f --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/Makefile @@ -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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.3 06/12/12 +# + +# Generic makefile for use in src directories.  Knows how to make common things +# in the right $(VARIANT) directory. + +#TOP =		../../../.. +include $(TOP)/rules/variant.mk + +all :=		TARG = all  +install :=		TARG = install  +clean :=		TARG = clean  +test :=		TARG = test +l10n_install :=	TARG = l10n_install +i18n_install :=	TARG = i18n_install + +SRC =		../src +MFLAGS += 	SRC=$(SRC) + +# See $(TOP)/rules/master.mk for how these are built. +%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC +	@ if [ ! -d ../$(VARIANT) ]; then \ +		mkdir ../$(VARIANT) ; \ +	fi +	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@ + +FRC: diff --git a/usr/src/make_src/Make/lib/mksh/src/Variant.mk b/usr/src/make_src/Make/lib/mksh/src/Variant.mk new file mode 100644 index 0000000..427ba54 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/Variant.mk @@ -0,0 +1,58 @@ +# +# 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. +# +# @(#)Variant.mk 1.19 06/12/12 +# + +TOP =		 ../../../.. +include $(TOP)/rules/master.mk +include $(TOP)/rules/dmake.mk + +PKG_TOP =	$(TOP)/Make +CPPFLAGS +=	-I$(PKG_TOP)/include + +CCSRCS =	\ +		dosys.cc \ +		globals.cc \ +		i18n.cc \ +		macro.cc \ +		misc.cc \ +		mksh.cc \ +		read.cc + +HDRS_DIR =	$(PKG_TOP)/include/mksh +HDRS_LIST =	$(HDRS_DIR)/defs.h \ +		$(CCSRCS:%.cc=$(HDRS_DIR)/%.h) \ +		$(CSRCS:%.c=$(HDRS_DIR)/%.h) + +.INIT: $(HDRS_LIST) + +LIBNAME =	libmksh.a +MSG_FILE = libmksh.msg +I18N_DIRS = $(SRC) + +#CPPFLAGS	+= -DTEAMWARE_MAKE_CMN -DDISTRIBUTED + +include $(TOP)/Make/lib/Lib.mk +include $(TOP)/rules/lib.mk + diff --git a/usr/src/make_src/Make/lib/mksh/src/dosys.cc b/usr/src/make_src/Make/lib/mksh/src/dosys.cc new file mode 100644 index 0000000..fc4306b --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/dosys.cc @@ -0,0 +1,851 @@ +/* + * 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. + */ +/* + * @(#)dosys.cc 1.38 06/12/12 + */ + +#pragma	ident	"@(#)dosys.cc	1.38	06/12/12" + +/* + *	dosys.cc + * + *	Execute one commandline + */ + +/* + * Included files + */ +#include <sys/wait.h>			/* WIFEXITED(status) */ +#include <avo/avo_alloca.h>		/* alloca() */ + +#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL) /* tolik */ +#	include <avo/strings.h>	/* AVO_STRDUP() */ +#if defined(DISTRIBUTED) +#	include <dm/Avo_CmdOutput.h> +#	include <rw/xdrstrea.h> +#endif +#endif + +#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 <mksdmsi18n/mksdmsi18n.h>	/* libmksdmsi18n_init() */ +#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() */ + +#if defined (HP_UX) || defined (linux) +#	include <sys/param.h> +#	include <wctype.h> +#	include <wchar.h> +#endif + +#if defined (linux) +#	define wslen(x) wcslen(x) +#	define wscpy(x,y) wcscpy(x,y) +#endif + +/* + * Defined macros + */ +#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */ +#define SEND_MTOOL_MSG(cmds) \ +	if (send_mtool_msgs) { \ +		cmds \ +	} +#else +#define SEND_MTOOL_MSG(cmds) +#endif + +/* + * 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); +#ifdef linux +// Workaround for NFS problem: even when all directories in 'path' +// exist, 'open' (file creation) fails with ENOENT. +	int nattempt = 0; +	while (res < 0 && (errno == ESTALE || errno == EAGAIN || errno == ENOENT)) { +		nattempt++; +		if(nattempt > 30) { +			break; +		} +		sleep(1); +#else +	if (res < 0 && (errno == ESTALE || errno == EAGAIN)) { +#endif +		/* 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) +{         +	long		descriptor_limit; +	int		i; + +#if defined (HP_UX) || defined (linux) +        /* +         *  HP-UX does not support the UL_GDESLIM command for ulimit(). +	 *  NOFILE == max num open files per process (from <sys/param.h>) +         */ +	descriptor_limit = NOFILE; +#else +	if ((descriptor_limit = ulimit(UL_GDESLIM)) < 0) { +		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 89, "ulimit() failed: %s"), errmsg(errno)); +	} +#endif +	for (i = 3; i < descriptor_limit; i++) { +		(void) close(i); +	} +	if ((i = my_open(stdout_file, +	         O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC, +	         S_IREAD | S_IWRITE)) < 0) { +		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 90, "Couldn't open standard out temp file `%s': %s"), +		      stdout_file, +		      errmsg(errno)); +	} else { +		if (dup2(i, 1) == -1) { +			fatal_mksh(NOCATGETS("*** Error: dup2(3, 1) failed: %s"), +				errmsg(errno)); +		} +		close(i); +	} +	if (stderr_file == NULL) { +		if (dup2(1, 2) == -1) { +			fatal_mksh(NOCATGETS("*** 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(catgets(libmksdmsi18n_catd, 1, 91, "Couldn't open standard error temp file `%s': %s"), +		      stderr_file, +		      errmsg(errno)); +	} else { +		if (dup2(i, 2) == -1) { +			fatal_mksh(NOCATGETS("*** Error: dup2(3, 2) failed: %s"), +				errmsg(errno)); +		} +		close(i); +	} +} + +/* + *	dosys_mksh(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 we abort when an error is seen? + *		call_make	Did command reference $(MAKE) ? + *		silent_error	Should error messages be suppressed for dmake? + *		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_mksh(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio) +{ +	register int		length = command->hash.length; +	register wchar_t	*p; +	register wchar_t	*q; +	register wchar_t	*cmd_string; +	struct stat		before; +	Doname			result; +	Boolean			working_on_targets_mksh = true; +	Wstring wcb(command); +	p = wcb.get_string(); +	cmd_string = p; + +	/* 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_mksh && +	    !call_make && +	    !always_exec) { +		return build_ok; +	} + +	/* Copy string to make it OK to write it. */ +	q = ALLOC_WC(length + 1); +	(void) wscpy(q, p); +	/* Write the state file iff this command uses make. */ +/* XXX - currently does not support recursive make's, $(MAKE)'s +	if (call_make && command_changed) { +		write_state_file(0, false); +	} +	(void) stat(make_state->string_mb, &before); + */ +	/* +	 * Run command directly if it contains no shell meta chars, +	 * else run it using the shell. +	 */ +	/* XXX - command->meta *may* not be set correctly */ +	if (await(ignore_error, +		  silent_error, +		  target, +		  cmd_string, +                  command->meta ? +	            doshell(q, ignore_error, redirect_out_err, stdout_file, stderr_file, nice_prio) : +	            doexec(q, ignore_error, redirect_out_err, stdout_file, stderr_file, vroot_path, nice_prio), +	          false, +	          NULL, +	          -1)) { + +#ifdef PRINT_EXIT_STATUS +		warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_ok.")); +#endif + +		result = build_ok; +	} else { + +#ifdef PRINT_EXIT_STATUS +		warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_failed.")); +#endif + +		result = build_failed; +	} +	retmem(q); + +/* XXX - currently does not support recursive make's, $(MAKE)'s +	if ((report_dependencies_level == 0) && +	    call_make) { +		make_state->stat.time = (time_t)file_no_time; +		(void)exists(make_state); +		if (before.st_mtime == make_state->stat.time) { +			return result; +		} +		makefile_type = reading_statefile; +		if (read_trace_level > 1) { +			trace_reader = true; +		} +		(void) read_simple_file(make_state, +					false, +					false, +					false, +					false, +					false, +					true); +		trace_reader = false; +	} + */ +	return result; +} + +/* + *	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, Boolean redirect_out_err, 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++] = NOCATGETS("nice"); +		(void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio); +		argv[argv_index++] = strdup(nice_prio_buf); +	} +	argv[argv_index++] = shellname; +#if defined(linux) +	if(0 == strcmp(shell->string_mb, (char*)NOCATGETS("/bin/sh"))) { +		argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce")); +	} else { +		argv[argv_index++] = (char*)NOCATGETS("-c"); +	} +#else +	argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce")); +#endif +	if ((length = wslen(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; +#if defined(linux) +		int mbl = strlen(mbs_buffer); +		if(mbl > 2) { +			if(mbs_buffer[mbl-1] == '\n' && mbs_buffer[mbl-2] == '\\') { +				mbs_buffer[mbl] = '\n'; +				mbs_buffer[mbl+1] = 0; +			} +		} +#endif +		argv[argv_index++] = strdup(mbs_buffer); +	} +	argv[argv_index] = NULL; +	(void) fflush(stdout); +	if ((childPid = fork()) == 0) { +		enable_interrupt((void (*) (int)) SIG_DFL); +		if (redirect_out_err) { +			redirect_io(stdout_file, stderr_file); +		} +#if 0 +		if (filter_stderr) { +			redirect_stderr(); +		} +#endif +		if (nice_prio != 0) { +			(void) execve(NOCATGETS("/usr/bin/nice"), argv, environ); +			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 92, "Could not load `/usr/bin/nice': %s"), +			      errmsg(errno)); +		} else { +			(void) execve(shell->string_mb, argv, environ); +			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 93, "Could not load Shell from `%s': %s"), +			      shell->string_mb, +			      errmsg(errno)); +		} +	} +	if (childPid  == -1) { +		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 94, "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 ? NOCATGETS("-c") : NOCATGETS("-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, Boolean redirect_out_err, 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 = wslen(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(NOCATGETS("/usr/bin/nice")); +		(void) sprintf(nice_prio_buf, NOCATGETS("-%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(catgets(libmksdmsi18n_catd, 1, 95, "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 = wslen(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 (redirect_out_err) { +			redirect_io(stdout_file, stderr_file); +		} +#if 0 +		if (filter_stderr) { +			redirect_stderr(); +		} +#endif +		(void) exec_vp(argv[1], argv, environ, ignore_error, vroot_path); +		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 96, "Cannot load command `%s': %s"), argv[1], errmsg(errno)); +	} +	if (childPid  == -1) { +		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 97, "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 + */ +#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */ +Boolean +await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, XDR *xdrs_p, int job_msg_id) +#else +Boolean +await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, void *xdrs_p, int job_msg_id) +#endif +{ +#ifdef SUN5_0 +        int                     status; +#else +#ifndef WEXITSTATUS +#define WEXITSTATUS(stat)       stat.w_T.w_Retcode +#endif +#ifndef WTERMSIG +#define WTERMSIG(stat)          stat.w_T.w_Termsig +#endif +#ifndef WCOREDUMP +#define WCOREDUMP(stat)         stat.w_T.w_Coredump +#endif +#if defined (HP_UX) || defined (linux) +	int			status; +#else +	union wait		status; +#endif +#endif +	char			*buffer; +	int			core_dumped; +	int			exit_status; +#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */ +	Avo_CmdOutput		*make_output_msg; +#endif +	FILE			*outfp; +	register pid_t		pid; +	struct stat		stat_buff; +	int			termination_signal; +	char			tmp_buf[MAXPATHLEN]; +#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */ +	RWCollectable		*xdr_msg; +#endif + +	while ((pid = wait(&status)) != running_pid) { +		if (pid == -1) { +			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 98, "wait() failed: %s"), errmsg(errno)); +		} +	} +	(void) fflush(stdout); +	(void) fflush(stderr); + +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +        if (status == 0) { + +#ifdef PRINT_EXIT_STATUS +		warning_mksh(NOCATGETS("I'm in await(), and status is 0.")); +#endif + +                return succeeded; +	} + +#ifdef PRINT_EXIT_STATUS +	warning_mksh(NOCATGETS("I'm in await(), and status is *NOT* 0.")); +#endif + +#else +        if (status.w_status == 0) { +                return succeeded; +	} +#endif + +        exit_status = WEXITSTATUS(status); + +#ifdef PRINT_EXIT_STATUS +	warning_mksh(NOCATGETS("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. +	 */ +	SEND_MTOOL_MSG( +		make_output_msg = new Avo_CmdOutput(); +		(void) sprintf(tmp_buf, "%d", job_msg_id); +		make_output_msg->appendOutput(AVO_STRDUP(tmp_buf)); +	); + +	tmp_buf[0] = (int) nul_char; +	if (!silent_error) { +		if (exit_status != 0) { +			(void) fprintf(stdout, +				       catgets(libmksdmsi18n_catd, 1, 103, "*** Error code %d"), +				       exit_status); +			SEND_MTOOL_MSG( +				(void) sprintf(&tmp_buf[strlen(tmp_buf)], +					       catgets(libmksdmsi18n_catd, 1, 104, "*** Error code %d"), +					       exit_status); +			); +		} else { +#if ! defined(SUN5_0) && ! defined(HP_UX) && ! defined(linux) +			if (termination_signal > NSIG) { +#endif +				(void) fprintf(stdout, +					       catgets(libmksdmsi18n_catd, 1, 105, "*** Signal %d"), +					       termination_signal); +				SEND_MTOOL_MSG( +					(void) sprintf(&tmp_buf[strlen(tmp_buf)], +						       catgets(libmksdmsi18n_catd, 1, 106, "*** Signal %d"), +						       termination_signal); +				); +#if ! defined(SUN5_0) && ! defined(HP_UX) && ! defined(linux) +			} else { +				(void) fprintf(stdout, +					       "*** %s", +					       sys_siglist[termination_signal]); +				SEND_MTOOL_MSG( +					(void) sprintf(&tmp_buf[strlen(tmp_buf)], +						       "*** %s", +						       sys_siglist[termination_signal]); +				); +			} +#endif +			if (core_dumped) { +				(void) fprintf(stdout, +					       catgets(libmksdmsi18n_catd, 1, 107, " - core dumped")); +				SEND_MTOOL_MSG( +					(void) sprintf(&tmp_buf[strlen(tmp_buf)], +						       catgets(libmksdmsi18n_catd, 1, 108, " - core dumped")); +				); +			} +		} +		if (ignore_error) { +			(void) fprintf(stdout, +				       catgets(libmksdmsi18n_catd, 1, 109, " (ignored)")); +			SEND_MTOOL_MSG( +				(void) sprintf(&tmp_buf[strlen(tmp_buf)], +					       catgets(libmksdmsi18n_catd, 1, 110, " (ignored)")); +			); +		} +		(void) fprintf(stdout, "\n"); +		(void) fflush(stdout); +		SEND_MTOOL_MSG( +			make_output_msg->appendOutput(AVO_STRDUP(tmp_buf)); +		); +	} +	SEND_MTOOL_MSG( +		xdr_msg = (RWCollectable*) make_output_msg; +		xdr(xdrs_p, xdr_msg); +		delete make_output_msg; +	); + +#ifdef PRINT_EXIT_STATUS +	warning_mksh(NOCATGETS("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(catgets(libmksdmsi18n_catd, 1, 111, "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(catgets(libmksdmsi18n_catd, 1, 112, "The command `%s' returned status `%d'"), +		      mbs_buffer, +		      WEXITSTATUS(status)); +	} +} + + diff --git a/usr/src/make_src/Make/lib/mksh/src/globals.cc b/usr/src/make_src/Make/lib/mksh/src/globals.cc new file mode 100644 index 0000000..2d36d24 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/globals.cc @@ -0,0 +1,140 @@ +/* + * 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 1.16 06/12/12 + */ + +#pragma	ident	"@(#)globals.cc	1.16	06/12/12" + +/* + *	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, +#ifdef SGE_SUPPORT +	space_char, +	tab_char, +#endif +	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 +#ifdef SUN5_0 +int		exit_status; +#endif +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; +#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR) +Boolean		out_err_same; +#endif +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 }; diff --git a/usr/src/make_src/Make/lib/mksh/src/i18n.cc b/usr/src/make_src/Make/lib/mksh/src/i18n.cc new file mode 100644 index 0000000..f12341e --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/i18n.cc @@ -0,0 +1,100 @@ +/* + * 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 1.3 06/12/12 + */ + +#pragma	ident	"@(#)i18n.cc	1.3	06/12/12" + +/* + *      i18n.cc + * + *      Deal with internationalization conversions + */ + +/* + * Included files + */ +#include <mksh/i18n.h> +#include <mksh/misc.h>		/* setup_char_semantics() */ +#if defined (linux) +#	include <wctype.h> +#	include <wchar.h> +#	define wschr(x,y) wcschr(x,y) +#endif + +/* + *	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 *) wschr(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); +	} +} + diff --git a/usr/src/make_src/Make/lib/mksh/src/libmksh.msg b/usr/src/make_src/Make/lib/mksh/src/libmksh.msg new file mode 100644 index 0000000..d1994aa --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/libmksh.msg @@ -0,0 +1,81 @@ + +$quote " + + +$set	1 +$ +$ 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 1996 Sun Microsystems, Inc. All rights reserved. +$ Use is subject to license terms. +$ +$ @(#)libmksh.msg 1.2 06/12/12 +$ +89	"ulimit() failed: %s" +90	"Couldn't open standard out temp file `%s': %s" +91	"Couldn't open standard error temp file `%s': %s" +92	"Could not load `/usr/bin/nice': %s" +93	"Could not load Shell from `%s': %s" +94	"fork failed: %s" +95	"Command `%s' has more than %d arguments" +96	"Cannot load command `%s': %s" +97	"fork failed: %s" +98	"wait() failed: %s" +99	"Could not open filter file for -X" +100	"Could not stat filter file for -X" +101	"\n**** Error: Directory %s Target %s:\n%s\n" +102	"**** Error: Directory %s Target %s\n" +103	"*** Error code %d" +104	"*** Error code %d" +105	"*** Signal %d" +106	"*** Signal %d" +107	" - core dumped" +108	" - core dumped" +109	" (ignored)" +110	" (ignored)" +111	"Could not run command `%s' for :sh transformation" +112	"The command `%s' returned status `%d'" +113	"Loop detected when expanding macro value `%s'" +114	"'$' at end of string `%s'" +115	"'$' at end of line" +116	"Unmatched `%c' in string `%s'" +117	"Premature EOF" +118	"Unmatched `%c' on line" +119	"Illegal macro reference `%s'" +120	"= missing from replacement macro reference" +121	"= missing from replacement macro reference" +122	"%% missing from replacement macro reference" +123	"%% missing from replacement macro reference" +124	"Too many %% in pattern" +125	"Conditional macro `%s' referenced on line %d" +126	"Out of memory" +127	"Error %d" +128	"mksh: Fatal error: " +129	"Current working directory %s\n" +131	"mksh: Fatal error in reader: " +133	"Current working directory %s\n" +134	"mksh: Warning: " +135	"Current working directory %s\n" +136	"Internal error. Unknown prop type %d" +137	"`cd %s' failed, and conversion of %s to automounter pathname also failed" +138	"`cd %s' and `cd %s' both failed" +139	"The following command caused the error:\n%s\n" +140	"Error reading `%s': Premature EOF" +141	"Error reading `%s': %s" diff --git a/usr/src/make_src/Make/lib/mksh/src/macro.cc b/usr/src/make_src/Make/lib/mksh/src/macro.cc new file mode 100644 index 0000000..43d7603 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/macro.cc @@ -0,0 +1,1414 @@ +/* + * 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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * @(#)macro.cc 1.22 06/12/12 + */ + +#pragma	ident	"@(#)macro.cc	1.22	06/12/12" + +/* + *	macro.cc + * + *	Handle expansion of make macros + */ + +/* + * Included files + */ +#include <mksh/dosys.h>		/* sh_command2string() */ +#include <mksh/i18n.h>		/* get_char_semantics_value() */ +#include <mksh/macro.h> +#include <mksh/misc.h>		/* retmem() */ +#include <mksh/read.h>		/* get_next_block_fn() */ +#include <mksdmsi18n/mksdmsi18n.h>	/* libmksdmsi18n_init() */ + +/* + * File table of contents + */ +static void	add_macro_to_global_list(Name macro_to_add); +#ifdef NSE +static void	expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd); +#else +static void	expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd); +#endif + +static void	init_arch_macros(void); +static void	init_mach_macros(void); +static Boolean	init_arch_done = false; +static Boolean	init_mach_done = false; + + +long env_alloc_num = 0; +long env_alloc_bytes = 0; + +/* + *	getvar(name) + * + *	Return expanded value of macro. + * + *	Return value: + *				The expanded value of the macro + * + *	Parameters: + *		name		The name of the macro we want the value for + * + *	Global variables used: + */ +Name +getvar(register Name name) +{ +	String_rec		destination; +	wchar_t			buffer[STRING_BUFFER_LENGTH]; +	register Name		result; + +	if ((name == host_arch) || (name == target_arch)) { +		if (!init_arch_done) { +			init_arch_done = true; +			init_arch_macros(); +		} +	} +	if ((name == host_mach) || (name == target_mach)) { +		if (!init_mach_done) { +			init_mach_done = true; +			init_mach_macros(); +		} +	} + +	INIT_STRING_FROM_STACK(destination, buffer); +	expand_value(maybe_append_prop(name, macro_prop)->body.macro.value, +		     &destination, +		     false); +	result = GETNAME(destination.buffer.start, FIND_LENGTH); +	if (destination.free_after_use) { +		retmem(destination.buffer.start); +	} +	return result; +} + +/* + *	expand_value(value, destination, cmd) + * + *	Recursively expands all macros in the string value. + *	destination is where the expanded value should be appended. + * + *	Parameters: + *		value		The value we are expanding + *		destination	Where to deposit the expansion + *		cmd		If we are evaluating a command line we + *				turn \ quoting off + * + *	Global variables used: + */ +void +expand_value(Name value, register String destination, Boolean cmd) +{ +	Source_rec		sourceb; +	register Source		source = &sourceb; +	register wchar_t	*source_p = NULL; +	register wchar_t	*source_end = NULL; +	wchar_t			*block_start = NULL; +	int			quote_seen = 0; + +	if (value == NULL) { +		/* +		 * Make sure to get a string allocated even if it +		 * will be empty. +		 */ +		MBSTOWCS(wcs_buffer, ""); +		append_string(wcs_buffer, destination, FIND_LENGTH); +		destination->text.end = destination->text.p; +		return; +	} +	if (!value->dollar) { +		/* +		 * If the value we are expanding does not contain +		 * any $, we don't have to parse it. +		 */ +		APPEND_NAME(value, +			destination, +			(int) value->hash.length +		); +		destination->text.end = destination->text.p; +		return; +	} + +	if (value->being_expanded) { +		fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 113, "Loop detected when expanding macro value `%s'"), +			     value->string_mb); +	} +	value->being_expanded = true; +	/* Setup the structure we read from */ +	Wstring vals(value); +	sourceb.string.text.p = sourceb.string.buffer.start = wsdup(vals.get_string()); +	sourceb.string.free_after_use = true; +	sourceb.string.text.end = +	  sourceb.string.buffer.end = +	    sourceb.string.text.p + value->hash.length; +	sourceb.previous = NULL; +	sourceb.fd = -1; +	sourceb.inp_buf = +	  sourceb.inp_buf_ptr = +	    sourceb.inp_buf_end = NULL; +	sourceb.error_converting = false; +	/* Lift some pointers from the struct to local register variables */ +	CACHE_SOURCE(0); +/* We parse the string in segments */ +/* We read chars until we find a $, then we append what we have read so far */ +/* (since last $ processing) to the destination. When we find a $ we call */ +/* expand_macro() and let it expand that particular $ reference into dest */ +	block_start = source_p; +	quote_seen = 0; +	for (; 1; source_p++) { +		switch (GET_CHAR()) { +		case backslash_char: +			/* Quote $ in macro value */ +			if (!cmd) { +				quote_seen = ~quote_seen; +			} +			continue; +		case dollar_char: +			/* Save the plain string we found since */ +			/* start of string or previous $ */ +			if (quote_seen) { +				append_string(block_start, +					      destination, +					      source_p - block_start - 1); +				block_start = source_p; +				break; +			} +			append_string(block_start, +				      destination, +				      source_p - block_start); +			source->string.text.p = ++source_p; +			UNCACHE_SOURCE(); +			/* Go expand the macro reference */ +			expand_macro(source, destination, sourceb.string.buffer.start, cmd); +			CACHE_SOURCE(1); +			block_start = source_p + 1; +			break; +		case nul_char: +			/* The string ran out. Get some more */ +			append_string(block_start, +				      destination, +				      source_p - block_start); +			GET_NEXT_BLOCK_NOCHK(source); +			if (source == NULL) { +				destination->text.end = destination->text.p; +				value->being_expanded = false; +				return; +			} +			if (source->error_converting) { +				fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_value()")); +			} +			block_start = source_p; +			source_p--; +			continue; +		} +		quote_seen = 0; +	} +	retmem(sourceb.string.buffer.start); +} + +/* + *	expand_macro(source, destination, current_string, cmd) + * + *	Should be called with source->string.text.p pointing to + *	the first char after the $ that starts a macro reference. + *	source->string.text.p is returned pointing to the first char after + *	the macro name. + *	It will read the macro name, expanding any macros in it, + *	and get the value. The value is then expanded. + *	destination is a String that is filled in with the expanded macro. + *	It may be passed in referencing a buffer to expand the macro into. + * 	Note that most expansions are done on demand, e.g. right  + *	before the command is executed and not while the file is + * 	being parsed. + * + *	Parameters: + *		source		The source block that references the string + *				to expand + *		destination	Where to put the result + *		current_string	The string we are expanding, for error msg + *		cmd		If we are evaluating a command line we + *				turn \ quoting off + * + *	Global variables used: + *		funny		Vector of semantic tags for characters + *		is_conditional	Set if a conditional macro is refd + *		make_word_mentioned Set if the word "MAKE" is mentioned + *		makefile_type	We deliver extra msg when reading makefiles + *		query		The Name "?", compared against + *		query_mentioned	Set if the word "?" is mentioned + */ +void +expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd) +{ +	static Name		make = (Name)NULL; +	static wchar_t		colon_sh[4]; +	static wchar_t		colon_shell[7]; +	String_rec		string; +	wchar_t			buffer[STRING_BUFFER_LENGTH]; +	register wchar_t	*source_p = source->string.text.p; +	register wchar_t	*source_end = source->string.text.end; +	register int		closer = 0; +	wchar_t			*block_start = (wchar_t *)NULL; +	int			quote_seen = 0; +	register int		closer_level = 1; +	Name			name = (Name)NULL; +	wchar_t			*colon = (wchar_t *)NULL; +	wchar_t			*percent = (wchar_t *)NULL; +	wchar_t			*eq = (wchar_t *) NULL; +	Property		macro = NULL; +	wchar_t			*p = (wchar_t*)NULL; +	String_rec		extracted; +	wchar_t			extracted_string[MAXPATHLEN]; +	wchar_t			*left_head = NULL; +	wchar_t			*left_tail = NULL; +	wchar_t			*right_tail = NULL; +	int			left_head_len = 0; +	int			left_tail_len = 0; +	int			tmp_len = 0; +	wchar_t			*right_hand[128]; +	int			i = 0; +	enum { +		no_extract, +		dir_extract, +		file_extract +	}                       extraction = no_extract; +	enum { +		no_replace, +		suffix_replace, +		pattern_replace, +		sh_replace +	}			replacement = no_replace; + +	if (make == NULL) { +		MBSTOWCS(wcs_buffer, NOCATGETS("MAKE")); +		make = GETNAME(wcs_buffer, FIND_LENGTH); + +		MBSTOWCS(colon_sh, NOCATGETS(":sh")); +		MBSTOWCS(colon_shell, NOCATGETS(":shell")); +	} + +	right_hand[0] = NULL; + +	/* First copy the (macro-expanded) macro name into string. */ +	INIT_STRING_FROM_STACK(string, buffer); +recheck_first_char: +	/* Check the first char of the macro name to figure out what to do. */ +	switch (GET_CHAR()) { +	case nul_char: +		GET_NEXT_BLOCK_NOCHK(source); +		if (source == NULL) { +			WCSTOMBS(mbs_buffer, current_string); +			fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 114, "'$' at end of string `%s'"), +				     mbs_buffer); +		} +		if (source->error_converting) { +			fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_macro()")); +		} +		goto recheck_first_char; +	case parenleft_char: +		/* Multi char name. */ +		closer = (int) parenright_char; +		break; +	case braceleft_char: +		/* Multi char name. */ +		closer = (int) braceright_char; +		break; +	case newline_char: +		fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 115, "'$' at end of line")); +	default: +		/* Single char macro name. Just suck it up */ +		append_char(*source_p, &string); +		source->string.text.p = source_p + 1; +		goto get_macro_value; +	} + +	/* Handle multi-char macro names */ +	block_start = ++source_p; +	quote_seen = 0; +	for (; 1; source_p++) { +		switch (GET_CHAR()) { +		case nul_char: +			append_string(block_start, +				      &string, +				      source_p - block_start); +			GET_NEXT_BLOCK_NOCHK(source); +			if (source == NULL) { +				if (current_string != NULL) { +					WCSTOMBS(mbs_buffer, current_string); +					fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 116, "Unmatched `%c' in string `%s'"), +						     closer == +						     (int) braceright_char ? +						     (int) braceleft_char : +						     (int) parenleft_char, +						     mbs_buffer); +				} else { +					fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 117, "Premature EOF")); +				} +			} +			if (source->error_converting) { +				fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_macro()")); +			} +			block_start = source_p; +			source_p--; +			continue; +		case newline_char: +			fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 118, "Unmatched `%c' on line"), +				     closer == (int) braceright_char ? +				     (int) braceleft_char : +				     (int) parenleft_char); +		case backslash_char: +			/* Quote dollar in macro value. */ +			if (!cmd) { +				quote_seen = ~quote_seen; +			} +			continue; +		case dollar_char: +			/* +			 * Macro names may reference macros. +			 * This expands the value of such macros into the +			 * macro name string. +			 */ +			if (quote_seen) { +				append_string(block_start, +					      &string, +					      source_p - block_start - 1); +				block_start = source_p; +				break; +			} +			append_string(block_start, +				      &string, +				      source_p - block_start); +			source->string.text.p = ++source_p; +			UNCACHE_SOURCE(); +			expand_macro(source, &string, current_string, cmd); +			CACHE_SOURCE(0); +			block_start = source_p; +			source_p--; +			break; +		case parenleft_char: +			/* Allow nested pairs of () in the macro name. */ +			if (closer == (int) parenright_char) { +				closer_level++; +			} +			break; +		case braceleft_char: +			/* Allow nested pairs of {} in the macro name. */ +			if (closer == (int) braceright_char) { +				closer_level++; +			} +			break; +		case parenright_char: +		case braceright_char: +			/* +			 * End of the name. Save the string in the macro +			 * name string. +			 */ +			if ((*source_p == closer) && (--closer_level <= 0)) { +				source->string.text.p = source_p + 1; +				append_string(block_start, +					      &string, +					      source_p - block_start); +				goto get_macro_value; +			} +			break; +		} +		quote_seen = 0; +	} +	/* +	 * We got the macro name. We now inspect it to see if it +	 * specifies any translations of the value. +	 */ +get_macro_value: +	name = NULL; +	/* First check if we have a $(@D) type translation. */ +	if ((get_char_semantics_value(string.buffer.start[0]) & +	     (int) special_macro_sem) && +	    (string.text.p - string.buffer.start >= 2) && +	    ((string.buffer.start[1] == 'D') || +	     (string.buffer.start[1] == 'F'))) { +		switch (string.buffer.start[1]) { +		case 'D': +			extraction = dir_extract; +			break; +		case 'F': +			extraction = file_extract; +			break; +		default: +			WCSTOMBS(mbs_buffer, string.buffer.start); +			fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 119, "Illegal macro reference `%s'"), +				     mbs_buffer); +		} +		/* Internalize the macro name using the first char only. */ +		name = GETNAME(string.buffer.start, 1); +		(void) wscpy(string.buffer.start, string.buffer.start + 2); +	} +	/* Check for other kinds of translations. */ +	if ((colon = (wchar_t *) wschr(string.buffer.start, +				       (int) colon_char)) != NULL) { +		/* +		 * We have a $(FOO:.c=.o) type translation. +		 * Get the name of the macro proper. +		 */ +		if (name == NULL) { +			name = GETNAME(string.buffer.start, +				       colon - string.buffer.start); +		} +		/* Pickup all the translations. */ +		if (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell)) { +			replacement = sh_replace; +		} else if ((svr4) || +		           ((percent = (wchar_t *) wschr(colon + 1, +							 (int) percent_char)) == NULL)) { +			while (colon != NULL) { +				if ((eq = (wchar_t *) wschr(colon + 1, +							    (int) equal_char)) == NULL) { +					fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 120, "= missing from replacement macro reference")); +				} +				left_tail_len = eq - colon - 1; +				if(left_tail) { +					retmem(left_tail); +				} +				left_tail = ALLOC_WC(left_tail_len + 1); +				(void) wsncpy(left_tail, +					      colon + 1, +					      eq - colon - 1); +				left_tail[eq - colon - 1] = (int) nul_char; +				replacement = suffix_replace; +				if ((colon = (wchar_t *) wschr(eq + 1, +							       (int) colon_char)) != NULL) { +					tmp_len = colon - eq; +					if(right_tail) { +						retmem(right_tail); +					} +					right_tail = ALLOC_WC(tmp_len); +					(void) wsncpy(right_tail, +						      eq + 1, +						      colon - eq - 1); +					right_tail[colon - eq - 1] = +					  (int) nul_char; +				} else { +					if(right_tail) { +						retmem(right_tail); +					} +					right_tail = ALLOC_WC(wslen(eq) + 1); +					(void) wscpy(right_tail, eq + 1); +				} +			} +		} else { +			if ((eq = (wchar_t *) wschr(colon + 1, +						    (int) equal_char)) == NULL) { +				fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 121, "= missing from replacement macro reference")); +			} +			if ((percent = (wchar_t *) wschr(colon + 1, +							 (int) percent_char)) == NULL) { +				fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 122, "%% missing from replacement macro reference")); +			} +			if (eq < percent) { +				fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 123, "%% missing from replacement macro reference")); +			} + +			if (percent > (colon + 1)) { +				tmp_len = percent - colon; +				if(left_head) { +					retmem(left_head); +				} +				left_head = ALLOC_WC(tmp_len); +				(void) wsncpy(left_head, +					      colon + 1, +					      percent - colon - 1); +				left_head[percent-colon-1] = (int) nul_char; +				left_head_len = percent-colon-1; +			} else { +				left_head = NULL; +				left_head_len = 0; +			} + +			if (eq > percent+1) { +				tmp_len = eq - percent; +				if(left_tail) { +					retmem(left_tail); +				} +				left_tail = ALLOC_WC(tmp_len); +				(void) wsncpy(left_tail, +					      percent + 1, +					      eq - percent - 1); +				left_tail[eq-percent-1] = (int) nul_char; +				left_tail_len = eq-percent-1; +			} else { +				left_tail = NULL; +				left_tail_len = 0; +			} + +			if ((percent = (wchar_t *) wschr(++eq, +							 (int) percent_char)) == NULL) { + +				right_hand[0] = ALLOC_WC(wslen(eq) + 1); +				right_hand[1] = NULL; +				(void) wscpy(right_hand[0], eq); +			} else { +				i = 0; +				do { +					right_hand[i] = ALLOC_WC(percent-eq+1); +					(void) wsncpy(right_hand[i], +						      eq, +						      percent - eq); +					right_hand[i][percent-eq] = +					  (int) nul_char; +					if (i++ >= VSIZEOF(right_hand)) { +						fatal_mksh(catgets(libmksdmsi18n_catd, 1, 124, "Too many %% in pattern")); +					} +					eq = percent + 1; +					if (eq[0] == (int) nul_char) { +						MBSTOWCS(wcs_buffer, ""); +						right_hand[i] = (wchar_t *) wsdup(wcs_buffer); +						i++; +						break; +					} +				} while ((percent = (wchar_t *) wschr(eq, (int) percent_char)) != NULL); +				if (eq[0] != (int) nul_char) { +					right_hand[i] = ALLOC_WC(wslen(eq) + 1); +					(void) wscpy(right_hand[i], eq); +					i++; +				} +				right_hand[i] = NULL; +			} +			replacement = pattern_replace; +		} +	} +	if (name == NULL) { +		/* +		 * No translations found. +		 * Use the whole string as the macro name. +		 */ +		name = GETNAME(string.buffer.start, +			       string.text.p - string.buffer.start); +	} +	if (string.free_after_use) { +		retmem(string.buffer.start); +	} +	if (name == make) { +		make_word_mentioned = true; +	} +	if (name == query) { +		query_mentioned = true; +	} +	if ((name == host_arch) || (name == target_arch)) { +		if (!init_arch_done) { +			init_arch_done = true; +			init_arch_macros(); +		} +	} +	if ((name == host_mach) || (name == target_mach)) { +		if (!init_mach_done) { +			init_mach_done = true; +			init_mach_macros(); +		} +	} +	/* Get the macro value. */ +	macro = get_prop(name->prop, macro_prop); +#ifdef NSE +        if (nse_watch_vars && nse && macro != NULL) { +                if (macro->body.macro.imported) { +                        nse_shell_var_used= name; +		} +                if (macro->body.macro.value != NULL){ +	              if (nse_backquotes(macro->body.macro.value->string)) { +	                       nse_backquote_seen= name; +		      } +	       } +	} +#endif +	if ((macro != NULL) && macro->body.macro.is_conditional) { +		conditional_macro_used = true; +		/* +		 * Add this conditional macro to the beginning of the +		 * global list. +		 */ +		add_macro_to_global_list(name); +		if (makefile_type == reading_makefile) { +			warning_mksh(catgets(libmksdmsi18n_catd, 1, 164, "Conditional macro `%s' referenced in file `%ws', line %d"), +					name->string_mb, file_being_read, line_number); +		} +	} +	/* Macro name read and parsed. Expand the value. */ +	if ((macro == NULL) || (macro->body.macro.value == NULL)) { +		/* If the value is empty, we just get out of here. */ +		goto exit; +	} +	if (replacement == sh_replace) { +		/* If we should do a :sh transform, we expand the command +		 * and process it. +		 */ +		INIT_STRING_FROM_STACK(string, buffer); +		/* Expand the value into a local string buffer and run cmd. */ +		expand_value_with_daemon(name, macro, &string, cmd); +		sh_command2string(&string, destination); +	} else if ((replacement != no_replace) || (extraction != no_extract)) { +		/* +		 * If there were any transforms specified in the macro +		 * name, we deal with them here. +		 */ +		INIT_STRING_FROM_STACK(string, buffer); +		/* Expand the value into a local string buffer. */ +		expand_value_with_daemon(name, macro, &string, cmd); +		/* Scan the expanded string. */ +		p = string.buffer.start; +		while (*p != (int) nul_char) { +			wchar_t		chr; + +			/* +			 * First skip over any white space and append +			 * that to the destination string. +			 */ +			block_start = p; +			while ((*p != (int) nul_char) && iswspace(*p)) { +				p++; +			} +			append_string(block_start, +				      destination, +				      p - block_start); +			/* Then find the end of the next word. */ +			block_start = p; +			while ((*p != (int) nul_char) && !iswspace(*p)) { +				p++; +			} +			/* If we cant find another word we are done */ +			if (block_start == p) { +				break; +			} +			/* Then apply the transforms to the word */ +			INIT_STRING_FROM_STACK(extracted, extracted_string); +			switch (extraction) { +			case dir_extract: +				/* +				 * $(@D) type transform. Extract the +				 * path from the word. Deliver "." if +				 * none is found. +				 */ +				if (p != NULL) { +					chr = *p; +					*p = (int) nul_char; +				} +				eq = (wchar_t *) wsrchr(block_start, (int) slash_char); +				if (p != NULL) { +					*p = chr; +				} +				if ((eq == NULL) || (eq > p)) { +					MBSTOWCS(wcs_buffer, "."); +					append_string(wcs_buffer, &extracted, 1); +				} else { +					append_string(block_start, +						      &extracted, +						      eq - block_start); +				} +				break; +			case file_extract: +				/* +				 * $(@F) type transform. Remove the path +				 * from the word if any. +				 */ +				if (p != NULL) { +					chr = *p; +					*p = (int) nul_char; +				} +				eq = (wchar_t *) wsrchr(block_start, (int) slash_char); +				if (p != NULL) { +					*p = chr; +				} +				if ((eq == NULL) || (eq > p)) { +					append_string(block_start, +						      &extracted, +						      p - block_start); +				} else { +					append_string(eq + 1, +						      &extracted, +						      p - eq - 1); +				} +				break; +			case no_extract: +				append_string(block_start, +					      &extracted, +					      p - block_start); +				break; +			} +			switch (replacement) { +			case suffix_replace: +				/* +				 * $(FOO:.o=.c) type transform. +				 * Maybe replace the tail of the word. +				 */ +				if (((extracted.text.p - +				      extracted.buffer.start) >= +				     left_tail_len) && +				    IS_WEQUALN(extracted.text.p - left_tail_len, +					      left_tail, +					      left_tail_len)) { +					append_string(extracted.buffer.start, +						      destination, +						      (extracted.text.p - +						       extracted.buffer.start) +						      - left_tail_len); +					append_string(right_tail, +						      destination, +						      FIND_LENGTH); +				} else { +					append_string(extracted.buffer.start, +						      destination, +						      FIND_LENGTH); +				} +				break; +			case pattern_replace: +				/* $(X:a%b=c%d) type transform. */ +				if (((extracted.text.p - +				      extracted.buffer.start) >= +				     left_head_len+left_tail_len) && +				    IS_WEQUALN(left_head, +					      extracted.buffer.start, +					      left_head_len) && +				    IS_WEQUALN(left_tail, +					      extracted.text.p - left_tail_len, +					      left_tail_len)) { +					i = 0; +					while (right_hand[i] != NULL) { +						append_string(right_hand[i], +							      destination, +							      FIND_LENGTH); +						i++; +						if (right_hand[i] != NULL) { +							append_string(extracted.buffer. +								      start + +								      left_head_len, +								      destination, +								      (extracted.text.p - extracted.buffer.start)-left_head_len-left_tail_len); +						} +					} +				} else { +					append_string(extracted.buffer.start, +						      destination, +						      FIND_LENGTH); +				} +				break; +			case no_replace: +				append_string(extracted.buffer.start, +					      destination, +					      FIND_LENGTH); +				break; +			case sh_replace: +				break; +			    } +		} +		if (string.free_after_use) { +			retmem(string.buffer.start); +		} +	} else { +		/* +		 * This is for the case when the macro name did not +		 * specify transforms. +		 */ +		if (!strncmp(name->string_mb, NOCATGETS("GET"), 3)) { +			dollarget_seen = true; +		} +		dollarless_flag = false; +		if (!strncmp(name->string_mb, "<", 1) && +		    dollarget_seen) { +			dollarless_flag = true; +			dollarget_seen = false; +		} +		expand_value_with_daemon(name, macro, destination, cmd); +	} +exit: +	if(left_tail) { +		retmem(left_tail); +	} +	if(right_tail) { +		retmem(right_tail); +	} +	if(left_head) { +		retmem(left_head); +	} +	i = 0; +	while (right_hand[i] != NULL) { +		retmem(right_hand[i]); +		i++; +	} +	*destination->text.p = (int) nul_char; +	destination->text.end = destination->text.p; +} + +static void +add_macro_to_global_list(Name macro_to_add) +{ +	Macro_list	new_macro; +	Macro_list	macro_on_list; +	char		*name_on_list = (char*)NULL; +	char		*name_to_add = macro_to_add->string_mb; +	char		*value_on_list = (char*)NULL; +	char		*value_to_add = (char*)NULL; + +	if (macro_to_add->prop->body.macro.value != NULL) { +		value_to_add = macro_to_add->prop->body.macro.value->string_mb; +	} else { +		value_to_add = ""; +	} + +	/*  +	 * Check if this macro is already on list, if so, do nothing +	 */ +	for (macro_on_list = cond_macro_list; +	     macro_on_list != NULL; +	     macro_on_list = macro_on_list->next) { + +		name_on_list = macro_on_list->macro_name; +		value_on_list = macro_on_list->value; + +		if (IS_EQUAL(name_on_list, name_to_add)) { +			if (IS_EQUAL(value_on_list, value_to_add)) { +				return; +			} +		} +	} +	new_macro = (Macro_list) malloc(sizeof(Macro_list_rec)); +	new_macro->macro_name = strdup(name_to_add); +	new_macro->value = strdup(value_to_add); +	new_macro->next = cond_macro_list; +	cond_macro_list = new_macro; +} + +/* + *	init_arch_macros(void) + * + *	Set the magic macros TARGET_ARCH, HOST_ARCH, + * + *	Parameters:  + * + *	Global variables used: + * 	                        host_arch   Property for magic macro HOST_ARCH + * 	                        target_arch Property for magic macro TARGET_ARCH + * + *	Return value: + *				The function does not return a value, but can + *				call fatal() in case of error. + */ +static void +init_arch_macros(void) +{ +	String_rec	result_string; +	wchar_t		wc_buf[STRING_BUFFER_LENGTH]; +	char		mb_buf[STRING_BUFFER_LENGTH]; +	FILE		*pipe; +	Name		value; +	int		set_host, set_target; +#ifdef NSE +	Property	macro; +#endif +#if defined(linux) +	const char	*mach_command = NOCATGETS("/bin/uname -p"); +#else +	const char	*mach_command = NOCATGETS("/bin/mach"); +#endif + +	set_host = (get_prop(host_arch->prop, macro_prop) == NULL); +	set_target = (get_prop(target_arch->prop, macro_prop) == NULL); + +	if (set_host || set_target) { +		INIT_STRING_FROM_STACK(result_string, wc_buf); +		append_char((int) hyphen_char, &result_string); + +		if ((pipe = popen(mach_command, "r")) == NULL) { +			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 185, "Execute of %s failed"), mach_command); +		} +		while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) { +			MBSTOWCS(wcs_buffer, mb_buf); +			append_string(wcs_buffer, &result_string, wslen(wcs_buffer)); +		} +		if (pclose(pipe) != 0) { +			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 186, "Execute of %s failed"), mach_command); +		} + +		value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start)); + +#ifdef NSE +	        macro = setvar_daemon(host_arch, value, false, no_daemon, true, 0); +	        macro->body.macro.imported= true; +	        macro = setvar_daemon(target_arch, value, false, no_daemon, true, 0); +	        macro->body.macro.imported= true; +#else +		if (set_host) { +			(void) setvar_daemon(host_arch, value, false, no_daemon, true, 0); +		} +		if (set_target) { +			(void) setvar_daemon(target_arch, value, false, no_daemon, true, 0); +		} +#endif +	} +} + +/* + *	init_mach_macros(void) + * + *	Set the magic macros TARGET_MACH, HOST_MACH, + * + *	Parameters:  + * + *	Global variables used: + * 	                        host_mach   Property for magic macro HOST_MACH + * 	                        target_mach Property for magic macro TARGET_MACH + * + *	Return value: + *				The function does not return a value, but can + *				call fatal() in case of error. + */ +static void +init_mach_macros(void) +{ +	String_rec	result_string; +	wchar_t		wc_buf[STRING_BUFFER_LENGTH]; +	char		mb_buf[STRING_BUFFER_LENGTH]; +	FILE		*pipe; +	Name		value; +	int		set_host, set_target; +	const char	*arch_command = NOCATGETS("/bin/arch"); + +	set_host = (get_prop(host_mach->prop, macro_prop) == NULL); +	set_target = (get_prop(target_mach->prop, macro_prop) == NULL); + +	if (set_host || set_target) { +		INIT_STRING_FROM_STACK(result_string, wc_buf); +		append_char((int) hyphen_char, &result_string); + +		if ((pipe = popen(arch_command, "r")) == NULL) { +			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 183, "Execute of %s failed"), arch_command); +		} +		while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) { +			MBSTOWCS(wcs_buffer, mb_buf); +			append_string(wcs_buffer, &result_string, wslen(wcs_buffer)); +		} +		if (pclose(pipe) != 0) { +			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 184, "Execute of %s failed"), arch_command); +		} + +		value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start)); + +		if (set_host) { +			(void) setvar_daemon(host_mach, value, false, no_daemon, true, 0); +		} +		if (set_target) { +			(void) setvar_daemon(target_mach, value, false, no_daemon, true, 0); +		} +	} +} + +/* + *	expand_value_with_daemon(name, macro, destination, cmd) + * + *	Checks for daemons and then maybe calls expand_value(). + * + *	Parameters: + *              name            Name of the macro  (Added by the NSE) + *		macro		The property block with the value to expand + *		destination	Where the result should be deposited + *		cmd		If we are evaluating a command line we + *				turn \ quoting off + * + *	Global variables used: + */ +static void +#ifdef NSE +expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd) +#else +expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd) +#endif +{ +	register Chain		chain; + +#ifdef NSE +        if (reading_dependencies) { +                /* +                 * Processing the dependencies themselves +                 */ +                depvar_dep_macro_used(name); +	} else { +                /* +	         * Processing the rules for the targets +	         * the nse_watch_vars flags chokes off most +	         * checks.  it is true only when processing +	         * the output from a recursive make run +	         * which is all we are interested in here. +	         */ +	         if (nse_watch_vars) { +	                depvar_rule_macro_used(name); +		} +	 } +#endif + +	switch (macro->body.macro.daemon) { +	case no_daemon: +		if (!svr4 && !posix) { +			expand_value(macro->body.macro.value, destination, cmd); +		} else { +			if (dollarless_flag && tilde_rule) { +				expand_value(dollarless_value, destination, cmd); +				dollarless_flag = false; +				tilde_rule = false; +			} else { +				expand_value(macro->body.macro.value, destination, cmd); +			} +		} +		return; +	case chain_daemon: +		/* If this is a $? value we call the daemon to translate the */ +		/* list of names to a string */ +		for (chain = (Chain) macro->body.macro.value; +		     chain != NULL; +		     chain = chain->next) { +			APPEND_NAME(chain->name, +				      destination, +				      (int) chain->name->hash.length); +			if (chain->next != NULL) { +				append_char((int) space_char, destination); +			} +		} +		return; +	} +} + +/* + * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value. + */ +char	*sunpro_dependencies_buf = NULL; +char	*sunpro_dependencies_oldbuf = NULL; +int	sunpro_dependencies_buf_size = 0; + +/* + *	setvar_daemon(name, value, append, daemon, strip_trailing_spaces) + * + *	Set a macro value, possibly supplying a daemon to be used + *	when referencing the value. + * + *	Return value: + *				The property block with the new value + * + *	Parameters: + *		name		Name of the macro to set + *		value		The value to set + *		append		Should we reset or append to the current value? + *		daemon		Special treatment when reading the value + *		strip_trailing_spaces from the end of value->string + *		debug_level	Indicates how much tracing we should do + * + *	Global variables used: + *		makefile_type	Used to check if we should enforce read only + *		path_name	The Name "PATH", compared against + *		virtual_root	The Name "VIRTUAL_ROOT", compared against + *		vpath_defined	Set if the macro VPATH is set + *		vpath_name	The Name "VPATH", compared against + *		envvar		A list of environment vars with $ in value + */ +Property +setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level) +{ +	register Property	macro = maybe_append_prop(name, macro_prop); +	register Property	macro_apx = get_prop(name->prop, macro_append_prop); +	int			length = 0; +	String_rec		destination; +	wchar_t			buffer[STRING_BUFFER_LENGTH]; +	register Chain		chain; +	Name			val; +	wchar_t			*val_string = (wchar_t*)NULL; +	Wstring			wcb; + +#ifdef NSE +        macro->body.macro.imported = false; +#endif + +	if ((makefile_type != reading_nothing) && +	    macro->body.macro.read_only) { +		return macro; +	} +	/* Strip spaces from the end of the value */ +	if (daemon == no_daemon) { +		if(value != NULL) { +			wcb.init(value); +			length = wcb.length(); +			val_string = wcb.get_string(); +		} +		if ((length > 0) && iswspace(val_string[length-1])) { +			INIT_STRING_FROM_STACK(destination, buffer); +			buffer[0] = 0; +			append_string(val_string, &destination, length); +			if (strip_trailing_spaces) { +				while ((length > 0) && +				       iswspace(destination.buffer.start[length-1])) { +					destination.buffer.start[--length] = 0; +				} +			} +			value = GETNAME(destination.buffer.start, FIND_LENGTH); +		} +	} +		 +	if(macro_apx != NULL) { +		val = macro_apx->body.macro_appendix.value; +	} else { +		val = macro->body.macro.value; +	} + +	if (append) { +		/* +		 * If we are appending, we just tack the new value after +		 * the old one with a space in between. +		 */ +		INIT_STRING_FROM_STACK(destination, buffer); +		buffer[0] = 0; +		if ((macro != NULL) && (val != NULL)) { +			APPEND_NAME(val, +				      &destination, +				      (int) val->hash.length); +			if (value != NULL) { +				wcb.init(value); +				if(wcb.length() > 0) { +					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); +		wcb.init(value); +		if (destination.free_after_use) { +			retmem(destination.buffer.start); +		} +	} + +	/* Debugging trace */ +	if (debug_level > 1) { +		if (value != NULL) { +			switch (daemon) { +			case chain_daemon: +				(void) printf("%s =", name->string_mb); +				for (chain = (Chain) value; +				     chain != NULL; +				     chain = chain->next) { +					(void) printf(" %s", chain->name->string_mb); +				} +				(void) printf("\n"); +				break; +			case no_daemon: +				(void) printf("%s= %s\n", +					      name->string_mb, +					      value->string_mb); +				break; +			} +		} else { +			(void) printf("%s =\n", name->string_mb); +		} +	} +	/* Set the new values in the macro property block */ +/**/ +	if(macro_apx != NULL) { +		macro_apx->body.macro_appendix.value = value; +		INIT_STRING_FROM_STACK(destination, buffer); +		buffer[0] = 0; +		if (value != NULL) { +			APPEND_NAME(value, +				      &destination, +				      (int) value->hash.length); +			if (macro_apx->body.macro_appendix.value_to_append != NULL) { +				MBTOWC(wcs_buffer, " "); +				append_char(wcs_buffer[0], &destination); +			} +		} +		if (macro_apx->body.macro_appendix.value_to_append != NULL) { +			APPEND_NAME(macro_apx->body.macro_appendix.value_to_append, +				      &destination, +				      (int) macro_apx->body.macro_appendix.value_to_append->hash.length); +		} +		value = GETNAME(destination.buffer.start, FIND_LENGTH); +		if (destination.free_after_use) { +			retmem(destination.buffer.start); +		} +	} +/**/ +	macro->body.macro.value = value; +	macro->body.macro.daemon = daemon; +	/* +	 * If the user changes the VIRTUAL_ROOT, we need to flush +	 * the vroot package cache. +	 */ +	if (name == path_name) { +		flush_path_cache(); +	} +	if (name == virtual_root) { +		flush_vroot_cache(); +	} +	/* If this sets the VPATH we remember that */ +	if ((name == vpath_name) && +	    (value != NULL) && +	    (value->hash.length > 0)) { +		vpath_defined = true; +	} +	/* +	 * For environment variables we also set the +	 * environment value each time. +	 */ +	if (macro->body.macro.exported) { +		static char	*env; + +#ifdef DISTRIBUTED +		if (!reading_environment && (value != NULL)) { +#else +		if (!reading_environment && (value != NULL) && value->dollar) { +#endif +			Envvar	p; + +			for (p = envvar; p != NULL; p = p->next) { +				if (p->name == name) { +					p->value = value; +					p->already_put = false; +					goto found_it; +				} +			} +			p = ALLOC(Envvar); +			p->name = name; +			p->value = value; +			p->next = envvar; +			p->env_string = NULL; +			p->already_put = false; +			envvar = p; +found_it:; +#ifdef DISTRIBUTED +		} +		if (reading_environment || (value == NULL) || !value->dollar) { +#else +		} else { +#endif +			length = 2 + strlen(name->string_mb); +			if (value != NULL) { +				length += strlen(value->string_mb); +			} +			Property env_prop = maybe_append_prop(name, env_mem_prop); +			/* +			 * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value. +			 */ +			if (!strncmp(name->string_mb, NOCATGETS("SUNPRO_DEPENDENCIES"), 19)) { +				if (length >= sunpro_dependencies_buf_size) { +					sunpro_dependencies_buf_size=length*2; +					if (sunpro_dependencies_buf_size < 4096) +						sunpro_dependencies_buf_size = 4096; // Default minimum size +					if (sunpro_dependencies_buf) +						sunpro_dependencies_oldbuf = sunpro_dependencies_buf; +					sunpro_dependencies_buf=getmem(sunpro_dependencies_buf_size); +				} +				env = sunpro_dependencies_buf; +			} else { +				env = getmem(length); +			} +			env_alloc_num++; +			env_alloc_bytes += length; +			(void) sprintf(env, +				       "%s=%s", +				       name->string_mb, +				       value == NULL ? +			                 "" : value->string_mb); +			(void) putenv(env); +			env_prop->body.env_mem.value = env; +			if (sunpro_dependencies_oldbuf) { +				/* Return old buffer */ +				retmem_mb(sunpro_dependencies_oldbuf); +				sunpro_dependencies_oldbuf = NULL; +			} +		} +	} +	if (name == target_arch) { +		Name		ha = getvar(host_arch); +		Name		ta = getvar(target_arch); +		Name		vr = getvar(virtual_root); +		int		length; +		wchar_t		*new_value; +		wchar_t		*old_vr; +		Boolean		new_value_allocated = false; + +		Wstring		ha_str(ha); +		Wstring		ta_str(ta); +		Wstring		vr_str(vr); + +		wchar_t * wcb_ha = ha_str.get_string(); +		wchar_t * wcb_ta = ta_str.get_string(); +		wchar_t * wcb_vr = vr_str.get_string(); + +		length = 32 + +		  wslen(wcb_ha) + +		    wslen(wcb_ta) + +		      wslen(wcb_vr); +		old_vr = wcb_vr; +		MBSTOWCS(wcs_buffer, NOCATGETS("/usr/arch/")); +		if (IS_WEQUALN(old_vr, +			       wcs_buffer, +			       wslen(wcs_buffer))) { +			old_vr = (wchar_t *) wschr(old_vr, (int) colon_char) + 1; +		} +		if ( (ha == ta) || (wslen(wcb_ta) == 0) ) { +			new_value = old_vr; +		} else { +			new_value = ALLOC_WC(length); +			new_value_allocated = true; +			WCSTOMBS(mbs_buffer, old_vr); +#if !defined(linux) +			(void) wsprintf(new_value, +				        NOCATGETS("/usr/arch/%s/%s:%s"), +				        ha->string_mb + 1, +				        ta->string_mb + 1, +				        mbs_buffer); +#else +			char * mbs_new_value = (char *)getmem(length); +			(void) sprintf(mbs_new_value, +				        NOCATGETS("/usr/arch/%s/%s:%s"), +				        ha->string_mb + 1, +				        ta->string_mb + 1, +				        mbs_buffer); +			MBSTOWCS(new_value, mbs_new_value); +			retmem_mb(mbs_new_value); +#endif +		} +		if (new_value[0] != 0) { +			(void) setvar_daemon(virtual_root, +					     GETNAME(new_value, FIND_LENGTH), +					     false, +					     no_daemon, +					     true, +					     debug_level); +		} +		if (new_value_allocated) { +			retmem(new_value); +		} +	} +	return macro; +} diff --git a/usr/src/make_src/Make/lib/mksh/src/misc.cc b/usr/src/make_src/Make/lib/mksh/src/misc.cc new file mode 100644 index 0000000..17a878b --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/misc.cc @@ -0,0 +1,1178 @@ +/* + * 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. + */ +/* + * @(#)misc.cc 1.31 06/12/12 + */ + +#pragma	ident	"@(#)misc.cc	1.31	06/12/12" + +/* + *	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 <bsd/bsd.h>		/* bsd_signal() */ +#include <mksh/i18n.h>		/* get_char_semantics_value() */ +#include <mksh/misc.h> +#include <mksdmsi18n/mksdmsi18n.h> +#include <stdarg.h>		/* va_list, va_start(), va_end() */ +#include <stdlib.h>		/* mbstowcs() */ +#include <sys/signal.h>		/* SIG_DFL */ +#include <sys/wait.h>		/* wait() */ + +#ifdef SUN5_0 +#include <string.h>		/* strerror() */ +#endif + +#if defined (HP_UX) || defined (linux) +#include <unistd.h> +#endif + +/* + * Defined macros + */ + +/* + * typedefs & structs + */ + +/* + * Static variables + */ +#ifdef SUN5_0 +extern "C" void		(*sigivalue)(int) = SIG_DFL; +extern "C" void		(*sigqvalue)(int) = SIG_DFL; +extern "C" void		(*sigtvalue)(int) = SIG_DFL; +extern "C" void		(*sighvalue)(int) = SIG_DFL; +#else +static	void		(*sigivalue)(int) = (void (*) (int)) SIG_DFL; +static	void		(*sigqvalue)(int) = (void (*) (int)) SIG_DFL; +static	void		(*sigtvalue)(int) = (void (*) (int)) SIG_DFL; +static	void		(*sighvalue)(int) = (void (*) (int)) SIG_DFL; +#endif + +long	getname_bytes_count = 0; +long	getname_names_count = 0; +long	getname_struct_count = 0; + +long	freename_bytes_count = 0; +long	freename_names_count = 0; +long	freename_struct_count = 0; + +long	expandstring_count = 0; +long	getwstring_count = 0; + +/* + * File table of contents + */ +static void	expand_string(register String string, register int length); + +#define	FATAL_ERROR_MSG_SIZE 200 + +/* + *	getmem(size) + * + *	malloc() version that checks the returned value. + * + *	Return value: + *				The memory chunk we allocated + * + *	Parameters: + *		size		The size of the chunk we need + * + *	Global variables used: + */ +char * +getmem(register int size) +{ +	register char          *result = (char *) malloc((unsigned) size); +	if (result == NULL) { +		char buf[FATAL_ERROR_MSG_SIZE]; +		sprintf(buf, NOCATGETS("*** Error: malloc(%d) failed: %s\n"), size, strerror(errno)); +		strcat(buf, catgets(libmksdmsi18n_catd, 1, 126, "mksh: Fatal error: Out of memory\n")); +		fputs(buf, stderr); +#ifdef SUN5_0 +		exit_status = 1; +#endif +		exit(1); +	} +	return result; +} + +/* + *	retmem(p) + * + *	Cover funtion for free() to make it possible to insert advises. + * + *	Parameters: + *		p		The memory block to free + * + *	Global variables used: + */ +void +retmem(wchar_t *p) +{ +	(void) free((char *) p); +} + +void +retmem_mb(caddr_t p) +{ +	(void) free(p); +} + +/* + *	getname_fn(name, len, dont_enter) + * + *	Hash a name string to the corresponding nameblock. + * + *	Return value: + *				The Name block for the string + * + *	Parameters: + *		name		The string we want to internalize + *		len		The length of that string + *		dont_enter	Don't enter the name if it does not exist + * + *	Global variables used: + *		funny		The vector of semantic tags for characters + *		hashtab		The hashtable used for the nametable + */ +Name +getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp) +{ +	register int		length; +	register wchar_t	*cap = name; +	register Name		np; +	static Name_rec		empty_Name; +	char			*tmp_mbs_buffer = NULL; +	char			*mbs_name = mbs_buffer; + +	/* +	 * First figure out how long the string is. +	 * If the len argument is -1 we count the chars here. +	 */ +	if (len == FIND_LENGTH) { +		length = wslen(name); +	} else { +		length = len; +	} + +	Wstring ws; +	ws.init(name, length); +	if (length >= MAXPATHLEN) { +		mbs_name = tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1); +	} +	(void) wcstombs(mbs_name, ws.get_string(), (length * MB_LEN_MAX) + 1); + +	/* Look for the string */ +	if (dont_enter || (foundp != 0)) { +		np = hashtab.lookup(mbs_name); +		if (foundp != 0) { +			*foundp = (np != 0) ? true : false; +		} +		if ((np != 0) || dont_enter) { +			if(tmp_mbs_buffer != NULL) { +				retmem_mb(tmp_mbs_buffer); +			} +			return np; +		} else { +			np = ALLOC(Name); +		} +	} else { +		Boolean found; +		np = hashtab.insert(mbs_name, found); +		if (found) { +			if(tmp_mbs_buffer != NULL) { +				retmem_mb(tmp_mbs_buffer); +			} +			return np; +		} +	} +	getname_struct_count += sizeof(struct _Name); +	*np = empty_Name; + +	np->string_mb = strdup(mbs_name); +	if(tmp_mbs_buffer != NULL) { +		retmem_mb(tmp_mbs_buffer); +		mbs_name = tmp_mbs_buffer = NULL; +	} +	getname_bytes_count += strlen(np->string_mb) + 1; +	/* Fill in the new Name */ +	np->stat.time = file_no_time; +	np->hash.length = length; +	/* Scan the namestring to classify it */ +	for (cap = name, len = 0; --length >= 0;) { +		len |= get_char_semantics_value(*cap++); +	} +	np->dollar = BOOLEAN((len & (int) dollar_sem) != 0); +	np->meta = BOOLEAN((len & (int) meta_sem) != 0); +	np->percent = BOOLEAN((len & (int) percent_sem) != 0); +	np->wildcard = BOOLEAN((len & (int) wildcard_sem) != 0); +	np->colon = BOOLEAN((len & (int) colon_sem) != 0); +	np->parenleft = BOOLEAN((len & (int) parenleft_sem) != 0); +	getname_names_count++; +	return np; +} + +void +store_name(Name name) +{ +	hashtab.insert(name); +} + +void +free_name(Name name) +{ +	freename_names_count++; +	freename_struct_count += sizeof(struct _Name); +	freename_bytes_count += strlen(name->string_mb) + 1; +	retmem_mb(name->string_mb); +	for (Property next, p = name->prop; p != NULL; p = next) { +		next = p->next; +		free(p); +	} +	free(name); +} + +/* + *	enable_interrupt(handler) + * + *	This routine sets a new interrupt handler for the signals make + *	wants to deal with. + * + *	Parameters: + *		handler		The function installed as interrupt handler + * + *	Static variables used: + *		sigivalue	The original signal handler + *		sigqvalue	The original signal handler + *		sigtvalue	The original signal handler + *		sighvalue	The original signal handler + */ +void +enable_interrupt(register void (*handler) (int)) +{ +#ifdef SUN5_0 +	if (sigivalue != SIG_IGN) { +#else +	if (sigivalue != (void (*) (int)) SIG_IGN) { +#endif +		(void) bsd_signal(SIGINT, (SIG_PF) handler); +	} +#ifdef SUN5_0 +	if (sigqvalue != SIG_IGN) { +#else +	if (sigqvalue != (void (*) (int)) SIG_IGN) { +#endif +		(void) bsd_signal(SIGQUIT, (SIG_PF) handler); +	} +#ifdef SUN5_0 +	if (sigtvalue != SIG_IGN) { +#else +	if (sigtvalue != (void (*) (int)) SIG_IGN) { +#endif +		(void) bsd_signal(SIGTERM, (SIG_PF) handler); +	} +#ifdef SUN5_0 +	if (sighvalue != SIG_IGN) { +#else +	if (sighvalue != (void (*) (int)) SIG_IGN) { +#endif +		(void) bsd_signal(SIGHUP, (SIG_PF) handler); +	} +} + +/* + *	setup_char_semantics() + * + *	Load the vector char_semantics[] with lexical markers + * + *	Parameters: + * + *	Global variables used: + *		char_semantics	The vector of character semantics that we set + */ +void +setup_char_semantics(void) +{ +	char		*s; +	wchar_t		wc_buffer[1]; +	int		entry; + +	if (svr4) { +		s = "@-"; +	} else { +		s = "=@-?!+"; +	} +	for (s; MBTOWC(wc_buffer, s); s++) { +		entry = get_char_semantics_entry(*wc_buffer); +		char_semantics[entry] |= (int) command_prefix_sem; +	} +	char_semantics[dollar_char_entry] |= (int) dollar_sem; +	for (s = "#|=^();&<>*?[]:$`'\"\\\n"; MBTOWC(wc_buffer, s); s++) { +		entry = get_char_semantics_entry(*wc_buffer); +		char_semantics[entry] |= (int) meta_sem; +	} +	char_semantics[percent_char_entry] |= (int) percent_sem; +	for (s = "@*<%?^"; MBTOWC(wc_buffer, s); s++) { +		entry = get_char_semantics_entry(*wc_buffer); +		char_semantics[entry] |= (int) special_macro_sem; +	} +	for (s = "?[*"; MBTOWC(wc_buffer, s); s++) { +		entry = get_char_semantics_entry(*wc_buffer); +		char_semantics[entry] |= (int) wildcard_sem; +	} +	char_semantics[colon_char_entry] |= (int) colon_sem; +	char_semantics[parenleft_char_entry] |= (int) parenleft_sem; +} + +/* + *	errmsg(errnum) + * + *	Return the error message for a system call error + * + *	Return value: + *				An error message string + * + *	Parameters: + *		errnum		The number of the error we want to describe + * + *	Global variables used: + *		sys_errlist	A vector of error messages + *		sys_nerr	The size of sys_errlist + */ +char * +errmsg(int errnum) +{ +#ifdef linux +	return strerror(errnum); +#else // linux + +	extern int		sys_nerr; +#ifdef SUN4_x +	extern char		*sys_errlist[]; +#endif +	char			*errbuf; + +	if ((errnum < 0) || (errnum > sys_nerr)) { +		errbuf = getmem(6+1+11+1); +		(void) sprintf(errbuf, catgets(libmksdmsi18n_catd, 1, 127, "Error %d"), errnum); +		return errbuf; +	} else { +#ifdef SUN4_x +		return(sys_errlist[errnum]); +#endif +#ifdef SUN5_0 +		return strerror(errnum); +#endif + +	} +#endif // linux +} + +static char static_buf[MAXPATHLEN*3]; + +/* + *	fatal_mksh(format, args...) + * + *	Print a message and die + * + *	Parameters: + *		format		printf type format string + *		args		Arguments to match the format + */ +/*VARARGS*/ +void +fatal_mksh(char * message, ...) +{ +	va_list args; +	char    *buf = static_buf; +	char	*mksh_fat_err = catgets(libmksdmsi18n_catd, 1, 128, "mksh: Fatal error: "); +	char	*cur_wrk_dir = catgets(libmksdmsi18n_catd, 1, 129, "Current working directory: "); +	int	mksh_fat_err_len = strlen(mksh_fat_err); + +	va_start(args, message); +	(void) fflush(stdout); +	(void) strcpy(buf, mksh_fat_err); +	size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len, +				   sizeof(static_buf) - mksh_fat_err_len, +				   message, args) +			+ mksh_fat_err_len +			+ strlen(cur_wrk_dir) +			+ strlen(get_current_path_mksh()) +			+ 3; // "\n\n" +	va_end(args); +	if (buf_len >= sizeof(static_buf)) { +		buf = getmem(buf_len); +		(void) strcpy(buf, mksh_fat_err); +		va_start(args, message); +		(void) vsprintf(buf + mksh_fat_err_len, message, args); +		va_end(args); +	} +	(void) strcat(buf, "\n"); +/* +	if (report_pwd) { + */ +	if (1) { +		(void) strcat(buf, cur_wrk_dir); +		(void) strcat(buf, get_current_path_mksh()); +		(void) strcat(buf, "\n"); +	} +	(void) fputs(buf, stderr); +	(void) fflush(stderr); +	if (buf != static_buf) { +		retmem_mb(buf); +	} +#ifdef SUN5_0 +	exit_status = 1; +#endif +	exit(1); +} + +/* + *	fatal_reader_mksh(format, args...) + * + *	Parameters: + *		format		printf style format string + *		args		arguments to match the format + */ +/*VARARGS*/ +void +fatal_reader_mksh(char * pattern, ...) +{ +	va_list args; +	char	message[1000]; + +	va_start(args, pattern); +/* +	if (file_being_read != NULL) { +		WCSTOMBS(mbs_buffer, file_being_read); +		if (line_number != 0) { +			(void) sprintf(message, +				       catgets(libmksdmsi18n_catd, 1, 130, "%s, line %d: %s"), +				       mbs_buffer, +				       line_number, +				       pattern); +		} else { +			(void) sprintf(message, +				       "%s: %s", +				       mbs_buffer, +				       pattern); +		} +		pattern = message; +	} + */ + +	(void) fflush(stdout); +	(void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 131, "mksh: Fatal error in reader: ")); +	(void) vfprintf(stderr, pattern, args); +	(void) fprintf(stderr, "\n"); +	va_end(args); + +/* +	if (temp_file_name != NULL) { +		(void) fprintf(stderr, +			       catgets(libmksdmsi18n_catd, 1, 132, "mksh: Temp-file %s not removed\n"), +			       temp_file_name->string_mb); +		temp_file_name = NULL; +	} + */ + +/* +	if (report_pwd) { + */ +	if (1) { +		(void) fprintf(stderr, +			       catgets(libmksdmsi18n_catd, 1, 133, "Current working directory %s\n"), +			       get_current_path_mksh()); +	} +	(void) fflush(stderr); +#ifdef SUN5_0 +	exit_status = 1; +#endif +	exit(1); +} + +/* + *	warning_mksh(format, args...) + * + *	Print a message and continue. + * + *	Parameters: + *		format		printf type format string + *		args		Arguments to match the format + */ +/*VARARGS*/ +void +warning_mksh(char * message, ...) +{ +	va_list args; + +	va_start(args, message); +	(void) fflush(stdout); +	(void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 134, "mksh: Warning: ")); +	(void) vfprintf(stderr, message, args); +	(void) fprintf(stderr, "\n"); +	va_end(args); +/* +	if (report_pwd) { + */ +	if (1) { +		(void) fprintf(stderr, +			       catgets(libmksdmsi18n_catd, 1, 135, "Current working directory %s\n"), +			       get_current_path_mksh()); +	} +	(void) fflush(stderr); +} + +/* + *	get_current_path_mksh() + * + *	Stuff current_path with the current path if it isnt there already. + * + *	Parameters: + * + *	Global variables used: + */ +char * +get_current_path_mksh(void) +{ +	char			pwd[(MAXPATHLEN * MB_LEN_MAX)]; +	static char		*current_path; + +	if (current_path == NULL) { +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +		getcwd(pwd, sizeof(pwd)); +#else +		(void) getwd(pwd); +#endif +		if (pwd[0] == (int) nul_char) { +			pwd[0] = (int) slash_char; +			pwd[1] = (int) nul_char; +		} +		current_path = strdup(pwd); +	} +	return current_path; +} + +/* + *	append_prop(target, type) + * + *	Create a new property and append it to the property list of a Name. + * + *	Return value: + *				A new property block for the target + * + *	Parameters: + *		target		The target that wants a new property + *		type		The type of property being requested + * + *	Global variables used: + */ +Property +append_prop(register Name target, register Property_id type) +{ +	register Property	*insert = &target->prop; +	register Property	prop = *insert; +	register int		size; + +	switch (type) { +	case conditional_prop: +		size = sizeof (struct Conditional); +		break; +	case line_prop: +		size = sizeof (struct Line); +		break; +	case macro_prop: +		size = sizeof (struct _Macro); +		break; +	case makefile_prop: +		size = sizeof (struct Makefile); +		break; +	case member_prop: +		size = sizeof (struct Member); +		break; +	case recursive_prop: +		size = sizeof (struct Recursive); +		break; +	case sccs_prop: +		size = sizeof (struct Sccs); +		break; +	case suffix_prop: +		size = sizeof (struct Suffix); +		break; +	case target_prop: +		size = sizeof (struct Target); +		break; +	case time_prop: +		size = sizeof (struct STime); +		break; +	case vpath_alias_prop: +		size = sizeof (struct Vpath_alias); +		break; +	case long_member_name_prop: +		size = sizeof (struct Long_member_name); +		break; +	case macro_append_prop: +		size = sizeof (struct _Macro_appendix); +		break; +	case env_mem_prop: +		size = sizeof (struct _Env_mem); +		break; +	default: +		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 136, "Internal error. Unknown prop type %d"), type); +	} +	for (; prop != NULL; insert = &prop->next, prop = *insert); +	size += PROPERTY_HEAD_SIZE; +	*insert = prop = (Property) getmem(size); +	memset((char *) prop, 0, size); +	prop->type = type; +	prop->next = NULL; +	return prop; +} + +/* + *	maybe_append_prop(target, type) + * + *	Append a property to the Name if none of this type exists + *	else return the one already there + * + *	Return value: + *				A property of the requested type for the target + * + *	Parameters: + *		target		The target that wants a new property + *		type		The type of property being requested + * + *	Global variables used: + */ +Property +maybe_append_prop(register Name target, register Property_id type) +{ +	register Property	prop; + +	if ((prop = get_prop(target->prop, type)) != NULL) { +		return prop; +	} +	return append_prop(target, type); +} + +/* + *	get_prop(start, type) + * + *	Scan the property list of a Name to find the next property + *	of a given type. + * + *	Return value: + *				The first property of the type, if any left + * + *	Parameters: + *		start		The first property block to check for type + *		type		The type of property block we need + * + *	Global variables used: + */ +Property +get_prop(register Property start, register Property_id type) +{ +	for (; start != NULL; start = start->next) { +		if (start->type == type) { +			return start; +		} +	} +	return NULL; +} + +/* + *	append_string(from, to, length) + * + *	Append a C string to a make string expanding it if nessecary + * + *	Parameters: + *		from		The source (C style) string + *		to		The destination (make style) string + *		length		The length of the from string + * + *	Global variables used: + */ +void +append_string(register wchar_t *from, register String to, register int length) +{ +	if (length == FIND_LENGTH) { +		length = wslen(from); +	} +	if (to->buffer.start == NULL) { +		expand_string(to, 32 + length); +	} +	if (to->buffer.end - to->text.p <= length) { +		expand_string(to, +			      (to->buffer.end - to->buffer.start) * 2 + +			      length); +	} +	if (length > 0) { +		(void) wsncpy(to->text.p, from, length); +		to->text.p += length; +	} +	*(to->text.p) = (int) nul_char; +} + +wchar_t * get_wstring(char *from) { +	if(from == NULL) { +		return NULL; +	} +	getwstring_count++; +	wchar_t * wcbuf = ALLOC_WC(strlen(from) + 1); +	mbstowcs(wcbuf, from, strlen(from)+1); +	return wcbuf; +} + +void +append_string(register char *from, register String to, register int length) +{ +	if (length == FIND_LENGTH) { +		length = strlen(from); +	} +	if (to->buffer.start == NULL) { +		expand_string(to, 32 + length); +	} +	if (to->buffer.end - to->text.p <= length) { +		expand_string(to, +			      (to->buffer.end - to->buffer.start) * 2 + +			      length); +	} +	if (length > 0) { +		(void) mbstowcs(to->text.p, from, length); +		to->text.p += length; +	} +	*(to->text.p) = (int) nul_char; +} + +/* + *	expand_string(string, length) + * + *	Allocate more memory for strings that run out of space. + * + *	Parameters: + *		string		The make style string we want to expand + *		length		The new length we need + * + *	Global variables used: + */ +static void +expand_string(register String string, register int length) +{ +	register wchar_t	*p; + +	if (string->buffer.start == NULL) { +		/* For strings that have no memory allocated */ +		string->buffer.start = +		  string->text.p = +		    string->text.end = +		      ALLOC_WC(length); +		string->buffer.end = string->buffer.start + length; +		string->text.p[0] = (int) nul_char; +		string->free_after_use = true; +		expandstring_count++; +		return; +	} +	if (string->buffer.end - string->buffer.start >= length) { +		/* If we really don't need more memory. */ +		return; +	} +	/* +	 * Get more memory, copy the string and free the old buffer if +	 * it is was malloc()'ed. +	 */ +	expandstring_count++; +	p = ALLOC_WC(length); +	(void) wscpy(p, string->buffer.start); +	string->text.p = p + (string->text.p - string->buffer.start); +	string->text.end = p + (string->text.end - string->buffer.start); +	string->buffer.end = p + length; +	if (string->free_after_use) { +		retmem(string->buffer.start); +	} +	string->buffer.start = p; +	string->free_after_use = true; +} + +/* + *	append_char(from, to) + * + *	Append one char to a make string expanding it if nessecary + * + *	Parameters: + *		from		Single character to append to string + *		to		The destination (make style) string + * + *	Global variables used: + */ +void +append_char(wchar_t from, register String to) +{ +	if (to->buffer.start == NULL) { +		expand_string(to, 32); +	} +	if (to->buffer.end - to->text.p <= 2) { +		expand_string(to, to->buffer.end - to->buffer.start + 32); +	} +	*(to->text.p)++ = from; +	*(to->text.p) = (int) nul_char; +} + +/* + *	handle_interrupt_mksh() + * + *	This is where C-C traps are caught. + */ +void +handle_interrupt_mksh(int) +{ +	(void) fflush(stdout); +	/* Make sure the processes running under us terminate first. */ +	if (childPid > 0) { +		kill(childPid, SIGTERM); +		childPid = -1; +	} +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +	while (wait((int *) NULL) != -1); +#if defined(SUN5_0) +	exit_status = 2; +#endif +#else +	while (wait((union wait *) NULL) != -1); +#endif +	exit(2); +} + +/* + *	setup_interrupt() + * + *	This routine saves the original interrupt handler pointers + * + *	Parameters: + * + *	Static variables used: + *		sigivalue	The original signal handler + *		sigqvalue	The original signal handler + *		sigtvalue	The original signal handler + *		sighvalue	The original signal handler + */ +void +setup_interrupt(register void (*handler) (int)) +{ +#ifdef SUN5_0 +	sigivalue = bsd_signal(SIGINT, SIG_IGN); +	sigqvalue = bsd_signal(SIGQUIT, SIG_IGN); +	sigtvalue = bsd_signal(SIGTERM, SIG_IGN); +	sighvalue = bsd_signal(SIGHUP, SIG_IGN); +#else +	sigivalue = (void (*) (int)) bsd_signal(SIGINT, SIG_IGN); +	sigqvalue = (void (*) (int)) bsd_signal(SIGQUIT, SIG_IGN); +	sigtvalue = (void (*) (int)) bsd_signal(SIGTERM, SIG_IGN); +	sighvalue = (void (*) (int)) bsd_signal(SIGHUP, SIG_IGN); +#endif +	enable_interrupt(handler); +} + + +void +mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n) +{ +	if(mbstowcs(pwcs, s, n) == -1) { +		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 143, "The string `%s' is not valid in current locale"), s); +	} +} + + + +Wstring::Wstring() +{ +	INIT_STRING_FROM_STACK(string, string_buf); +} + +Wstring::Wstring(struct _Name * name) +{ +	INIT_STRING_FROM_STACK(string, string_buf); +	append_string(name->string_mb, &string, name->hash.length); +} + +Wstring::~Wstring() +{ +	if(string.free_after_use) { +		retmem(string.buffer.start); +	} +} + +void +Wstring::init(struct _Name * name) +{ +	if(string.free_after_use) { +		retmem(string.buffer.start); +	} +	INIT_STRING_FROM_STACK(string, string_buf); +	append_string(name->string_mb, &string, name->hash.length); +} + +void +Wstring::init(wchar_t * name, unsigned length) +{ +	INIT_STRING_FROM_STACK(string, string_buf); +	append_string(name, &string, length); +	string.buffer.start[length] = 0; +} + +Boolean +Wstring::equaln(wchar_t * str, unsigned length) +{ +	return (Boolean)IS_WEQUALN(string.buffer.start, str, length); +} + +Boolean +Wstring::equaln(Wstring * str, unsigned length) +{ +	return (Boolean)IS_WEQUALN(string.buffer.start, str->string.buffer.start, length); +} + +Boolean +Wstring::equal(wchar_t * str, unsigned off, unsigned length) +{ +	return (Boolean)IS_WEQUALN(string.buffer.start + off, str, length); +} + +Boolean +Wstring::equal(wchar_t * str, unsigned off) +{ +	return (Boolean)IS_WEQUAL(string.buffer.start + off, str); +} + +Boolean +Wstring::equal(wchar_t * str) +{ +	return equal(str, 0); +} + +Boolean +Wstring::equal(Wstring * str, unsigned off, unsigned length) +{ +	return (Boolean)IS_WEQUALN(string.buffer.start + off, str->string.buffer.start, length); +} + +Boolean +Wstring::equal(Wstring * str) +{ +	return equal(str, 0); +} + +Boolean +Wstring::equal(Wstring * str, unsigned off) +{ +	return (Boolean)IS_WEQUAL(string.buffer.start + off, str->string.buffer.start); +} + +void +Wstring::append_to_str(struct _String * str, unsigned off, unsigned length) +{ +	append_string(string.buffer.start + off, str, length); +} + +Name +Name_set::lookup(const char *key) +{ +	for (entry *node = root; node != 0;) { +		int res = strcmp(key, node->name->string_mb); +		if (res < 0) { +			node = node->left; +		} else if (res > 0) { +			node = node->right; +		} else { +			return node->name; +		} +	} +	return 0; +} + +Name +Name_set::insert(const char *key, Boolean &found) +{ +	Name	name = 0; + +	if (root != 0) { +		for (entry *node = root; name == 0;) { +			int res = strcmp(key, node->name->string_mb); +			if (res < 0) { +				if (node->left != 0) { +					node = node->left; +				} else { +					found = false; +					name = ALLOC(Name); + +					node->left = new entry(name, node); +					rebalance(node); +				} +			} else if (res > 0) { +				if (node->right != 0) { +					node = node->right; +				} else { +					found = false; +					name = ALLOC(Name); + +					node->right = new entry(name, node); +					rebalance(node); +				} +			} else { +				found = true; +				name = node->name; +			} +		} +	} else { +		found = false; +		name = ALLOC(Name); + +		root = new entry(name, 0); +	} +	return name; +} + +void +Name_set::insert(Name name) { +	if (root != 0) { +		for (entry *node = root;;) { +			int res = strcmp(name->string_mb, node->name->string_mb); +			if (res < 0) { +				if (node->left != 0) { +					node = node->left; +				} else { +					node->left = new entry(name, node); +					rebalance(node); +					break; +				} +			} else if (res > 0) { +				if (node->right != 0) { +					node = node->right; +				} else { +					node->right = new entry(name, node); +					rebalance(node); +					break; +				} +			} else { +				// should be an error: inserting already existing name +				break; +			} +		} +	} else { +		root = new entry(name, 0); +	} +} + +void +Name_set::rebalance(Name_set::entry *node) { +	for (; node != 0; node = node->parent) { +		entry *right = node->right; +		entry *left = node->left; + +		unsigned rdepth = (right != 0) ? right->depth : 0; +		unsigned ldepth = (left != 0) ? left->depth : 0; + +		if (ldepth > rdepth + 1) { +			if ((node->left = left->right) != 0) { +				left->right->parent = node; +			} +			if ((left->parent = node->parent) != 0) { +				if (node == node->parent->right) { +					node->parent->right = left; +				} else { +					node->parent->left = left; +				} +			} else { +				root = left; +			} +			left->right = node; +			node->parent = left; + +			node->setup_depth(); +			node = left; +		} else if (rdepth > ldepth + 1) { +			if ((node->right = right->left) != 0) { +				right->left->parent = node; +			} +			if ((right->parent = node->parent) != 0) { +				if (node == node->parent->right) { +					node->parent->right = right; +				} else { +					node->parent->left = right; +				} +			} else { +				root = right; +			} +			right->left = node; +			node->parent = right; + +			node->setup_depth(); +			node = right; +		} +		node->setup_depth(); +	} +} + +Name_set::iterator +Name_set::begin() const { +	for (entry *node = root; node != 0; node = node->left) { +		if (node->left == 0) { +			return iterator(node); +		} +	} +	return iterator(); +} + +Name_set::iterator& +Name_set::iterator::operator++() { +	if (node != 0) { +		if (node->right != 0) { +			node = node->right; +			while (node->left != 0) { +				node = node->left; +			} +		} else { +			while ((node->parent != 0) && (node->parent->right == node)) { +				node = node->parent; +			} +			node = node->parent; +		} +	} +	return *this; +} diff --git a/usr/src/make_src/Make/lib/mksh/src/mksh.cc b/usr/src/make_src/Make/lib/mksh/src/mksh.cc new file mode 100644 index 0000000..98c9601 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/mksh.cc @@ -0,0 +1,286 @@ +/* + * 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 1.22 06/12/12 + */ + +#pragma	ident	"@(#)mksh.cc	1.22	06/12/12" + +/* + *	mksh.cc + * + *	Execute the command(s) of one Make or DMake rule + */ + +/* + * Included files + */ +#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL) /* tolik */ +#	include <avo/util.h> +#endif + +#include <mksh/dosys.h>		/* redirect_io() */ +#include <mksh/misc.h>		/* retmem() */ +#include <mksh/mksh.h> +#include <mksdmsi18n/mksdmsi18n.h> +#include <errno.h> +#include <signal.h> + +#ifdef HP_UX +	extern void (*sigset(int, void (*)(__harg)))(__harg); +#endif + +/* + * 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[]); + +#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */ +/* + *	Execute the command(s) of one Make or DMake rule + */ +int +do_job(Avo_DmakeCommand *cmd_list[], char *env_list[], char *stdout_file, char *stderr_file, char *cwd, char *cnwd, int ignore, int silent, pathpt vroot_path, char *shell, int nice_prio) +{ +	Boolean			always_exec_flag; +	char			*cmd; +	Avo_DmakeCommand	**cmd_list_p; +	Name			command; +	Boolean			do_not_exec_flag; +	Boolean			ignore_flag; +	int			length; +	Boolean			make_refd_flag; +	Boolean			meta_flag; +	char			pathname[MAXPATHLEN]; +	Doname			result; +	Boolean			silent_flag; +	wchar_t			*tmp_wcs_buffer; + +	if ((childPid = fork()) < 0) {	/* error */ +		; +	} else if (childPid > 0) {		/* parent */ +		; +	} else {			/* child, mksh */ +		(void) sigset(SIGCHLD, SIG_DFL); +		enable_interrupt(handle_interrupt_mksh); +		/* set environment variables */ +		set_env_vars(env_list); +		/* redirect stdout and stderr to temp files */ +		dup2(1, 2);	// Because fatal_mksh() prints error messages into +				// stderr but dmake uses stderr for XDR communications +				// and stdout for errors messages. +		redirect_io(stdout_file, stderr_file); +		/* try cd'ing to cwd */ +		if (my_chdir(cwd) != 0) { +			/* try the netpath machine:pathname */ +			if (!avo_netpath_to_path(cnwd, pathname)) { +				fatal_mksh(catgets(libmksdmsi18n_catd, 1, 137, "`cd %s' failed, and conversion of %s to automounter pathname also failed: %s"), cwd, cnwd, strerror(errno)); +			} else if (my_chdir(pathname) != 0) { +				fatal_mksh(catgets(libmksdmsi18n_catd, 1, 138, "`cd %s' and `cd %s' both failed: %s"), cwd, pathname, strerror(errno)); +			} +			/* +			 * change the value of SUNPRO_DEPENDENCIES +			 * to the new path. +			 */ +			change_sunpro_dependencies_value(cwd, pathname); +		} +		init_mksh_globals(shell); +		for (cmd_list_p = cmd_list; +		     *cmd_list_p != (Avo_DmakeCommand *) NULL; +		     cmd_list_p++) { +			if ((*cmd_list_p)->ignore()) { +				ignore_flag = true; +			} else { +				ignore_flag = false; +			} +			if ((*cmd_list_p)->silent()) { +				silent_flag = true; +			} else { +				silent_flag = false; +			} +/* +			if ((*cmd_list_p)->always_exec()) { +				always_exec_flag = true; +			} else { +				always_exec_flag = false; +			} + */ +			always_exec_flag = false; +			if ((*cmd_list_p)->meta()) { +				meta_flag = true; +			} else { +				meta_flag = false; +			} +			if ((*cmd_list_p)->make_refd()) { +				make_refd_flag = true; +			} else { +				make_refd_flag = false; +			} +			if ((*cmd_list_p)->do_not_exec()) { +				do_not_exec_flag = true; +			} else { +				do_not_exec_flag = false; +			} +			do_not_exec_rule = do_not_exec_flag; +			cmd = (*cmd_list_p)->getCmd(); +			if ((length = strlen(cmd)) >= MAXPATHLEN) { +				tmp_wcs_buffer = ALLOC_WC(length + 1); +				(void) mbstowcs(tmp_wcs_buffer, cmd, length + 1); +				command = GETNAME(tmp_wcs_buffer, FIND_LENGTH); +				retmem(tmp_wcs_buffer); +			} else { +				MBSTOWCS(wcs_buffer, cmd); +				command = GETNAME(wcs_buffer, FIND_LENGTH); +			} +			if ((command->hash.length > 0) && +			    (!silent_flag || do_not_exec_flag)) { +				(void) printf("%s\n", command->string_mb); +			} +			result = dosys_mksh(command, +					    ignore_flag, +					    make_refd_flag, +					    false, /* bugs #4085164 & #4990057 */ +					    /* BOOLEAN(silent_flag && ignore_flag), */ +					    always_exec_flag, +					    (Name) NULL, +					    false, +					    NULL, +					    NULL, +					    vroot_path, +					    nice_prio); +			if (result == build_failed) { + +#ifdef PRINT_EXIT_STATUS +				warning_mksh(NOCATGETS("I'm in do_job(), and dosys_mksh() returned result of build_failed.")); +#endif + +				if (silent_flag) { +					(void) printf(catgets(libmksdmsi18n_catd, 1, 139, "The following command caused the error:\n%s\n"), +						      command->string_mb); +				} +				if (!ignore_flag && !ignore) { + +#ifdef PRINT_EXIT_STATUS +					warning_mksh(NOCATGETS("I'm in do_job(), and dosys_mksh() returned result of build_failed, exiting 1.")); +#endif + +					exit(1); +				} +			} +		} + +#ifdef PRINT_EXIT_STATUS +		warning_mksh(NOCATGETS("I'm in do_job(), exiting 0.")); +#endif + +	        exit(0); +	} +        return childPid; +} +#endif /* TEAMWARE_MAKE_CMN */ + +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, NOCATGETS("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(NOCATGETS("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(NOCATGETS("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(NOCATGETS("SUNPRO_DEPENDENCIES")) + +				strlen(buf); +			env = getmem(length); +			(void) sprintf(env, +				       "%s=%s", +				       NOCATGETS("SUNPRO_DEPENDENCIES"), +				       buf); +			(void) putenv(env); +		} +	} +} + + diff --git a/usr/src/make_src/Make/lib/mksh/src/read.cc b/usr/src/make_src/Make/lib/mksh/src/read.cc new file mode 100644 index 0000000..53cd524 --- /dev/null +++ b/usr/src/make_src/Make/lib/mksh/src/read.cc @@ -0,0 +1,174 @@ +/* + * 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.cc 1.11 06/12/12 + */ + +#pragma	ident	"@(#)read.cc	1.11	06/12/12" + +/* + *	read.c + * + *	This file contains the makefile reader. + */ + +/* + * Included files + */ +#include <mksh/misc.h>		/* retmem() */ +#include <mksh/read.h> +#include <mksdmsi18n/mksdmsi18n.h> +#include <sys/uio.h>		/* read() */ +#include <unistd.h>		/* close(), unlink(), read() */ + +#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(catgets(libmksdmsi18n_catd, 1, 140, "Error reading `%s': Premature EOF"), +				      mbs_buffer); +			} else { +				fatal_mksh(catgets(libmksdmsi18n_catd, 1, 141, "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(catgets(libmksdmsi18n_catd, 1, 142, "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; +} + + diff --git a/usr/src/make_src/Make/lib/vroot/Makefile b/usr/src/make_src/Make/lib/vroot/Makefile new file mode 100644 index 0000000..fd663cd --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/Makefile @@ -0,0 +1,29 @@ +# +# 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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.5 06/12/12 +# + +TOP =		../../.. +include $(TOP)/rules/variant.mk +include $(TOP)/rules/derived.mk diff --git a/usr/src/make_src/Make/lib/vroot/src/Makefile b/usr/src/make_src/Make/lib/vroot/src/Makefile new file mode 100644 index 0000000..299c46d --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/Makefile @@ -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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Makefile 1.3 06/12/12 +# + +# Generic makefile for use in src directories.  Knows how to make common things +# in the right $(VARIANT) directory. + +include $(TOP)/rules/variant.mk + +all :=		TARG = all  +install :=		TARG = install  +clean :=		TARG = clean  +test :=		TARG = test +l10n_install :=	TARG = l10n_install +i18n_install :=	TARG = i18n_install + +SRC =		../src +MFLAGS += 	SRC=$(SRC) + +# See $(TOP)/rules/master.mk for how these are built. +%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC +	@ if [ ! -d ../$(VARIANT) ]; then \ +		mkdir ../$(VARIANT) ; \ +	fi +	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@ + +FRC: diff --git a/usr/src/make_src/Make/lib/vroot/src/Variant.mk b/usr/src/make_src/Make/lib/vroot/src/Variant.mk new file mode 100644 index 0000000..b276156 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/Variant.mk @@ -0,0 +1,71 @@ +# +# 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 1996 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# @(#)Variant.mk 1.28 06/12/12 +# + +TOP =		../../../.. +include $(TOP)/rules/master.mk +include $(TOP)/rules/dmake.mk + +PKG_TOP =	$(TOP)/Make +CPPFLAGS +=	-I$(PKG_TOP)/include + +CCSRCS =	\ +		access.cc \ +		args.cc \ +		chdir.cc \ +		chmod.cc \ +		chown.cc \ +		chroot.cc \ +		creat.cc \ +		execve.cc \ +		lock.cc \ +		lstat.cc \ +		mkdir.cc \ +		mount.cc \ +		open.cc \ +		readlink.cc \ +		report.cc \ +		rmdir.cc \ +		stat.cc \ +		statfs.cc \ +		truncate.cc \ +		unlink.cc \ +		unmount.cc \ +		utimes.cc \ +		vroot.cc \ +		setenv.cc + + +HDRS_DIR =	$(PKG_TOP)/include/vroot + +.INIT: $(HDRS_DIR)/args.h $(HDRS_DIR)/report.h $(HDRS_DIR)/vroot.h + +LIBNAME =	libvroot.a +MSG_FILE = libvroot.msg +I18N_DIRS = $(SRC) + +include $(TOP)/Make/lib/Lib.mk +include $(TOP)/rules/lib.mk + diff --git a/usr/src/make_src/Make/lib/vroot/src/access.cc b/usr/src/make_src/Make/lib/vroot/src/access.cc new file mode 100644 index 0000000..83141cc --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/access.cc @@ -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. + */ +/* + * @(#)access.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)access.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/args.cc b/usr/src/make_src/Make/lib/vroot/src/args.cc new file mode 100644 index 0000000..de4ad9b --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/args.cc @@ -0,0 +1,35 @@ +/* + * 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. + */ +/* + * @(#)args.cc 1.3 06/12/12 + */ + +#pragma	ident	"@(#)args.cc	1.3	06/12/12" + +#include <vroot/vroot.h> +#include <vroot/args.h> + +union Args	vroot_args; +int		vroot_result; diff --git a/usr/src/make_src/Make/lib/vroot/src/chdir.cc b/usr/src/make_src/Make/lib/vroot/src/chdir.cc new file mode 100644 index 0000000..c5aa0ac --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/chdir.cc @@ -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. + */ +/* + * @(#)chdir.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)chdir.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/chmod.cc b/usr/src/make_src/Make/lib/vroot/src/chmod.cc new file mode 100644 index 0000000..64cda72 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/chmod.cc @@ -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. + */ +/* + * @(#)chmod.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)chmod.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/chown.cc b/usr/src/make_src/Make/lib/vroot/src/chown.cc new file mode 100644 index 0000000..eeeb2ef --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/chown.cc @@ -0,0 +1,51 @@ +/* + * 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. + */ +/* + * @(#)chown.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)chown.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/chroot.cc b/usr/src/make_src/Make/lib/vroot/src/chroot.cc new file mode 100644 index 0000000..8586a8c --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/chroot.cc @@ -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 1993 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * @(#)chroot.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)chroot.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/creat.cc b/usr/src/make_src/Make/lib/vroot/src/creat.cc new file mode 100644 index 0000000..27aa694 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/creat.cc @@ -0,0 +1,51 @@ +/* + * 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. + */ +/* + * @(#)creat.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)creat.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/execve.cc b/usr/src/make_src/Make/lib/vroot/src/execve.cc new file mode 100644 index 0000000..ec2a268 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/execve.cc @@ -0,0 +1,54 @@ +/* + * 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. + */ +/* + * @(#)execve.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)execve.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/libvroot.msg b/usr/src/make_src/Make/lib/vroot/src/libvroot.msg new file mode 100644 index 0000000..f3a805f --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/libvroot.msg @@ -0,0 +1,38 @@ + +$quote " + + +$set	1 +$ +$ 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 1996 Sun Microsystems, Inc. All rights reserved. +$ Use is subject to license terms. +$ +$ @(#)libvroot.msg 1.2 06/12/12 +$ +142	"file_lock: file %s is already locked.\n" +143	"file_lock: will periodically check the lockfile %s for two minutes.\n" +144	"Current working directory %s\n" +145	"Could not lock file `%s'; " +146	" failed - " +147	"Couldn't write to %s" +148	"Cannot open `%s' for writing\n" +149	"Cannot open %s for writing\n" diff --git a/usr/src/make_src/Make/lib/vroot/src/lock.cc b/usr/src/make_src/Make/lib/vroot/src/lock.cc new file mode 100644 index 0000000..ca5a9a5 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/lock.cc @@ -0,0 +1,196 @@ +/* + * 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. + */ +/* + * @(#)lock.cc 1.17 06/12/12 + */ + +#pragma	ident	"@(#)lock.cc	1.17	06/12/12" + +#include <avo/intl.h>	/* for NOCATGETS */ +#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 <mksdmsi18n/mksdmsi18n.h> +#include <signal.h> +#include <errno.h>			/* errno */ + +#if !defined(linux) +extern	char		*sys_errlist[]; +extern	int		sys_nerr; +#endif + +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, NOCATGETS("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 */ +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +				(void) getcwd(msg, MAXPATHLEN); +#else +				(void) getwd(msg); +#endif +				fprintf(stderr, +					catgets(libmksdmsi18n_catd, 1, 162, "file_lock: file %s is already locked.\n"), +					name); +				fprintf(stderr, +					catgets(libmksdmsi18n_catd, 1, 163, "file_lock: will periodically check the lockfile %s for two minutes.\n"), +					lockname); +				fprintf(stderr, +					catgets(libmksdmsi18n_catd, 1, 144, "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, catgets(libmksdmsi18n_catd, 1, 145, "Could not lock file `%s'; "), file); +	len = strlen(msg); +	sprintf(&msg[len], str, arg1, arg2); +	strcat(msg, catgets(libmksdmsi18n_catd, 1, 146, " failed - ")); +#if !defined(linux) +	if (errno < sys_nerr) { +#ifdef SUN4_x +		strcat(msg, sys_errlist[errno]); +#endif +#ifdef SUN5_0 +		strcat(msg, strerror(errno)); +#endif +	} else { +		len = strlen(msg); +		sprintf(&msg[len], NOCATGETS("errno %d"), errno); +	} +#else +	strcat(msg, strerror(errno)); +#endif +} + diff --git a/usr/src/make_src/Make/lib/vroot/src/lstat.cc b/usr/src/make_src/Make/lib/vroot/src/lstat.cc new file mode 100644 index 0000000..ba938aa --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/lstat.cc @@ -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 1998 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * @(#)lstat.cc 1.6 06/12/12 + */ + +#pragma	ident	"@(#)lstat.cc	1.6	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/mkdir.cc b/usr/src/make_src/Make/lib/vroot/src/mkdir.cc new file mode 100644 index 0000000..7180039 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/mkdir.cc @@ -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. + */ +/* + * @(#)mkdir.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)mkdir.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/mount.cc b/usr/src/make_src/Make/lib/vroot/src/mount.cc new file mode 100644 index 0000000..2769a55 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/mount.cc @@ -0,0 +1,53 @@ +/* + * 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. + */ +/* + * @(#)mount.cc 1.5 06/12/12 + */ + +#pragma	ident	"@(#)mount.cc	1.5	06/12/12" + +#include <sys/types.h> +#include <sys/mount.h> + +#ifndef HP_UX +extern int mount(const char *spec, const char *dir, int mflag, ...); +#endif + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/open.cc b/usr/src/make_src/Make/lib/vroot/src/open.cc new file mode 100644 index 0000000..30b44e6 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/open.cc @@ -0,0 +1,53 @@ +/* + * 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. + */ +/* + * @(#)open.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)open.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/readlink.cc b/usr/src/make_src/Make/lib/vroot/src/readlink.cc new file mode 100644 index 0000000..e0efe5b --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/readlink.cc @@ -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. + */ +/* + * @(#)readlink.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)readlink.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/report.cc b/usr/src/make_src/Make/lib/vroot/src/report.cc new file mode 100644 index 0000000..192eb13 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/report.cc @@ -0,0 +1,396 @@ +/* + * 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. + */ +/* + * @(#)report.cc 1.17 06/12/12 + */ + +#pragma	ident	"@(#)report.cc	1.17	06/12/12" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/param.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <vroot/report.h> +#include <vroot/vroot.h> +#include <mksdmsi18n/mksdmsi18n.h> +#include <avo/intl.h>	/* for NOCATGETS */ +#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); +} + +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +extern "C" { +static void +close_report_file(void) +{ +	(void)fputs("\n", report_file); +	(void)fclose(report_file); +} +} // extern "C" +#else +static void +close_report_file(int, ...) +{ +	(void)fputs("\n", report_file); +	(void)fclose(report_file); +} +#endif + +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. + */ + +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +extern "C" { +static void +close_file(void) +#else +static void +close_file(int, ...) +#endif +{ +	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, NOCATGETS("%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)(catgets(libmksdmsi18n_catd, 1, 147, "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, catgets(libmksdmsi18n_catd, 1, 148, "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, catgets(libmksdmsi18n_catd, 1, 149, "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); +	} +} + +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +} // extern "C" +#endif + +static void +report_dep(char *iflag, char *filename) +{ + +	if (command_output_fp == NULL) { +		sprintf(command_output_tmpfile,  +			NOCATGETS("%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(NOCATGETS("NSE_DEP"))) == NULL) { +			return; +		} +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +		atexit(close_file); +#else +		on_exit(close_file, 0); +#endif +		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(NOCATGETS("NSE_DEP"))) == NULL) { +		return; +	} +	if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) { +		return; +	} +	ptr = strchr(p, ' '); +	if( ! ptr ) { +		return; +	} +	sprintf(filename, NOCATGETS("%s-CPP"), ptr+1); +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +	getcwd(curdir, sizeof(curdir)); +#else +	getwd(curdir); +#endif +	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(register 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; +			} +		} +#if defined(SUN5_0) || defined(HP_UX) || defined(linux) +		atexit(close_report_file); +#else +		(void)on_exit(close_report_file, (char *)report_file); +#endif +		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); +} + +#ifdef MAKE_IT +void +make_it(filename) +	register char	*filename; +{ +	register char	*command; +	register char	*argv[6]; +	register int	pid; +	union wait	foo; + +	if (getenv(SUNPRO_DEPENDENCIES) == NULL) return; +	command= alloca(strlen(filename)+32); +	(void)sprintf(command, NOCATGETS("make %s\n"), filename); +	switch (pid= fork()) { +		case 0: /* child */ +			argv[0]= NOCATGETS("csh"); +			argv[1]= NOCATGETS("-c"); +			argv[2]= command; +			argv[3]= 0;			 +			(void)dup2(2, 1); +			execve(NOCATGETS("/bin/sh"), argv, environ); +			perror(NOCATGETS("execve error")); +			exit(1); +		case -1: /* error */ +			perror(NOCATGETS("fork error")); +		default: /* parent */ +			while (wait(&foo) != pid);}; +} +#endif + diff --git a/usr/src/make_src/Make/lib/vroot/src/rmdir.cc b/usr/src/make_src/Make/lib/vroot/src/rmdir.cc new file mode 100644 index 0000000..48a9a6b --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/rmdir.cc @@ -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 1993 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * @(#)rmdir.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)rmdir.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/setenv.cc b/usr/src/make_src/Make/lib/vroot/src/setenv.cc new file mode 100644 index 0000000..dc135e7 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/setenv.cc @@ -0,0 +1,65 @@ +/* + * 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. + */ +/* + * @(#)setenv.cc 1.6 06/12/12 + */ + +#pragma	ident	"@(#)setenv.cc	1.6	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/stat.cc b/usr/src/make_src/Make/lib/vroot/src/stat.cc new file mode 100644 index 0000000..475a851 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/stat.cc @@ -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 1998 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * @(#)stat.cc 1.6 06/12/12 + */ + +#pragma	ident	"@(#)stat.cc	1.6	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/statfs.cc b/usr/src/make_src/Make/lib/vroot/src/statfs.cc new file mode 100644 index 0000000..ff8ac36 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/statfs.cc @@ -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. + */ +/* + * @(#)statfs.cc 1.5 06/12/12 + */ + +#pragma	ident	"@(#)statfs.cc	1.5	06/12/12" + +#ifndef SUN5_0 + +#include <vroot/vroot.h> +#include <vroot/args.h> +#include <sys/vfs.h> + +static int	statfs_thunk(char *path) +{ +	vroot_result= statfs(path, vroot_args.statfs.buffer); +	return(vroot_result == 0); +} + +int	statfs_vroot(char *path, struct statfs *buffer, pathpt vroot_path, pathpt vroot_vroot) +{ +	vroot_args.statfs.buffer= buffer; +	translate_with_thunk(path, statfs_thunk, vroot_path, vroot_vroot, rw_read); +	return(vroot_result); +} +#endif diff --git a/usr/src/make_src/Make/lib/vroot/src/truncate.cc b/usr/src/make_src/Make/lib/vroot/src/truncate.cc new file mode 100644 index 0000000..d38aa37 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/truncate.cc @@ -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. + */ +/* + * @(#)truncate.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)truncate.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/unlink.cc b/usr/src/make_src/Make/lib/vroot/src/unlink.cc new file mode 100644 index 0000000..71ae091 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/unlink.cc @@ -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 1993 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * @(#)unlink.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)unlink.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/unmount.cc b/usr/src/make_src/Make/lib/vroot/src/unmount.cc new file mode 100644 index 0000000..e90d321 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/unmount.cc @@ -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 1993 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * @(#)unmount.cc 1.5 06/12/12 + */ + +#pragma	ident	"@(#)unmount.cc	1.5	06/12/12" + +#ifndef SUN5_0 +#include <vroot/vroot.h> +#include <vroot/args.h> + +extern int	unmount(char *name); + +static int	unmount_thunk(char *path) +{ +	vroot_result= unmount(path); +	return(vroot_result == 0); +} + +int	unmount_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot) +{ +	translate_with_thunk(path, unmount_thunk, vroot_path, vroot_vroot, rw_read); +	return(vroot_result); +} +#endif diff --git a/usr/src/make_src/Make/lib/vroot/src/utimes.cc b/usr/src/make_src/Make/lib/vroot/src/utimes.cc new file mode 100644 index 0000000..4f670b7 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/utimes.cc @@ -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. + */ +/* + * @(#)utimes.cc 1.4 06/12/12 + */ + +#pragma	ident	"@(#)utimes.cc	1.4	06/12/12" + +#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); +} diff --git a/usr/src/make_src/Make/lib/vroot/src/vroot.cc b/usr/src/make_src/Make/lib/vroot/src/vroot.cc new file mode 100644 index 0000000..1a41c03 --- /dev/null +++ b/usr/src/make_src/Make/lib/vroot/src/vroot.cc @@ -0,0 +1,344 @@ +/* + * 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. + */ +/* + * @(#)vroot.cc 1.11 06/12/12 + */ + +#pragma	ident	"@(#)vroot.cc	1.11	06/12/12" + +#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> + +#include <avo/intl.h>	/* for NOCATGETS */ + +typedef struct { +	short		init; +	pathpt		vector; +	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, NOCATGETS("VIRTUAL_ROOT")}, +	{ 0, NULL, NOCATGETS("PATH")}, +	"", NULL, NULL, NULL, 0, 1}; + +void +add_dir_to_path(register 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); +} + +char * +get_vroot_name(void) +{ +	return(vroot_data.vroot.env_var); +} + +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;};}; +} | 
