Beispiel #1
0
/*
 * argv[0]: command
 * argv[1]: for detail output
 * argv[2]: kmemcache.ko path
 * argv[3]: umemcached command
 * argv[4]: args of umemcached
 */
int main(int argc, char *argv[])
{
	assert(argc > 4);

	if (!strcmp(argv[1], "0"))
		close_terminal();

	start_kmc_server(argv + 2);

	return 0;
}
Beispiel #2
0
ErrorCode ProcessSpawner::run(std::function<bool()> preExecAction) {
  if (_pid != 0 || _executablePath.empty())
    return kErrorInvalidArgument;

  //
  // If we have redirection, prepare pipes and handles.
  //
  int fds[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}};
  int term[2] = {-1, -1};
  bool startRedirectThread = false;

  for (size_t n = 0; n < 3; n++) {
    switch (_descriptors[n].mode) {
    case kRedirectConsole:
      // do nothing
      break;

    case kRedirectNull:
      if (n == 0) {
        fds[n][RD] = ::open("/dev/null", O_RDONLY);
      } else {
        fds[n][WR] = ::open("/dev/null", O_WRONLY);
      }
      break;

    case kRedirectFile:
      if (n == 0) {
        fds[n][RD] = ::open(_descriptors[n].path.c_str(), O_RDONLY);
      } else {
        fds[n][WR] = ::open(_descriptors[n].path.c_str(), O_RDWR);
        if (fds[n][WR] < 0) {
          fds[n][WR] =
              ::open(_descriptors[n].path.c_str(), O_CREAT | O_RDWR, 0600);
        }
      }
      break;

    case kRedirectBuffer:
      _outputBuffer.clear();
    // fall-through
    case kRedirectDelegate:
      startRedirectThread = true;
      if (term[0] == -1) {
        if (!open_terminal(term)) {
          return Platform::TranslateError();
        }
      }
      fds[n][RD] = term[RD];
      fds[n][WR] = term[WR];
      break;
    }
  }

  _pid = ::fork();
  if (_pid < 0) {
    close_terminal(term);
    return kErrorNoMemory;
  }

  if (_pid == 0) {
    if (::setgid(::getgid()) == 0) {
      ::setsid();

      for (size_t n = 0; n < 3; n++) {
        switch (_descriptors[n].mode) {
        case kRedirectConsole:
          // do nothing
          break;

        case kRedirectDelegate:
          //
          // We are using the same virtual terminal for all delegate
          // redirections, so dup2() only, do not close. We will close when all
          // FDs have been dup2()'d.
          //
          ::dup2(fds[n][WR], n);
          break;

        default:
          if (n == 0) {
            if (fds[n][WR] != -1) {
              ::close(fds[n][WR]);
            }
            ::dup2(fds[n][RD], n);
            ::close(fds[n][RD]);
          } else {
            if (fds[n][RD] != -1) {
              ::close(fds[n][RD]);
            }
            ::dup2(fds[n][WR], n);
            ::close(fds[n][WR]);
          }
          break;
        }
      }

      close_terminal(term);

      if (!_workingDirectory.empty()) {
        ::chdir(_workingDirectory.c_str());
      }

      std::vector<char *> args;
      args.push_back(const_cast<char *>(_executablePath.c_str()));
      for (auto const &e : _arguments)
        args.push_back(const_cast<char *>(e.c_str()));
      args.push_back(nullptr);

      std::vector<char *> environment;
      for (auto const &env : _environment)
        environment.push_back(const_cast<char *>(
            (new std::string(env.first + '=' + env.second))->c_str()));
      environment.push_back(nullptr);

      if (!preExecAction())
        return kErrorUnknown;

      if (::execve(_executablePath.c_str(), &args[0], &environment[0]) < 0) {
        DS2LOG(Error, "cannot spawn executable %s, error=%s",
               _executablePath.c_str(), strerror(errno));
      }
    }
    ::_exit(127);
  }

  ::close(term[WR]);

  for (size_t n = 0; n < 3; n++) {
    switch (_descriptors[n].mode) {
    case kRedirectConsole:
      // do nothing
      break;

    case kRedirectDelegate:
      _descriptors[n].fd = term[RD];
      break;

    default:
      if (n == 0) {
        if (fds[n][RD] != -1) {
          ::close(fds[n][RD]);
          _descriptors[n].fd = fds[n][WR];
        }
      } else {
        if (fds[n][WR] != -1) {
          ::close(fds[n][WR]);
          _descriptors[n].fd = fds[n][RD];
        }
      }
      break;
    }
  }

  if (startRedirectThread) {
    _delegateThread = std::thread(&ProcessSpawner::redirectionThread, this);
  }

  return kSuccess;
}