/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include "tmux.h"
/*
* Main server functions.
*/
/* Client list. */
struct clients clients;
struct clients dead_clients;
/* Mapping of a pollfd to an fd independent of its position in the array. */
struct poll_item {
struct pollfd pfd;
RB_ENTRY(poll_item) entry;
};
RB_HEAD(poll_items, poll_item) poll_items;
int server_poll_cmp(struct poll_item *, struct poll_item *);
struct pollfd *server_poll_lookup(int);
void server_poll_add(int, int);
struct pollfd *server_poll_flatten(int *);
void server_poll_parse(struct pollfd *);
void server_poll_reset(void);
RB_PROTOTYPE(poll_items, poll_item, entry, server_poll_cmp);
RB_GENERATE(poll_items, poll_item, entry, server_poll_cmp);
void server_create_client(int);
int server_create_socket(void);
int server_main(int);
void server_shutdown(void);
int server_should_shutdown(void);
void server_child_signal(void);
void server_fill_windows(void);
void server_handle_windows(void);
void server_fill_clients(void);
void server_handle_clients(void);
void server_accept_client(int);
void server_handle_client(struct client *);
void server_handle_window(struct window *, struct window_pane *);
int server_check_window_bell(struct session *, struct window *);
int server_check_window_activity(struct session *,
struct window *);
int server_check_window_content(struct session *, struct window *,
struct window_pane *);
void server_clean_dead(void);
void server_lost_client(struct client *);
void server_check_window(struct window *);
void server_check_redraw(struct client *);
void server_set_title(struct client *);
void server_check_timers(struct client *);
void server_lock_server(void);
void server_lock_sessions(void);
void server_second_timers(void);
int server_update_socket(void);
int
server_poll_cmp(struct poll_item *pitem1, struct poll_item *pitem2)
{
return (pitem1->pfd.fd - pitem2->pfd.fd);
}
struct pollfd *
server_poll_lookup(int fd)
{
struct poll_item pitem;
pitem.pfd.fd = fd;
return (&RB_FIND(poll_items, &poll_items, &pitem)->pfd);
}
void
server_poll_add(int fd, int events)
{
struct poll_item *pitem;
pitem = xmalloc(sizeof *pitem);
pitem->pfd.fd = fd;
pitem->pfd.events = events;
RB_INSERT(poll_items, &poll_items, pitem);
}
struct pollfd *
server_poll_flatten(int *nfds)
{
struct poll_item *pitem;
struct pollfd *pfds;
pfds = NULL;
*nfds = 0;
RB_FOREACH(pitem, poll_items, &poll_items) {
pfds = xrealloc(pfds, (*nfds) + 1, sizeof *pfds);
pfds[*nfds].fd = pitem->pfd.fd;
pfds[*nfds].events = pitem->pfd.events;
(*nfds)++;
}
return (pfds);
}
void
server_poll_parse(struct pollfd *pfds)
{
struct poll_item *pitem;
int nfds;
nfds = 0;
RB_FOREACH(pitem, poll_items, &poll_items) {
pitem->pfd.revents = pfds[nfds].revents;
nfds++;
}
xfree(pfds);
}
void
server_poll_reset(void
|