289 lines
5.8 KiB
C
289 lines
5.8 KiB
C
#ident "@(#)makesh.c 1.1 94/10/31 Copyright 1987,1988 Sun Micro"
|
|
|
|
/*
|
|
* makesh.c
|
|
*
|
|
* This program is what make runs on remote systems to execute a command
|
|
* when running in parallel mode.
|
|
*/
|
|
|
|
|
|
#define PARALLEL
|
|
|
|
/*
|
|
* Included files
|
|
*/
|
|
#include "defs.h"
|
|
#include "report.h"
|
|
#include <sys/wait.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
|
|
#define COMPILING_MAKESH
|
|
#include "globals.c"
|
|
#undef COMPILING_MAKESH
|
|
|
|
/*
|
|
* Defined macros
|
|
*/
|
|
|
|
/*
|
|
* typedefs & structs
|
|
*/
|
|
|
|
/*
|
|
* Static variables
|
|
*/
|
|
|
|
/*
|
|
* File table of contents
|
|
*/
|
|
extern void main();
|
|
extern void handle_interrupt();
|
|
extern Name getvar();
|
|
extern Property setvar_daemon();
|
|
extern void await_parallel();
|
|
extern void build_suffix_list();
|
|
extern void finish_children();
|
|
|
|
/*
|
|
* main(argc, argv)
|
|
*
|
|
* This program is used when make is running remote commands.
|
|
* It handles running the make command on the remote system.
|
|
*
|
|
* Parameters:
|
|
* argc You know what this is
|
|
* argv You know what this is
|
|
*
|
|
* Global variables referenced:
|
|
* cached_names Names refd from it
|
|
* vroot_path Set to path we use if env contaions no PATH
|
|
*/
|
|
void
|
|
main(argc, argv)
|
|
register int argc;
|
|
register char *argv[];
|
|
{
|
|
Boolean silent_flag;
|
|
Boolean ignore;
|
|
Name command;
|
|
Doname result;
|
|
|
|
/* Usage: makesh path shell -silent/nosilent command command ... */
|
|
if (argc < 4) {
|
|
(void) fprintf(stderr, "makesh: Too few arguments\n");
|
|
exit(1);
|
|
}
|
|
/* Make the vroot package scan the path using shell semantics */
|
|
set_path_style(0);
|
|
|
|
setup_char_semantics();
|
|
|
|
load_cached_names();
|
|
|
|
setup_interrupt();
|
|
|
|
argv++;
|
|
#ifdef CHECK_CD
|
|
if (chdir(*argv) < 0) {
|
|
(void) sprintf(str,
|
|
"makesh: Unable to connect to %s from %s",
|
|
*argv,
|
|
get_current_path());
|
|
perror(str);
|
|
exit(1);
|
|
}
|
|
#endif
|
|
shell_name = GETNAME(*++argv, FIND_LENGTH);
|
|
|
|
/*
|
|
* Make sure that the NSE_DEP environment variable reflects the current
|
|
* directory on this machine (which may be different due to symlinks).
|
|
*/
|
|
if (getenv("NSE_DEP") != NULL) {
|
|
(void) setenv("NSE_DEP", get_current_path());
|
|
}
|
|
if ((*++argv)[1] == 's') {
|
|
silent = true;
|
|
} else {
|
|
silent = false;
|
|
}
|
|
for (argv++; *argv; argv++) {
|
|
if (**argv == (int) at_char) {
|
|
silent_flag = true;
|
|
(*argv)++;
|
|
} else {
|
|
silent_flag = false;
|
|
}
|
|
if (**argv == (int) hyphen_char) {
|
|
ignore = true;
|
|
(*argv)++;
|
|
} else {
|
|
ignore = false;
|
|
}
|
|
command = GETNAME(*argv, FIND_LENGTH);
|
|
if ((command->hash.length > 0) &&
|
|
!silent_flag &&
|
|
!silent) {
|
|
(void) printf("%s\n", command->string);
|
|
}
|
|
result = dosys(command,
|
|
ignore,
|
|
false,
|
|
BOOLEAN(silent_flag && ignore),
|
|
(Name) NULL);
|
|
if (result == build_failed) {
|
|
if (silent) {
|
|
(void) printf("The following command caused the error:\n%s\n",
|
|
command->string);
|
|
}
|
|
if (!ignore) {
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
exit(0);
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
/*
|
|
* handle_interrupt()
|
|
*
|
|
* This is where C-C traps are caught
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Global variables used:
|
|
*/
|
|
void
|
|
handle_interrupt()
|
|
{
|
|
(void) fflush(stdout);
|
|
/* Make sure the process running under us terminates first */
|
|
while (wait((union wait *) NULL) != -1);
|
|
exit(2);
|
|
}
|
|
|
|
/*
|
|
* getvar(name)
|
|
*
|
|
* Return expanded value of macro. (simplified version from macro.c)
|
|
*
|
|
* Return value:
|
|
* The Name passed in
|
|
* Parameters:
|
|
* A Name
|
|
* Global variables used:
|
|
*/
|
|
Name
|
|
getvar(name)
|
|
register Name name;
|
|
{
|
|
return name;
|
|
}
|
|
|
|
/*
|
|
* setvar_daemon(name, value, append, daemon)
|
|
*
|
|
* Set a macro value, possibly supplying a daemon to be used when
|
|
* referencing the value. (Simplified version from macro.c)
|
|
*
|
|
* Return value:
|
|
* The macro value cell
|
|
*
|
|
* Parameters:
|
|
* name The name of the macro to set
|
|
* value The value to set
|
|
* append Should the value be appended to or set
|
|
* daemon Daemon function to run when reading value
|
|
*
|
|
* Global variables used:
|
|
* makefile_type If reading a makefile some stuff is read only
|
|
* path_name The Name "PATH", compared against
|
|
* virtual_root The Name "VIRTUAL_ROOT", compared against
|
|
* vpath_name The Name "VPATH against
|
|
* vpath_defined Set if the macro VPATH is set
|
|
*/
|
|
Property
|
|
setvar_daemon(name, value, append, daemon)
|
|
register Name name;
|
|
register Name value;
|
|
Boolean append;
|
|
Daemon daemon;
|
|
{
|
|
register Property macro = maybe_append_prop(name, macro_prop);
|
|
String_rec destination;
|
|
char buffer[STRING_BUFFER_LENGTH];
|
|
|
|
if ((makefile_type != reading_nothing) &&
|
|
macro->body.macro.read_only) {
|
|
return macro;
|
|
}
|
|
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);
|
|
if ((macro != NULL) && (macro->body.macro.value != NULL)) {
|
|
append_string(macro->body.macro.value->string,
|
|
&destination,
|
|
(int) macro->body.macro.value->
|
|
hash.length);
|
|
if (value != NULL) {
|
|
append_char((int) space_char, &destination);
|
|
}
|
|
}
|
|
if (value != NULL) {
|
|
append_string(value->string,
|
|
&destination,
|
|
(int) value->hash.length);
|
|
}
|
|
value = GETNAME(destination.buffer.start, FIND_LENGTH);
|
|
if (destination.free_after_use) {
|
|
retmem(destination.buffer.start);
|
|
}
|
|
}
|
|
/* Set the new values in the macro property block */
|
|
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;
|
|
}
|
|
return macro;
|
|
}
|
|
|
|
/* Misc.c calls these but we don't need them */
|
|
|
|
/*ARGSUSED*/
|
|
void
|
|
await_parallel(waitflg)
|
|
Boolean waitflg;
|
|
{
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
void
|
|
build_suffix_list(target_suffix)
|
|
Name target_suffix;
|
|
{
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
void
|
|
finish_children(docheck)
|
|
Boolean docheck;
|
|
{
|
|
}
|