74 lines
2.1 KiB
C++
74 lines
2.1 KiB
C++
#include "__call.h"
|
|
#include "Exception.h"
|
|
#include "MString.h"
|
|
#include <ostream>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
|
|
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.");
|
|
resolveKeyword("pgm");
|
|
for(ix = 0; ix <= 50; ++ix)
|
|
argv[ix] = NULL;
|
|
argv[0] = keywords["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)) {
|
|
resolveKeyword(arg);
|
|
argv[ix] = keywords[arg].c_str();
|
|
} else
|
|
break;
|
|
}
|
|
pipe(fdo);
|
|
pid = fork();
|
|
if(pid == 0) {
|
|
close(fdo[0]);
|
|
dup2(fdo[1], 1);
|
|
if(keywordDefined("input")) {
|
|
resolveKeyword("input");
|
|
coreutils::ZString input(variables["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["pgm"].c_str(), argv, global.envp);
|
|
close(fdo[1]);
|
|
exit(errno);
|
|
}
|
|
close(fdo[1]);
|
|
if(keywordDefined("name")) {
|
|
resolveKeyword("name");
|
|
if(!keywordDefined("scope") || (keywords["scope"] == "global"))
|
|
global.variables[keywords["name"]].read(fdo[0]);
|
|
else if(keywords["scope"] == "local")
|
|
this->local->variables[keywords["name"]].read(fdo[0]);
|
|
else if(keywords["scope"] == "parent")
|
|
this->local->parent->local->variables[keywords["name"]].read(fdo[0]);
|
|
else
|
|
throw coreutils::Exception("scope value is not valid.");
|
|
|
|
} else
|
|
out.read(fdo[0]);
|
|
waitpid(pid, &status, 0);
|
|
if(keywordDefined("error")) {
|
|
resolveKeyword("error");
|
|
global.variables[keywords["error"]] = (status >> 8 & 255);
|
|
}
|
|
}
|
|
|
|
}
|