Esempio n. 1
0
/**
 * Run an interactive CLI in non-blocking mode.  Does not allow
 * recursion - only one interactive CLI can be active at the same time.
 * This function will not return until the user exits the CLI.
 *
 * A CLI can only be started from the root mode.  If a parser wants to
 * start a new CLI (for example, when parsing the command line
 * arguments, one of the arguments requests an interactive CLI), a
 * whole new TestBaseCli object should be created and the CLI started on
 * the new object, from the root context.
 */
rw_status_t TestBaseCli::interactive_nb()
{
  if (editline_) {
    std::cerr << "CLI is already running" << std::endl;
    return RW_STATUS_FAILURE;
  }

  if (current_mode_ != root_mode_) {
    std::cerr << "Cannot start CLI outside of root mode context" << std::endl;
    return RW_STATUS_FAILURE;
  }

  editline_ = new CliEditline( *this, stdin, stdout, stderr );
  editline_->nonblocking_mode();

  int fd = fileno(stdin);
  fd_set fds = {0};
  editline_->read_ready();  // Yes, gratuitous read_ready is needed

  while (!editline_->should_quit()) {
    editline_->read_ready();
    FD_SET(fd, &fds);
    int nfds = select( fd+1, &fds, NULL, NULL, NULL );
    if (nfds == 1) {
      RW_ASSERT(FD_ISSET(fd, &fds));
    } else if(nfds == -1) {
      switch (errno) {
        case EINTR:
          continue;
        case EBADF:
        case EINVAL:
        default:
          std::cerr << "Unexpected errno " << errno << std::endl;
          editline_->quit();
      }
    } else {
      RW_ASSERT_NOT_REACHED(); // nfds == 0?
    }
  }

  delete editline_;
  editline_ = NULL;
  mode_end_even_if_root();
  return RW_STATUS_SUCCESS;
}
Esempio n. 2
0
rw_status_t rw_spawn_process(const char *filename, 
                             char *const argv[],
                             int set_pgid,
                             pid_t *child_pid)
{
  pid_t pid;

  pid = fork();
  if (pid < 0) {
    /* fork failed emit error and return */
    perror(NULL);
    return RW_STATUS_SUCCESS;
  } else if (pid == 0) {
    /* child process */

    fprintf(stdout, "filename: %s\n", filename);
    int i = 0;
    while (argv[i] != NULL) {
      fprintf(stdout, "argv[%d]: %s\n", i, argv[i]);
      i++;
    }

    execvp(filename, argv);
    /* should never reach here, unless execvp failed */
    perror(NULL);
    RW_ASSERT_NOT_REACHED();
  } else {
    /* This is the parent process */
    if (set_pgid) {
      /* set the process group id of the child to parent's process group id */
      if (setpgid(pid, getpgrp())) {
        fprintf(stdout, "Failed to set %s (%d) process group id\n", 
                filename, pid);
      }
    }

    if (child_pid) {
      *child_pid = pid;
    }
  }

  return RW_STATUS_SUCCESS;
}
Esempio n. 3
0
/**
 * Handler for RW.CLI internal message
 */
static rw_status_t controller_handle_internal_msg(
                    rwcli_controller_t* inst,
                    rwcli_msg_type_t    msg_type,
                    rwcli_internal_req_t* req,
                    rwcli_internal_rsp_t** rsp)
{
  rw_status_t status = RW_STATUS_SUCCESS;
  switch(msg_type) {
    case RWCLI_MSG_TYPE_GET_TRANSPORT_STATUS:
      status = controller_handle_get_transport_status(inst);
      break;
    case RWCLI_MSG_TYPE_SET_CLI_TRANPORT:
      status = controller_set_cli_transport(inst, req->u.transport_mode);
      break;
    default:
      RW_ASSERT_NOT_REACHED();
  }

  return status;
}