std::string runCommand(std::string& command) { // Run arbitrary command and return result char buffer[256]; std::string result = ""; std::string error = ""; // Call command FILE* pipe = popen(command.c_str(), "r"); if (!pipe) { error = "running " + command; USR_FATAL(error.c_str()); } // Read output of command into result via buffer while (!feof(pipe)) { if (fgets(buffer, 256, pipe) != NULL) { result += buffer; } } if (pclose(pipe)) { error = command + " did not run successfully"; USR_FATAL(error.c_str()); } return result; }
void testInputFiles(int numFilenames, char* filename[]) { inputFilenames = (const char**)malloc((numFilenames+1)*sizeof(char*)); int i; char achar; for (i = 0; i < numFilenames; i++) { if (!isRecognizedSource(filename[i])) { USR_FATAL(astr("file '", filename[i], "' does not have a recognized suffix")); } // WE SHOULDN"T TRY TO OPEN .h files, just .c and .chpl and .o if (!isCHeader(filename[i])) { FILE* testfile = openInputFile(filename[i]); if (fscanf(testfile, "%c", &achar) != 1) { USR_FATAL(astr("source file '", filename[i], "' is either empty or a directory")); } closeInputFile(testfile); } inputFilenames[i] = astr(filename[i]); } inputFilenames[i] = NULL; if (!foundChplSource) USR_FATAL("Command line contains no .chpl source files"); }
static void setCommentLabel(ArgumentState *arg_state, char* label) { assert(label != NULL); size_t len = strlen(label); if (len != 0) { if (len > sizeof(fDocsCommentLabel)) { USR_FATAL("the label is too large!"); }else if (label[0] != '/' || label[1] != '*') { USR_FATAL("comment label should start with /*"); } else { strcpy(fDocsCommentLabel, label); } } }
void addSourceFiles(int numNewFilenames, const char* filename[]) { static int numInputFiles = 0; int cursor = numInputFiles; char achar; numInputFiles += numNewFilenames; inputFilenames = (const char**)realloc(inputFilenames, (numInputFiles+1)*sizeof(char*)); for (int i = 0; i < numNewFilenames; i++) { if (!isRecognizedSource(filename[i])) { USR_FATAL(astr("file '", filename[i], "' does not have a recognized suffix")); } // WE SHOULDN"T TRY TO OPEN .h files, just .c and .chpl and .o if (!isCHeader(filename[i])) { FILE* testfile = openInputFile(filename[i]); if (fscanf(testfile, "%c", &achar) != 1) { USR_FATAL(astr("source file '", filename[i], "' is either empty or a directory")); } closeInputFile(testfile); } // // Don't add the same file twice -- it's unnecessary and can mess // up things like unprotected headers // bool duplicate = false; const char* newFilename = astr(filename[i]); for (int j = 0; j < cursor; j++) { if (inputFilenames[j] == newFilename) { // legal due to astr() duplicate = true; break; } } if (duplicate) { numInputFiles--; } else { inputFilenames[cursor++] = newFilename; } } inputFilenames[cursor] = NULL; if (!foundChplSource && fUseIPE == false) USR_FATAL("Command line contains no .chpl source files"); }
CallInfo::CallInfo(CallExpr* icall) : call(icall), scope(NULL) { if (SymExpr* se = toSymExpr(call->baseExpr)) name = se->var->name; else if (UnresolvedSymExpr* use = toUnresolvedSymExpr(call->baseExpr)) name = use->unresolved; if (call->numActuals() >= 2) { if (SymExpr* se = toSymExpr(call->get(1))) { if (se->var == gModuleToken) { se->remove(); se = toSymExpr(call->get(1)); INT_ASSERT(se); ModuleSymbol* mod = toModuleSymbol(se->var); INT_ASSERT(mod); se->remove(); scope = mod->block; } } } for_actuals(actual, call) { if (NamedExpr* named = toNamedExpr(actual)) { actualNames.add(named->name); actual = named->actual; } else { actualNames.add(NULL); } SymExpr* se = toSymExpr(actual); INT_ASSERT(se); Type* t = se->var->type; if (t == dtUnknown) USR_FATAL(call, "use of '%s' before encountering its definition, type unknown", se->var->name); if (t->symbol->hasFlag(FLAG_GENERIC)) INT_FATAL(call, "the type of the actual argument '%s' is generic", se->var->name); actuals.add(se->var); } }
static void verifySaveCDir(ArgumentState* arg, char* unused) { if (saveCDir[0] == '-') { USR_FATAL("--savec takes a directory name as its argument\n" " (you specified '%s', assumed to be another flag)", saveCDir); } }
void CallInfo::haltNotWellFormed() const { for (int i = 1; i <= call->numActuals(); i++) { Expr* actual = call->get(i); if (NamedExpr* named = toNamedExpr(actual)) { actual = named->actual; } SymExpr* se = toSymExpr(actual); INT_ASSERT(se); Symbol* sym = se->symbol(); Type* t = sym->type; if (t == dtUnknown && sym->hasFlag(FLAG_TYPE_VARIABLE) == false) { USR_FATAL(call, "use of '%s' before encountering its definition, " "type unknown", sym->name); } else if (t->symbol->hasFlag(FLAG_GENERIC) == true) { INT_FATAL(call, "the type of the actual argument '%s' is generic", sym->name); } } }
static void verifySaveCDir(const ArgumentDescription* desc, const char* unused) { if (saveCDir[0] == '-') { USR_FATAL("--savec takes a directory name as its argument\n" " (you specified '%s', assumed to be another flag)", saveCDir); } }
void closefile(FILE* thefile) { if (fclose(thefile) != 0) { const char* errorstr = "closing file: "; const char* errormsg = astr(errorstr, strerror(errno)); USR_FATAL(errormsg); } }
int mysystem(const char* command, const char* description, bool ignoreStatus) { int status = 0; // Treat a '#' at the start of a line as a comment if (command[0] != '#') { status = system(command); } if (status == -1) { USR_FATAL("system() fork failed"); } else if (status != 0 && ignoreStatus == false) { USR_FATAL(description); } return status; }
int mysystem(const char* command, const char* description, int ignorestatus) { if (printSystemCommands) { printf("%s\n\n", command); } int status = 0; if (command[0] != '#') { status = system(command); } if (status == -1) { USR_FATAL("system() fork failed"); } else if (status != 0 && !ignorestatus) { USR_FATAL(description); } return status; }
const std::string runUtilScript(const char* script) { char buffer[256]; std::string result = ""; FILE* pipe = popen(astr(CHPL_HOME, "/util/", script), "r"); if (!pipe) { USR_FATAL(astr("running $CHPL_HOME/util/", script)); } while (!feof(pipe)) { if (fgets(buffer, 256, pipe) != NULL) { result += buffer; } } if (pclose(pipe)) { USR_FATAL(astr("'$CHPL_HOME/util/", script, "' did not run successfully")); } return result; }
static void setupLogfiles() { if (logging() || fdump_html || *deletedIdFilename) ensureDirExists(log_dir, "ensuring directory for log files exists"); if (log_dir[strlen(log_dir)-1] != '/') strcat(log_dir, "/"); if (fdump_html) { if (!(html_index_file = fopen(astr(log_dir, "index.html"), "w"))) { USR_FATAL("cannot open html index file \"%s\" for writing", astr(log_dir, "index.html")); } dump_index_header(html_index_file); fprintf(html_index_file, "<TABLE CELLPADDING=\"0\" CELLSPACING=\"0\">"); } if (deletedIdFilename[0] != '\0') { deletedIdHandle = fopen(deletedIdFilename, "w"); if (!deletedIdHandle) { USR_FATAL("cannot open file to log deleted AST ids\"%s\" for writing", deletedIdFilename); } } }
static Expr* postFoldNormal(CallExpr* call) { FnSymbol* fn = call->resolvedFunction(); Expr* retval = call; if (fn->retTag == RET_PARAM || fn->hasFlag(FLAG_MAYBE_PARAM) == true) { VarSymbol* ret = toVarSymbol(fn->getReturnSymbol()); if (ret != NULL && ret->immediate != NULL) { retval = new SymExpr(ret); call->replace(retval); } else if (EnumSymbol* es = toEnumSymbol(fn->getReturnSymbol())) { retval = new SymExpr(es); call->replace(retval); } else if (ret == gVoid) { retval = new SymExpr(gVoid); call->replace(retval); } } if (fn->hasFlag(FLAG_MAYBE_TYPE) == true && fn->getReturnSymbol()->hasFlag(FLAG_TYPE_VARIABLE) == true) { fn->retTag = RET_TYPE; } if (fn->retTag == RET_TYPE) { Symbol* ret = fn->getReturnSymbol(); if (ret->type->symbol->hasFlag(FLAG_HAS_RUNTIME_TYPE) == false) { retval = new SymExpr(ret->type->symbol); call->replace(retval); } } if (call->isNamedAstr(astrSequals) == true) { if (SymExpr* lhs = toSymExpr(call->get(1))) { if (lhs->symbol()->hasFlag(FLAG_MAYBE_PARAM) == true || lhs->symbol()->isParameter() == true) { if (paramMap.get(lhs->symbol())) { USR_FATAL(call, "parameter set multiple times"); } } } } return retval; }
// In order to handle accumulating ccflags arguments, the argument // processing calls this function. This function appends the flags // to the ccflags variable, so that multiple --ccflags arguments // all end up together in the ccflags variable (and will end up // being passed to the backend C compiler). static void setCCFlags(const ArgumentDescription* desc, const char* arg) { // Append arg to the end of ccflags. int curlen = strlen(ccflags); int space = sizeof(ccflags) - curlen - 1 - 1; // room for ' ' and \0 int arglen = strlen(arg); if( arglen <= space ) { // add a space if there are already arguments here if( curlen != 0 ) ccflags[curlen++] = ' '; memcpy(&ccflags[curlen], arg, arglen); } else { USR_FATAL("ccflags argument too long"); } }
static void deleteDirLLVM(const char* dirname) { #if HAVE_LLVM_VER >= 50 // LLVM 5 added remove_directories std::error_code err = llvm::sys::fs::remove_directories(dirname, false); if (err) { USR_FATAL("removing directory %s failed: %s\n", dirname, err.message().c_str()); } #else deleteDirSystem(dirname); #endif }
static void setHome(const ArgumentDescription* desc, const char* arg) { // Wipe previous CHPL_HOME when comp flag is given CHPL_HOME[0] = '\0'; // Copy arg into CHPL_HOME size_t arglen = strlen(arg) + 1; // room for \0 if (arglen <= sizeof(CHPL_HOME)) { memcpy(CHPL_HOME, arg, arglen); // Update envMap envMap["CHPL_HOME"] = CHPL_HOME; } else { USR_FATAL("CHPL_HOME argument too long"); } }
static void setupDependentVars(void) { if (developer && !userSetCppLineno) { printCppLineno = false; } #ifndef HAVE_LLVM if (llvmCodegen) USR_FATAL("This compiler was built without LLVM support"); #endif if (specializeCCode && (strcmp(CHPL_TARGET_ARCH, "unknown") == 0)) { USR_WARN("--specialize was set, but CHPL_TARGET_ARCH is 'unknown'. If " "you want any specialization to occur please set CHPL_TARGET_ARCH " "to a proper value."); } }
void ensureDirExists(const char* dirname, const char* explanation) { #ifdef HAVE_LLVM std::error_code err = llvm::sys::fs::create_directories(dirname); if (err) { USR_FATAL("creating directory %s failed: %s\n", dirname, err.message().c_str()); } #else const char* mkdircommand = "mkdir -p "; const char* command = astr(mkdircommand, dirname); mysystem(command, explanation); #endif }
void AstDumpToHtml::init() { if (!(sIndexFP = fopen(astr(log_dir, "index.html"), "w"))) { USR_FATAL("cannot open html index file \"%s\" for writing", astr(log_dir, "index.html")); } fprintf(sIndexFP, "<HTML>\n"); fprintf(sIndexFP, "<HEAD>\n"); fprintf(sIndexFP, "<TITLE> Compilation Dump </TITLE>\n"); fprintf(sIndexFP, "<SCRIPT SRC=\"http://chapel.cray.com/developer/mktree.js\" LANGUAGE=\"JavaScript\"></SCRIPT>"); fprintf(sIndexFP, "<LINK REL=\"stylesheet\" HREF=\"http://chapel.cray.com/developer/mktree.css\">"); fprintf(sIndexFP, "</HEAD>\n"); fprintf(sIndexFP, "<div style=\"text-align: center;\"><big><big><span style=\"font-weight: bold;\">"); fprintf(sIndexFP, "Compilation Dump<br><br></span></big></big>\n"); fprintf(sIndexFP, "<div style=\"text-align: left;\">\n\n"); fprintf(sIndexFP, "<TABLE CELLPADDING=\"0\" CELLSPACING=\"0\">"); }
FILE* openfile(const char* filename, const char* mode, bool fatal) { FILE* newfile = fopen(filename, mode); if (newfile == NULL) { const char* errorstr = "opening "; const char* errormsg = astr(errorstr, filename, ": ", strerror(errno)); if (fatal == true) { USR_FATAL(errormsg); } } return newfile; }
bool AstPrintDocs::enterModSym(ModuleSymbol* node) { // If a module is not supposed to be documented, do not traverse into it (and // skip the documentation). if (node->noDocGen()) { return false; } // If this is a sub module (i.e. other modules were entered and not yet // exited before this one), we want to open a new file in a subdirectory. if (node->name != this->moduleName) { // Create a directory with our module name and store this file in it. static const int dirPerms = S_IRWXU | S_IRWXG | S_IRWXO; int result = mkdir(this->pathWithoutPostfix.c_str(), dirPerms); if (result != 0 && errno != 0 && errno != EEXIST) { USR_FATAL(astr("Failed to create directory: ", this->pathWithoutPostfix.c_str(), " due to: ", strerror(errno))); } std::string parent = ""; if (this->parentName != "") { parent = this->parentName + "."; } parent = parent + this->moduleName; AstPrintDocs *docsVisitor = new AstPrintDocs(node->name, this->pathWithoutPostfix, parent); node->accept(docsVisitor); delete docsVisitor; return false; } // Then print our documentation node->printDocs(this->file, this->tabs, this->parentName); if (fDocsTextOnly) { this->tabs++; } return true; }
static void readConfig(ArgumentState* arg_state, char* arg_unused) { // Expect arg_unused to be a string of either of these forms: // 1. name=value -- set the config param "name" to "value" // 2. name -- set the boolean config param "name" to NOT("name") // if name is not type bool, set it to 0. char *name = strdup(arg_unused); char *value; value = strstr(name, "="); if (value) { *value = '\0'; value++; if (value[0]) { // arg_unused was name=value parseCmdLineConfig(name, value); } else { // arg_unused was name= <blank> USR_FATAL("Missing config param value"); } } else { // arg_unused was just name parseCmdLineConfig(name, ""); } }
static void handleInterrupt(int sig) { USR_FATAL("received interrupt"); }
static void setupChplHome(const char* argv0) { const char* chpl_home = getenv("CHPL_HOME"); char* guess = NULL; // Get the executable path. guess = findProgramPath(argv0); if (guess) { // Determine CHPL_HOME based on the exe path. // Determined exe path, but don't have a env var set // Look for ../../../util/chplenv // Remove the /bin/some-platform/chpl part // from the path. if( guess[0] ) { int j = strlen(guess) - 5; // /bin and '\0' for( ; j >= 0; j-- ) { if( guess[j] == '/' && guess[j+1] == 'b' && guess[j+2] == 'i' && guess[j+3] == 'n' ) { guess[j] = '\0'; break; } } } if( isMaybeChplHome(guess) ) { // OK! } else { // Maybe we are in e.g. /usr/bin. free(guess); guess = NULL; } } if( chpl_home ) { if( strlen(chpl_home) > FILENAME_MAX ) USR_FATAL("$CHPL_HOME=%s path too long", chpl_home); if( guess == NULL ) { // Could not find exe path, but have a env var set strncpy(CHPL_HOME, chpl_home, FILENAME_MAX); } else { // We have env var and found exe path. // Check that they match and emit a warning if not. if( ! isSameFile(chpl_home, guess) ) { // Not the same. Emit warning. USR_WARN("$CHPL_HOME=%s mismatched with executable home=%s", chpl_home, guess); } // Since we have an enviro var, always use that. strncpy(CHPL_HOME, chpl_home, FILENAME_MAX); } } else { if( guess == NULL ) { // Could not find enviro var, and could not // guess at exe's path name. USR_FATAL("$CHPL_HOME must be set to run chpl"); } else { int rc; if( strlen(guess) > FILENAME_MAX ) USR_FATAL("chpl guessed home %s too long", guess); // Determined exe path, but don't have a env var set strncpy(CHPL_HOME, guess, FILENAME_MAX); // Also need to setenv in this case. rc = setenv("CHPL_HOME", guess, 0); if( rc ) USR_FATAL("Could not setenv CHPL_HOME"); } } // Check that the resulting path is a Chapel distribution. if( ! isMaybeChplHome(CHPL_HOME) ) { // Bad enviro var. USR_WARN("CHPL_HOME=%s is not a Chapel distribution", CHPL_HOME); } if( guess ) free(guess); parseCmdLineConfig("CHPL_HOME", astr("\"", CHPL_HOME, "\"")); }
static void checkLLVMCodeGen() { #ifndef HAVE_LLVM if (llvmCodegen) USR_FATAL("This compiler was built without LLVM support"); #endif }
CallExpr* ParamForLoop::foldForResolve() { SymExpr* idxExpr = indexExprGet(); SymExpr* lse = lowExprGet(); SymExpr* hse = highExprGet(); SymExpr* sse = strideExprGet(); if (!lse || !hse || !sse) USR_FATAL(this, "param for loop must be defined over a bounded param range"); VarSymbol* lvar = toVarSymbol(lse->var); VarSymbol* hvar = toVarSymbol(hse->var); VarSymbol* svar = toVarSymbol(sse->var); CallExpr* noop = new CallExpr(PRIM_NOOP); if (!lvar || !hvar || !svar) USR_FATAL(this, "param for loop must be defined over a bounded param range"); if (!lvar->immediate || !hvar->immediate || !svar->immediate) USR_FATAL(this, "param for loop must be defined over a bounded param range"); Symbol* idxSym = idxExpr->var; Symbol* continueSym = continueLabelGet(); Type* idxType = indexType(); IF1_int_type idxSize = (get_width(idxType) == 32) ? INT_SIZE_32 : INT_SIZE_64; // Insert an "insertion marker" for loop unrolling insertAfter(noop); if (is_int_type(idxType)) { int64_t low = lvar->immediate->to_int(); int64_t high = hvar->immediate->to_int(); int64_t stride = svar->immediate->to_int(); if (stride <= 0) { for (int64_t i = high; i >= low; i += stride) { SymbolMap map; map.put(idxSym, new_IntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } else { for (int64_t i = low; i <= high; i += stride) { SymbolMap map; map.put(idxSym, new_IntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } } else { INT_ASSERT(is_uint_type(idxType) || is_bool_type(idxType)); uint64_t low = lvar->immediate->to_uint(); uint64_t high = hvar->immediate->to_uint(); int64_t stride = svar->immediate->to_int(); if (stride <= 0) { for (uint64_t i = high; i >= low; i += stride) { SymbolMap map; map.put(idxSym, new_UIntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } else { for (uint64_t i = low; i <= high; i += stride) { SymbolMap map; map.put(idxSym, new_UIntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } } // Remove the "insertion marker" noop->remove(); // Replace the paramLoop with the NO-OP replace(noop); return noop; }
BlockStmt* ParamForLoop::buildParamForLoop(VarSymbol* indexVar, Expr* range, BlockStmt* stmts) { VarSymbol* lowVar = newParamVar(); VarSymbol* highVar = newParamVar(); VarSymbol* strideVar = newParamVar(); LabelSymbol* breakLabel = new LabelSymbol("_breakLabel"); LabelSymbol* continueLabel = new LabelSymbol("_unused_continueLabel"); CallExpr* call = toCallExpr(range); Expr* low = NULL; Expr* high = NULL; Expr* stride = NULL; BlockStmt* outer = new BlockStmt(); if (call && call->isNamed("chpl_by")) { stride = call->get(2)->remove(); call = toCallExpr(call->get(1)); } else { stride = new SymExpr(new_IntSymbol(1)); } if (call && call->isNamed("chpl_build_bounded_range")) { low = call->get(1)->remove(); high = call->get(1)->remove(); } else { USR_FATAL(range, "iterators for param-for-loops must be bounded literal ranges"); } outer->insertAtTail(new DefExpr(indexVar, new_IntSymbol((int64_t) 0))); outer->insertAtTail(new DefExpr(lowVar)); outer->insertAtTail(new CallExpr(PRIM_MOVE, lowVar, low)); outer->insertAtTail(new DefExpr(highVar)); outer->insertAtTail(new CallExpr(PRIM_MOVE, highVar, high)); outer->insertAtTail(new DefExpr(strideVar)); outer->insertAtTail(new CallExpr(PRIM_MOVE, strideVar, stride)); outer->insertAtTail(new ParamForLoop(indexVar, lowVar, highVar, strideVar, continueLabel, breakLabel, stmts)); // this continueLabel will be replaced by a per-iteration one. outer->insertAtTail(new DefExpr(continueLabel)); outer->insertAtTail(new DefExpr(breakLabel)); return buildChapelStmt(outer); }
void GenerateZMakefile(void) { FILE *zmakefile; char buffer[FILEPATHLEN]; mode_t cmask; sprintf(buffer,"%s/zmake",DESTPATH); if ((zmakefile=fopen(buffer,"w"))==NULL) { USR_FATAL(NULL, "Cannot open file '%s'",buffer); } fprintf(zmakefile, "#!/bin/sh\n\n"); fprintf(zmakefile, "#\n"); fprintf(zmakefile, "# zc automatically generated script to build %s binaries\n", trunc_in_filename); fprintf(zmakefile, "#\n\n"); fprintf(zmakefile, "# quote all args in string QARGS\n"); fprintf(zmakefile, "QARGS=\"\"\n"); fprintf(zmakefile, "while [ $# -gt 0 ] ; do\n"); fprintf(zmakefile, "\tQARGS=\"$QARGS\\\"$1\\\" \"\n"); fprintf(zmakefile, "\tshift\n"); fprintf(zmakefile, "done\n\n"); fprintf(zmakefile, "PROG=%s\n", trunc_in_filename); fprintf(zmakefile, "ZC_INCLS=\""); AddIs(zmakefile); fprintf(zmakefile, "\"\n"); fprintf(zmakefile, "ZC_ADDITIONAL_OBJS=\""); AddOsAndCs(zmakefile); fprintf(zmakefile, "\"\n"); fprintf(zmakefile, "ZC_LIBPATHS=\""); AddBigLs(zmakefile); fprintf(zmakefile, "\"\n"); fprintf(zmakefile, "ZC_LIBS=\""); AddLilLs(zmakefile); fprintf(zmakefile, "\"\n"); if (debug) { fprintf(zmakefile,"CFLAGS=\"-g\"\n"); } fprintf(zmakefile,"\n"); fprintf(zmakefile, "export PROG\n"); fprintf(zmakefile, "export ZC_INCLS\n"); fprintf(zmakefile, "export ZC_ADDITIONAL_OBJS\n"); fprintf(zmakefile, "export ZC_LIBPATHS\n"); fprintf(zmakefile, "export ZC_LIBS\n"); if (debug) { fprintf(zmakefile,"export CFLAGS\n"); } fprintf(zmakefile,"\n"); fprintf(zmakefile, "# ZPLHOME must be set to something non-null\n"); fprintf(zmakefile, "if [ \"$ZPLHOME\" = \"\" ] ; then\n"); fprintf(zmakefile, "\techo \"ERROR: Environment variable ZPLHOME must be set to ZPL home directory.\"\n"); fprintf(zmakefile, "\techo \"Aborting.\"\n"); fprintf(zmakefile, "\texit 2\n"); fprintf(zmakefile, "fi\n\n"); fprintf(zmakefile, "# ZMAKEBASE is the script used to actually compile PROG\n"); fprintf(zmakefile, "ZMAKEBASE=\"$ZPLHOME/etc/zmake.base\"\n\n"); fprintf(zmakefile, "# file $ZMAKEBASE must exist and be readable\n"); fprintf(zmakefile, "if [ ! -r \"$ZMAKEBASE\" ] ; then\n"); fprintf(zmakefile, "\techo \"ERROR: Unable to read zmake.base file.\"\n"); fprintf(zmakefile, "\techo \" ($ZMAKEBASE)\"\n"); fprintf(zmakefile, "\techo \" Make sure environment variable ZPLHOME is properly set.\"\n"); fprintf(zmakefile, "\techo \"Aborting.\"\n"); fprintf(zmakefile, "\texit 2\n"); fprintf(zmakefile, "fi\n\n"); fprintf(zmakefile, "# run the ZMAKEBASE script to actually compile PROG; pass along any arguments\n"); fprintf(zmakefile, "COMMAND=\"\\\"$ZMAKEBASE\\\" $QARGS\"\n"); fprintf(zmakefile, "eval $COMMAND\n\n"); fprintf(zmakefile, "exit $?\n"); fclose(zmakefile); /* make zmake an executable file */ cmask = umask((mode_t)0); umask(cmask); cmask = cmask ^ (S_IRWXU | S_IRWXG | S_IRWXO); chmod(buffer, cmask | S_IXUSR | S_IXGRP | S_IXOTH); /* the warning below is unnec., for if the file exists it has been * chmoded already * if (chmod(buffer, cmask | S_IXUSR | S_IXGRP | S_IXOTH)) { * USR_WARN(NULL, "Cannot chmod file '%s'",buffer); * } */ }