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;};}; +} |