SEXP myDoSystem()

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
}