#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 #include #include #include #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; { }