#include "__call.h" #include "Exception.h" #include "MString.h" #include #include #include #include #include namespace jet { __call::__call(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent, Tag *local) : Tag(in, parentOut, global, parent, local) { if(hasContainer) throw coreutils::Exception("call tag cannot have a container."); if(!keywordDefined("pgm")) throw coreutils::Exception("pgm keyword must be specified."); for(ix = 0; ix <= 50; ++ix) argv[ix] = NULL; argv[0] = keywords[resolveKeyword("pgm")].c_str(); // TODO: Need to peel off the program name only and pass as argv[0]. for(ix = 1; ix <= 50; ++ix) { coreutils::MString arg("arg"); arg << ix; if(keywordDefined(arg)) { argv[ix] = keywords[resolveKeyword(arg)].c_str(); } else break; } pipe(fdo); pid = fork(); if(pid == 0) { close(fdo[0]); dup2(fdo[1], 1); if(keywordDefined("input")) { coreutils::ZString input(variables[resolveKeyword("input")]); pipe(fdi); if(fork() == 0) { close(fdi[0]); write(fdi[1], input.getData(), input.getLength()); close(fdi[1]); exit(0); } close(fdi[1]); dup2(fdi[0], 0); } rc = execvpe(variables[resolveKeyword("pgm")].c_str(), argv, global.envp); close(fdo[1]); exit(errno); } close(fdo[1]); if(keywordDefined("name")) { storeVariable(keywords[resolveKeyword("name")]); } else out.read(fdo[0]); waitpid(pid, &status, 0); if(keywordDefined("error")) { global.variables[keywords[resolveKeyword("error")]] = (status >> 8 & 255); } } }