JetCore/__call.cpp

63 lines
1.7 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.");
for(ix = 0; ix <= 50; ++ix)
argv[ix] = NULL;
argv[0] = 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] = resolveKeyword(arg).c_str();
} else
break;
}
pipe(fdo);
pid = fork();
if(pid == 0) {
close(fdo[0]);
dup2(fdo[1], 1);
if(keywordDefined("input")) {
coreutils::MString input(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(resolveKeyword("pgm").c_str(), argv, global.envp);
close(fdo[1]);
exit(errno);
}
close(fdo[1]);
if(keywordDefined("name")) {
coreutils::MString value;
value.read(fdo[0]);
storeVariable(resolveKeyword("name"), value, resolveKeyword("scope"));
} else
out.read(fdo[0]);
waitpid(pid, &status, 0);
if(keywordDefined("error")) {
global.variables[resolveKeyword("error")] = (status >> 8 & 255);
}
}
}