Exemple #1
0
rbn *os_select(rbn *x, int i)
{
	int r;
	r = x->left->size + 1;
	if (i == r)
		return os_select(x->left, i);
	else
		return os_select(x->right, i - r);
}
Exemple #2
0
int exa_select_out(exa_select_handle_t *h, fd_set *set)
{
#if WIN32
    int nb_sock;

    EXA_ASSERT_VERBOSE(h->magic == EXA_SELECT_MAGIC,
                       "Corrupted handle detected %d", h->magic);

    nb_sock = os_select(0 /* ignored */, NULL, set, NULL, &select_timeout);

    if (nb_sock == 0) /* timeout is reached */
    {
        /* reset set because there was actually no event on sockets */
        FD_ZERO(set);
        return -EFAULT;
    }

    return nb_sock > 0 ? 0 : nb_sock;
#else
    if (ioctl(h->fd, EXA_SELECT_OUT, set) == -1)
	return -errno;

    return 0;
#endif
}
Exemple #3
0
static void
check_internal_msg(void)
{
  struct timeval timeout = { .tv_sec = 0, .tv_usec = EXAMSG_TIMEOUT };
  static Examsg msg;
  command_end_t *end;
  int i, ret;

  ret = examsgWaitTimeout(cli_mh, &timeout);

  if (ret < 0 && ret != -ETIME)
    {
      exalog_error("Message wait failed %s (%d)",
	           exa_error_msg(ret), ret);
      return;
    }

  if (ret == -ETIME)
    return;

  ret = examsgRecv(cli_mh, NULL, &msg, sizeof(msg));
  if (ret == 0)
    return;

  EXA_ASSERT_VERBOSE(ret > 0, "Message receive failed: %s (%d)",
                     exa_error_msg(ret), ret);

  if (ret < 0)
    exalog_error("Message receive failed: %s (%d)",
	         exa_error_msg(ret), ret);

  /* The CLI server can only receive EXAMSG_ADM_CLUSTER_CMD_END messages for now */
  EXA_ASSERT(msg.any.type == EXAMSG_ADM_CLUSTER_CMD_END);

  end = (command_end_t *)msg.payload;
  for (i = 0; i < MAX_CONNECTION; i++)
    if (end->cuid == connectlist[i].uid)
      {
	cli_command_end_complete(connectlist[i].fd, &end->err_desc);
	connectlist[i].uid = CMD_UID_INVALID;
	break;
      }
  EXA_ASSERT(i < MAX_CONNECTION);
}

static void
check_tcp_connection(void)
{
  static struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
  fd_set setSave = setSocks;
  int ret, conn_id;

  do
    ret = os_select(FD_SETSIZE, &setSave, NULL,  NULL, &timeout);
  while (ret == -EINTR);

  if (ret < 0)
    {
      /* FIXME should assert ? */
      exalog_debug("Select failed %m");
      return;
    }

  /* Check working sockets */
  for (conn_id = 0; conn_id < MAX_CONNECTION; ++conn_id)
    {
      int sock_fd = connectlist[conn_id].fd;
      if (sock_fd >= 0 && FD_ISSET(sock_fd, &setSave))
	handle_inputdata(conn_id, sock_fd);
    }

  /* Must be done at the end to make sure messages for current
   * working threads are processed first */
  if (FD_ISSET(listen_fd, &setSave))
    accept_new_client();
}

/*-------------------------------------------------------------------------*/
/** \brief Connection thread: wait on xml message and pass the command
 * to the work thread.
 *
 * \param[in] sock_xml: socket xml on which it receives commands.
 *
 */
/*-------------------------------------------------------------------------*/
static void
cli_server(void *data)
{
  int i;

  /* Initialize exalog */
  exalog_as(EXAMSG_ADMIND_ID);
  exalog_debug("cli_server: started");

  /* Initialization */
  FD_ZERO(&setSocks);
  FD_SET(listen_fd, &setSocks);

  for (i = 0; i < MAX_CONNECTION; i++)
    {
      connectlist[i].fd  = -1;
      /* A command cannot be CMD_UID_INVALID, so CMD_UID_INVALID means here
       * no command running */
      connectlist[i].uid = CMD_UID_INVALID;
    }

  while (!stop)
    {
      check_tcp_connection();
      check_internal_msg();
    }

  os_closesocket(listen_fd);

  os_net_cleanup();

  examsgDelMbox(cli_mh, EXAMSG_ADMIND_CLISERVER_ID);
  examsgExit(cli_mh);
}

int
cli_server_start(void)
{
  listen_fd = listen_socket_port(ADMIND_SOCKET_PORT);
  if (listen_fd < 0)
    return listen_fd;

  cli_mh = examsgInit(EXAMSG_ADMIND_CLISERVER_ID);
  if (!cli_mh)
    return -EINVAL;

  /* The mailbox needs to be able to receive command end messages from the
   * event manager; as there can be at most MAX_CONNECTION client connections
   * we can receive at the time at most 10 command end messages. */
  examsgAddMbox(cli_mh, EXAMSG_ADMIND_CLISERVER_ID, MAX_CONNECTION,
	        sizeof(command_end_t));

  stop = false;

  if (!exathread_create_named(&thr_xml_proto,
                              ADMIND_THREAD_STACK_SIZE+MIN_THREAD_STACK_SIZE,
                              &cli_server, NULL, "exa_adm_xml"))
      return -EXA_ERR_DEFAULT;

  return EXA_SUCCESS;
}
int 
main(int argc, char *argv[])
{
	int listenfd;
	int connfd;
	int on = 1;
	struct sockaddr_in serv_addr, cli_addr;
	socklen_t cli_len;
	int client_fd[FD_SETSIZE];/* each for every client  */
	fd_set allset; /* save interested descriptors */
	fd_set rdset; /* select on this set */
	int maxfd;
	int max_indx; /* max index in client_fd[] array */
	int i, n;
	int nready;
	char buf[MAXLINE];

	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		fprintf(stderr, "socket error: %s\n", strerror(errno));
		exit(1);
	}

	os_setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	bzero(&serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port = htons(SERV_PORT);

	if (bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
		fprintf(stderr, "bind error: %s\n", strerror(errno));
		exit(1);
	}
	
	if (listen(listenfd,  LISTEN_QUEUE) < 0) {
		fprintf(stderr, "listern error: %s\n", strerror(errno));
		exit(1);
	}

	for (i=0; i < FD_SETSIZE; i++)
		client_fd[i] = -1;
	
	FD_ZERO(&allset);
	FD_SET(listenfd, &allset);
	maxfd = listenfd;
	max_indx = 0;
	for (; ;) {
		rdset = allset;
		nready  = os_select(maxfd + 1, &rdset, NULL, NULL, NULL); /* select will modify rdset once return */

		/* task 1: listen... accept new connection */
		if(FD_ISSET(listenfd, &rdset)) {
			cli_len = sizeof(cli_addr);
			connfd = os_accept(listenfd, (struct sockaddr *)&cli_addr, &cli_len);

			for (i=0; i < FD_SETSIZE; i++) { /* a new client coming, select a useable fd */
				if (client_fd[i] == -1) {
					client_fd[i] = connfd;
					maxfd = (connfd > maxfd) ? connfd : maxfd;
					break;
				}
			}
			FD_SET(connfd, &allset);
			if (i > max_indx)
				max_indx = i;
			if (--nready <= 0)
				continue;  /* no more readable descriptors */
		}
		
		/* task 2: deal with all  clients' data  */
		for (i=0; i < maxfd; i++) {
			if (client_fd[i] == -1)
				continue;
			if (FD_ISSET(client_fd[i], &rdset)) {
				if ((n = os_read(client_fd[i], buf, MAXLINE)) == 0) {
					close(client_fd[i]);
					FD_CLR(client_fd[i], &allset);
					client_fd[i] = -1;
				}
				else {
#ifdef DEBUG
					os_write(fileno(stdout), buf, n);
#endif
					os_write(client_fd[i], buf, n);
				}
			}
			if (--nready <= 0)
				break;  /* no more readable descriptors */
		}
#if 0

		cli_len = sizeof(cli_addr);
	    if ((connfd = accept(listenfd, (struct sockaddr *)&cli_addr, &cli_len)) < 0) {
			if (errno == EINTR)
				continue;
			else
				os_err_sys("accept error");
		}

			
		if ((childpid = fork()) == 0) {
			close(listenfd);
			echo_string(connfd);
			exit(1);
		}
		close(connfd);
#endif
	}
	return 0;
}