Beispiel #1
0
int32_t
server_do(server_p srv)
{
	fd_set	fdset;
	int32_t	n, fd;

	assert(srv != NULL);

	/* Copy cached version of the fd set and call select */
	memcpy(&fdset, &srv->fdset, sizeof(fdset));
	n = select(srv->maxfd + 1, &fdset, NULL, NULL, NULL);
	if (n < 0) {
		if (errno == EINTR)
			return (0);

		log_err("Could not select(%d, %p). %s (%d)",
			srv->maxfd + 1, &fdset, strerror(errno), errno);

		return (-1);
	}

	/* Process  descriptors */
	for (fd = 0; fd < srv->maxfd + 1 && n > 0; fd ++) {
		if (!FD_ISSET(fd, &fdset))
			continue;

		assert(srv->fdidx[fd].valid);
		n --;

		if (srv->fdidx[fd].server)
			server_accept_client(srv, fd);
		else if (server_process_request(srv, fd) != 0)
			server_close_fd(srv, fd);
	}

	return (0);
	
}
Beispiel #2
0
/*
 * Do one server iteration
 */
bool
server_do(server_t *srv)
{
	fd_set	fdset;
	int	n, fd;

	assert(srv != NULL);

	memcpy(&fdset, &srv->fdset, sizeof(fdset));
	n = select(srv->fdmax + 1, &fdset, NULL, NULL, NULL);
	if (n == -1) {
		if (errno == EINTR)
			return true;

		log_err("Could not select(%d, %p). %s (%d)",
		    srv->fdmax + 1, &fdset, strerror(errno), errno);

		return false;
	}

	for (fd = 0; fd < srv->fdmax + 1 && n > 0; fd++) {
		if (!FD_ISSET(fd, &fdset))
			continue;

		assert(srv->fdidx[fd].valid);

		if (srv->fdidx[fd].server)
			server_accept_client(srv, fd);
		else if (!server_process_request(srv, fd))
			server_close_fd(srv, fd);

		n--;
	}

	return true;

}
Beispiel #3
0
static void server_mainloop(void) {
	atexit(server_atexit_handler);
	fd_set new_readfds, new_writefds;
	FD_ZERO(&new_readfds);
	FD_ZERO(&new_writefds);
	FD_SET(server.socket, &new_readfds);
	int new_fdmax = server.socket;
	bool exit_packet_delivered = false;

	if (server.read_pty)
		FD_SET_MAX(server.pty, &new_readfds, new_fdmax);

	while (server.clients || !exit_packet_delivered) {
		int fdmax = new_fdmax;
		fd_set readfds = new_readfds;
		fd_set writefds = new_writefds;
		FD_SET_MAX(server.socket, &readfds, fdmax);

		if (select(fdmax+1, &readfds, &writefds, NULL, NULL) == -1) {
			if (errno == EINTR)
				continue;
			die("server-mainloop");
		}

		FD_ZERO(&new_readfds);
		FD_ZERO(&new_writefds);
		new_fdmax = server.socket;

		bool pty_data = false;

		Packet server_packet, client_packet;

		if (FD_ISSET(server.socket, &readfds))
			server_accept_client();

		if (FD_ISSET(server.pty, &readfds))
			pty_data = server_read_pty(&server_packet);

		for (Client **prev_next = &server.clients, *c = server.clients; c;) {
			if (FD_ISSET(c->socket, &readfds) && server_recv_packet(c, &client_packet)) {
				switch (client_packet.type) {
				case MSG_CONTENT:
					server_write_pty(&client_packet);
					break;
				case MSG_ATTACH:
					c->flags = client_packet.u.i;
					if (c->flags & CLIENT_LOWPRIORITY)
						server_sink_client();
					break;
				case MSG_RESIZE:
					c->state = STATE_ATTACHED;
				case MSG_REDRAW:
					if (!(c->flags & CLIENT_READONLY) && (client_packet.type == MSG_REDRAW || c == server.clients)) {
						debug("server-ioct: TIOCSWINSZ\n");
						ioctl(server.pty, TIOCSWINSZ, &client_packet.u.ws);
					}
					kill(-server.pid, SIGWINCH);
					break;
				case MSG_EXIT:
					exit_packet_delivered = true;
					/* fall through */
				case MSG_DETACH:
					c->state = STATE_DISCONNECTED;
					break;
				default: /* ignore package */
					break;
				}
			}

			if (c->state == STATE_DISCONNECTED) {
				bool first = (c == server.clients);
				Client *t = c->next;
				client_free(c);
				*prev_next = c = t;
				if (first && server.clients) {
					Packet pkt = {
						.type = MSG_RESIZE,
						.len = 0,
					};
					server_send_packet(server.clients, &pkt);
				} else if (!server.clients) {
					server_mark_socket_exec(false, true);
				}
				continue;
			}

			FD_SET_MAX(c->socket, &new_readfds, new_fdmax);

			if (pty_data)
				server_send_packet(c, &server_packet);
			if (!server.running) {
				if (server.exit_status != -1) {
					Packet pkt = {
						.type = MSG_EXIT,
						.u.i = server.exit_status,
						.len = sizeof(pkt.u.i),
					};
					if (!server_send_packet(c, &pkt))
						FD_SET_MAX(c->socket, &new_writefds, new_fdmax);
				} else {
					FD_SET_MAX(c->socket, &new_writefds, new_fdmax);
				}
			}