version 1.15, 2009/07/28 07:03:32 |
version 1.16, 2009/08/07 15:39:10 |
|
|
int |
int |
server_start(char *path) |
server_start(char *path) |
{ |
{ |
int pair[2], srv_fd, null_fd; |
struct client *c; |
char *cause; |
int pair[2], srv_fd; |
char rpathbuf[MAXPATHLEN]; |
char *cause; |
|
char rpathbuf[MAXPATHLEN]; |
|
|
/* The first client is special and gets a socketpair; create it. */ |
/* The first client is special and gets a socketpair; create it. */ |
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) |
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) |
|
|
* Must daemonise before loading configuration as the PID changes so |
* Must daemonise before loading configuration as the PID changes so |
* $TMUX would be wrong for sessions created in the config file. |
* $TMUX would be wrong for sessions created in the config file. |
*/ |
*/ |
if (daemon(1, 1) != 0) |
if (daemon(1, 0) != 0) |
fatal("daemon failed"); |
fatal("daemon failed"); |
|
|
|
logfile("server"); |
|
log_debug("server started, pid %ld", (long) getpid()); |
|
|
ARRAY_INIT(&windows); |
ARRAY_INIT(&windows); |
ARRAY_INIT(&clients); |
ARRAY_INIT(&clients); |
ARRAY_INIT(&sessions); |
ARRAY_INIT(&sessions); |
|
|
start_time = time(NULL); |
start_time = time(NULL); |
socket_path = path; |
socket_path = path; |
|
|
|
if (realpath(socket_path, rpathbuf) == NULL) |
|
strlcpy(rpathbuf, socket_path, sizeof rpathbuf); |
|
log_debug("socket path %s", socket_path); |
|
setproctitle("server (%s)", rpathbuf); |
|
|
|
srv_fd = server_create_socket(); |
|
server_create_client(pair[1]); |
|
|
if (access(SYSTEM_CFG, R_OK) != 0) { |
if (access(SYSTEM_CFG, R_OK) != 0) { |
if (errno != ENOENT) { |
if (errno != ENOENT) { |
log_warn("%s", SYSTEM_CFG); |
xasprintf( |
exit(1); |
&cause, "%s: %s", strerror(errno), SYSTEM_CFG); |
|
goto error; |
} |
} |
} else { |
} else if (load_cfg(SYSTEM_CFG, &cause) != 0) |
if (load_cfg(SYSTEM_CFG, &cause) != 0) { |
goto error; |
log_warnx("%s", cause); |
if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) |
exit(1); |
goto error; |
} |
|
} |
|
if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) { |
|
log_warnx("%s", cause); |
|
exit(1); |
|
} |
|
logfile("server"); |
|
|
|
/* |
exit(server_main(srv_fd)); |
* Close stdin/stdout/stderr. Can't let daemon() do this as they are |
|
* needed until now to print configuration file errors. |
|
*/ |
|
if ((null_fd = open(_PATH_DEVNULL, O_RDWR)) != -1) { |
|
dup2(null_fd, STDIN_FILENO); |
|
dup2(null_fd, STDOUT_FILENO); |
|
dup2(null_fd, STDERR_FILENO); |
|
if (null_fd > 2) |
|
close(null_fd); |
|
} |
|
|
|
log_debug("server started, pid %ld", (long) getpid()); |
error: |
log_debug("socket path %s", socket_path); |
/* Write the error and shutdown the server. */ |
|
c = ARRAY_FIRST(&clients); |
|
|
if (realpath(socket_path, rpathbuf) == NULL) |
server_write_error(c, cause); |
strlcpy(rpathbuf, socket_path, sizeof rpathbuf); |
xfree(cause); |
setproctitle("server (%s)", rpathbuf); |
|
|
|
srv_fd = server_create_socket(); |
server_shutdown(); |
server_create_client(pair[1]); |
c->flags |= CLIENT_BAD; |
|
|
exit(server_main(srv_fd)); |
exit(server_main(srv_fd)); |
} |
} |
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
c = ARRAY_ITEM(&clients, i); |
c = ARRAY_ITEM(&clients, i); |
if (c != NULL) |
if (c != NULL) { |
server_write_client(c, MSG_SHUTDOWN, NULL, 0); |
if (c->flags & CLIENT_BAD) |
|
server_lost_client(c); |
|
else |
|
server_write_client(c, MSG_SHUTDOWN, NULL, 0); |
|
c->flags |= CLIENT_BAD; |
|
} |
} |
} |
} |
} |
|
|
|
|
(*pfd)->fd = -1; |
(*pfd)->fd = -1; |
else { |
else { |
(*pfd)->fd = c->fd; |
(*pfd)->fd = c->fd; |
(*pfd)->events = POLLIN; |
if (!(c->flags & CLIENT_BAD)) |
|
(*pfd)->events = POLLIN; |
if (BUFFER_USED(c->out) > 0) |
if (BUFFER_USED(c->out) > 0) |
(*pfd)->events |= POLLOUT; |
(*pfd)->events |= POLLOUT; |
} |
} |
|
|
server_lost_client(c); |
server_lost_client(c); |
(*pfd) += 2; |
(*pfd) += 2; |
continue; |
continue; |
|
} else if (c->flags & CLIENT_BAD) { |
|
if (BUFFER_USED(c->out) == 0) |
|
server_lost_client(c); |
|
(*pfd) += 2; |
|
continue; |
} else |
} else |
server_msg_dispatch(c); |
server_msg_dispatch(c); |
} |
} |