in src/SubprocessUnix.cpp [43:109]
SEXP myDoSystem(SEXP call, SEXP op, SEXP args, SEXP) {
int intern = 0;
int timeout = 0;
int consignals = NA_INTEGER;
int argsCount = Rf_length(args);
Rf_checkArityCall(op, args, call);
if (argsCount < 2 || argsCount > 4) {
Rf_error("RWrapper error: %d arguments passed to .Internal(system) which requires 2, 3 or 4", argsCount);
}
if (!Rf_isValidStringF(CAR(args)))
Rf_error("non-empty character argument expected");
intern = Rf_asLogical(CADR(args));
if (intern == NA_INTEGER)
Rf_error("'intern' must be logical and not NA");
timeout = argsCount >= 3 ? Rf_asInteger(CADDR(args)) : 0;
if (timeout == NA_INTEGER || timeout < 0)
Rf_error("invalid 'timeout' argument");
if (argsCount >= 4) {
consignals = Rf_asLogical(CADDDR(args));
if (consignals == NA_INTEGER) {
Rf_error("'receive.console.signals' must be logical and not NA");
}
}
const void *vmax = vmaxget();
const char *cmd = Rf_translateCharUTF8(STRING_ELT(CAR(args), 0));
const char *c = cmd;
int last_is_amp = 0;
int len = 0;
for(;*c; c += len) {
len = utf8clen(*c);
if (len == 1) {
if (*c == '&')
last_is_amp = 1;
else if (*c != ' ' && *c != '\t' && *c != '\r' && *c != '\n')
last_is_amp = 0;
} else
last_is_amp = 0;
}
/* command ending with & is not supported by timeout */
if (timeout > 0 && last_is_amp) {
Rf_error("Timeout with background running processes is not supported.");
}
vmaxset(vmax);
CPP_BEGIN
DoSystemResult res = myDoSystemImpl(cmd, timeout, intern ? COLLECT : PRINT, "", PRINT, "", "", last_is_amp, consignals);
if (res.timedOut) Rf_warning("command '%s' timed out after %ds", cmd, timeout);
if (intern) {
std::vector<std::string> lines;
std::istringstream stream(res.output);
std::string line;
while (std::getline(stream, line)) {
lines.push_back(line);
}
R_Visible = TRUE;
return makeCharacterVector(lines);
} else {
R_Visible = FALSE;
return toSEXP(res.exitCode);
}
CPP_END
}