summaryrefslogtreecommitdiffstats
authornicm <nicm>2008-06-02 21:08:36 (GMT)
committer nicm <nicm>2008-06-02 21:08:36 (GMT)
commitb5ae4fba0fdc5edb3e81be98b528243a745aff4a (patch) (side-by-side diff)
tree1172209f7c1de7634f34be5f9087fe2b7d1fd4cd
parent195f66e80d4be7f31587217ae28351e1ba53b995 (diff)
downloadtmux-old-b5ae4fba0fdc5edb3e81be98b528243a745aff4a.zip
tmux-old-b5ae4fba0fdc5edb3e81be98b528243a745aff4a.tar.gz
tmux-old-b5ae4fba0fdc5edb3e81be98b528243a745aff4a.tar.bz2
Last bits of basic configuration file. By default in ~/.tmux.conf or specified with -f. Just a list of tmux commands executed when the server is started and before and any session/window is created.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--CHANGES38
-rw-r--r--Makefile5
-rw-r--r--TODO1
-rw-r--r--cfg.c23
-rw-r--r--client.c8
-rw-r--r--cmd-attach-session.c2
-rw-r--r--cmd-bind-key.c2
-rw-r--r--cmd-generic.c4
-rw-r--r--cmd-has-session.c21
-rw-r--r--cmd-kill-window.c2
-rw-r--r--cmd-link-window.c2
-rw-r--r--cmd-new-session.c46
-rw-r--r--cmd-new-window.c2
-rw-r--r--cmd-rename-session.c2
-rw-r--r--cmd-rename-window.c2
-rw-r--r--cmd-select-window.c2
-rw-r--r--cmd-send-keys.c2
-rw-r--r--cmd-set-option.c2
-rw-r--r--cmd-swap-window.c2
-rw-r--r--cmd-switch-client.c2
-rw-r--r--cmd-unbind-key.c2
-rw-r--r--cmd-unlink-window.c2
-rw-r--r--cmd.c3
-rw-r--r--server.c32
-rw-r--r--session.c4
-rw-r--r--tmux.c35
-rw-r--r--tmux.h4
27 files changed, 149 insertions, 103 deletions
diff --git a/CHANGES b/CHANGES
index 7976af5..6185202 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,46 @@
02 June 2008
+* New command, start-server (alias "start"), to start the tmux server and do
+ nothing else. This is good if you have a configuration file which creates
+ windows or sessions (like me): in that case, starting the server the first
+ time tmux new is run is bad since it creates a new session and window (as
+ it is supposed to - starting the server is a side-effect).
+
+ Instead, I have a little script which does the equivalent of:
+
+ tmux has -s0 2>/dev/null || tmux start
+ tmux attach -d -s0
+
+ And I use it to start the server if necessary and attach to my primary
+ session.
+* Basic configuration file in ~/.tmux.conf or specified with -f. This is file
+ contains a set of tmux commands that are run the first time the server is
+ started. The configuration commands are executed before any others, so
+ if you have a configuration file that contains:
+
+ new -d
+ neww -s0
+
+ And you do the following without an existing server running:
+
+ tmux new
+
+ You will end up with two sessions, session 0 with two windows (created by
+ the configuration file) and your client attached to session 1 with one
+ window (created by the command-line command). I'm not completely happy with
+ this, it seems a little non-obvious, but I haven't yet decided what to do
+ about it.
+
+ There is no environment variable handling or other special stuff yet.
+
+ In the future, it might be nice to be able to have per-session configuration
+ settings, probably by having conditionals in the file (so you could, for
+ example, have commands to define a particular window layout that would only
+ be invoked if you called tmux new -smysession and mysession did not already
+ exist).
* BIG CHANGE: -s and -c to specify session name and client name are now passed
after the command rather than before it. So, for example:
tmux -s0 neww
Becomes:
diff --git a/Makefile b/Makefile
index 6682b5e..6494a14 100644
--- a/Makefile
+++ b/Makefile
@@ -24,14 +24,15 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
cmd-list-windows.c cmd-attach-session.c cmd-send-prefix.c \
cmd-refresh-client.c cmd-kill-window.c cmd-list-clients.c \
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
- cmd-paste-buffer.c cmd-new-session.c window-scroll.c window-more.c \
- window-copy.c tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c
+ cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \
+ window-scroll.c window-more.c window-copy.c \
+ tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c
CC?= cc
INCDIRS+= -I. -I- -I/usr/local/include
CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\"" -DMETA="'${META}'"
.ifdef PROFILE
# Don't use ccache
diff --git a/TODO b/TODO
index 4fcdc6f..627da0f 100644
--- a/TODO
+++ b/TODO
@@ -66,12 +66,13 @@
-- it's not kkeypad/kcursor
- fix kkeypad/kcursor
- c/p is still borken in some ways
- tobiasu says it is borken on Linux with aterm + TERM=rxvt
- poll(2) is broken on OS X/Darwin, a workaround for this would be nice
- different screen model? layers perhaps? hmm
+- cfg file improvements: * comments to EOL
---
[18:20] *priteau* i found something in tmux that could be tweaked to be better
[18:21] *priteau* in screen, when you type ^A-D, you can actually keep ctrl down
when typing the D
[18:21] *priteau* in tmux, you have to release ctrl for the command to work
diff --git a/cfg.c b/cfg.c
index 0c8dab2..1789325 100644
--- a/cfg.c
+++ b/cfg.c
@@ -70,13 +70,13 @@ load_cfg(const char *path, char **causep)
argv = NULL;
argc = 0;
buf = NULL;
len = 0;
- line = 1;
+ line = 0;
while ((ch = getc(f)) != EOF) {
switch (ch) {
case '#':
/* Comment: discard until EOL. */
while ((ch = getc(f)) != '\n' && ch != EOF)
;
@@ -95,23 +95,24 @@ load_cfg(const char *path, char **causep)
argv[argc++] = s;
break;
case '\n':
case EOF:
case ' ':
case '\t':
- if (len == 0)
- break;
- buf[len] = '\0';
-
- argv = xrealloc(argv, argc + 1, sizeof (char *));
- argv[argc++] = buf;
+ if (len != 0) {
+ buf[len] = '\0';
- buf = NULL;
- len = 0;
+ argv = xrealloc(
+ argv, argc + 1, sizeof (char *));
+ argv[argc++] = buf;
+
+ buf = NULL;
+ len = 0;
+ }
- if (ch != '\n' && ch != EOF)
+ if ((ch != '\n' && ch != EOF) || argc == 0)
break;
line++;
if ((cmd = cmd_parse(argc, argv, &cause)) == NULL)
goto error;
@@ -120,13 +121,13 @@ load_cfg(const char *path, char **causep)
ctx.curclient = NULL;
ctx.error = cfg_error;
ctx.print = cfg_print;
ctx.cmdclient = NULL;
- ctx.flags = CMD_KEY;
+ ctx.flags = 0;
cfg_cause = NULL;
cmd_exec(cmd, &ctx);
cmd_free(cmd);
if (cfg_cause != NULL) {
cause = cfg_cause;
diff --git a/client.c b/client.c
index 45692ab..9fc6bae 100644
--- a/client.c
+++ b/client.c
@@ -42,19 +42,21 @@ client_init(const char *path, struct client_ctx *cctx, int start_server)
struct msg_identify_data data;
struct winsize ws;
size_t size;
int mode;
u_int retries;
struct buffer *b;
+ pid_t pid;
+ pid = 0;
retries = 0;
retry:
if (stat(path, &sb) != 0) {
if (start_server && errno == ENOENT && retries < 10) {
- if (server_start(path) != 0)
- return (-1);
+ if (pid == 0)
+ pid = server_start(path);
usleep(10000);
retries++;
goto retry;
}
goto fail;
}
@@ -109,13 +111,13 @@ retry:
}
return (0);
fail:
log_warn("server not found");
- return (-1);
+ return (1);
}
int
client_main(struct client_ctx *cctx)
{
struct pollfd pfd;
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 6f0d202..ceeb3f2 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -76,13 +76,13 @@ cmd_attach_session_parse(
if (argc != 0)
goto usage;
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
cmd_attach_session_free(data);
return (-1);
}
void
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index bddc231..7a34736 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -79,13 +79,13 @@ cmd_bind_key_parse(
if ((data->cmd = cmd_parse(argc, argv, cause)) == NULL)
goto error;
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
cmd_bind_key_free(data);
return (-1);
}
diff --git a/cmd-generic.c b/cmd-generic.c
index ecb0b36..6714ef6 100644
--- a/cmd-generic.c
+++ b/cmd-generic.c
@@ -54,13 +54,13 @@ cmd_clientonly_parse(
if (argc != 0)
goto usage;
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(data);
return (-1);
}
void
@@ -126,13 +126,13 @@ cmd_sessiononly_parse(
if (argc != 0)
goto usage;
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(data);
return (-1);
}
void
diff --git a/cmd-has-session.c b/cmd-has-session.c
index e4a178e..40be25f 100644
--- a/cmd-has-session.c
+++ b/cmd-has-session.c
@@ -21,30 +21,33 @@
#include <getopt.h>
#include <string.h>
#include "tmux.h"
/*
- * Cause client to exit with 0 if session exists, or 1 if it doesn't. This
- * is handled in the caller since this doesn't have flag CMD_NOSESSION, so
- * all that is necessary is to exit.
+ * Cause client to report an error and exit with 1 if session doesn't exist.
*/
void cmd_has_session_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
- "",
+ CMD_SESSIONONLY_USAGE,
0,
- NULL,
+ cmd_sessiononly_parse,
cmd_has_session_exec,
- NULL,
- NULL,
- NULL
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
-cmd_has_session_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_has_session_exec(void *ptr, struct cmd_ctx *ctx)
{
+ struct session *s;
+
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-kill-window.c b/cmd-kill-window.c
index 02ee076..bbdd912 100644
--- a/cmd-kill-window.c
+++ b/cmd-kill-window.c
@@ -82,13 +82,13 @@ cmd_kill_window_parse(
if (argc != 0)
goto usage;
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
cmd_kill_window_free(data);
return (-1);
}
diff --git a/cmd-link-window.c b/cmd-link-window.c
index 946af70..48bf4c6 100644
--- a/cmd-link-window.c
+++ b/cmd-link-window.c
@@ -103,13 +103,13 @@ cmd_link_window_parse(
goto error;
}
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
cmd_link_window_free(data);
return (-1);
}
diff --git a/cmd-new-session.c b/cmd-new-session.c
index fa78e0c..c4b9329 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -86,69 +86,83 @@ cmd_new_session_parse(
if (argc == 1)
data->cmd = xstrdup(argv[0]);
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
cmd_new_session_free(data);
return (-1);
}
void
cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_new_session_data *data = ptr;
struct cmd_new_session_data std = { NULL, NULL, NULL, 0 };
struct client *c = ctx->cmdclient;
+ struct session *s;
char *cmd, *cause;
- u_int sy;
+ u_int sx, sy;
if (data == NULL)
data = &std;
if (ctx->flags & CMD_KEY)
return;
- if (!data->flag_detached && !(c->flags & CLIENT_TERMINAL)) {
- ctx->error(ctx, "not a terminal");
- return;
+ if (!data->flag_detached) {
+ if (c == NULL) {
+ ctx->error(ctx, "no client to attach to");
+ return;
+ }
+ if (!(c->flags & CLIENT_TERMINAL)) {
+ ctx->error(ctx, "not a terminal");
+ return;
+ }
}
if (data->name != NULL && session_find(data->name) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->name);
return;
}
- sy = c->sy;
+ cmd = data->cmd;
+ if (cmd == NULL)
+ cmd = default_command;
+
+ sx = 80;
+ sy = 25;
+ if (!data->flag_detached) {
+ sx = c->sx;
+ sy = c->sy;
+ }
if (sy < status_lines)
sy = status_lines + 1;
sy -= status_lines;
if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) {
ctx->error(ctx, "%s", cause);
xfree(cause);
return;
}
- cmd = data->cmd;
- if (cmd == NULL)
- cmd = default_command;
- c->session = session_create(data->name, cmd, c->sx, sy);
- if (c->session == NULL)
+ if ((s = session_create(data->name, cmd, sx, sy)) == NULL)
fatalx("session_create failed");
if (data->winname != NULL) {
- xfree(c->session->curw->window->name);
- c->session->curw->window->name = xstrdup(data->winname);
+ xfree(s->curw->window->name);
+ s->curw->window->name = xstrdup(data->winname);
}
- if (data->flag_detached)
- server_write_client(c, MSG_EXIT, NULL, 0);
- else {
+ if (data->flag_detached) {
+ if (c != NULL)
+ server_write_client(c, MSG_EXIT, NULL, 0);
+ } else {
+ c->session = s;
server_write_client(c, MSG_READY, NULL, 0);
server_redraw_client(c);
}
}
void
diff --git a/cmd-new-window.c b/cmd-new-window.c
index c1933d0..c45b601 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -97,13 +97,13 @@ cmd_new_window_parse(
if (argc == 1)
data->cmd = xstrdup(argv[0]);
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
cmd_new_window_free(data);
return (-1);
}
diff --git a/cmd-rename-session.c b/cmd-rename-session.c
index f1e2b5b..496235a 100644
--- a/cmd-rename-session.c
+++ b/cmd-rename-session.c
@@ -76,13 +76,13 @@ cmd_rename_session_parse(
data->newname = xstrdup(argv[0]);
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
cmd_rename_session_free(data);
return (-1);
}
void
diff --git a/cmd-rename-window.c b/cmd-rename-window.c
index a21832f..b8838cf 100644
--- a/cmd-rename-window.c
+++ b/cmd-rename-window.c
@@ -86,13 +86,13 @@ cmd_rename_window_parse(
data->newname = xstrdup(argv[0]);
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
cmd_rename_window_free(data);
return (-1);
}
diff --git a/cmd-select-window.c b/cmd-select-window.c
index ed67f34..3cb29fa 100644
--- a/cmd-select-window.c
+++ b/cmd-select-window.c
@@ -95,13 +95,13 @@ cmd_select_window_parse(
goto error;
}
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
cmd_select_window_free(data);
return (-1);
}
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index 4e73b1f..d3c27e2 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -92,13 +92,13 @@ cmd_send_keys_parse(
argv++;
}
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
cmd_send_keys_free(data);
return (-1);
}
void
diff --git a/cmd-set-option.c b/cmd-set-option.c
index ddd7a66..60dc596 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -76,13 +76,13 @@ cmd_set_option_parse(
if (argc == 2)
data->value = xstrdup(argv[1]);
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
cmd_set_option_free(data);
return (-1);
}
void
diff --git a/cmd-swap-window.c b/cmd-swap-window.c
index b6ffb01..e7b02bd 100644
--- a/cmd-swap-window.c
+++ b/cmd-swap-window.c
@@ -98,13 +98,13 @@ cmd_swap_window_parse(
goto error;
}
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
cmd_swap_window_free(data);
return (-1);
}
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index f906c51..ef375a3 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -77,13 +77,13 @@ cmd_switch_client_parse(
data->name = xstrdup(argv[0]);
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
cmd_switch_client_free(data);
return (-1);
}
void
diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c
index f036333..de2ade2 100644
--- a/cmd-unbind-key.c
+++ b/cmd-unbind-key.c
@@ -72,13 +72,13 @@ cmd_unbind_key_parse(
goto error;
}
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
xfree(data);
return (-1);
}
diff --git a/cmd-unlink-window.c b/cmd-unlink-window.c
index b3045d4..78adb8d 100644
--- a/cmd-unlink-window.c
+++ b/cmd-unlink-window.c
@@ -82,13 +82,13 @@ cmd_unlink_window_parse(
if (argc != 0)
goto usage;
return (0);
usage:
- usage(cause, "%s %s", self->entry->name, self->entry->usage);
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
cmd_unlink_window_free(data);
return (-1);
}
diff --git a/cmd.c b/cmd.c
index 42e6a90..5f5a93c 100644
--- a/cmd.c
+++ b/cmd.c
@@ -48,12 +48,13 @@ const struct cmd_entry *cmd_table[] = {
&cmd_rename_window_entry,
&cmd_scroll_mode_entry,
&cmd_select_window_entry,
&cmd_send_keys_entry,
&cmd_send_prefix_entry,
&cmd_set_option_entry,
+ &cmd_start_server_entry,
&cmd_swap_window_entry,
&cmd_switch_client_entry,
&cmd_unbind_key_entry,
&cmd_unlink_window_entry,
NULL
};
@@ -125,13 +126,13 @@ ambiguous:
}
s[strlen(s) - 2] = '\0';
xasprintf(cause, "ambiguous command: %s, could be: %s", argv[0], s);
return (NULL);
usage:
- usage(cause, "%s %s", entry->name, entry->usage);
+ xasprintf(cause, "usage: %s %s", entry->name, entry->usage);
return (NULL);
}
void
cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
{
diff --git a/server.c b/server.c
index cc3270e..df1aecb 100644
--- a/server.c
+++ b/server.c
@@ -52,34 +52,45 @@ struct client *server_accept_client(int);
void server_handle_client(struct client *);
void server_handle_window(struct window *);
void server_lost_client(struct client *);
void server_lost_window(struct window *);
/* Fork new server. */
-int
+pid_t
server_start(const char *path)
{
struct sockaddr_un sa;
size_t size;
mode_t mask;
int n, fd, mode;
+ pid_t pid;
char *cause;
- switch (fork()) {
+ switch (pid = fork()) {
case -1:
fatal("fork");
case 0:
break;
default:
- return (0);
+ return (pid);
}
#ifdef DEBUG
xmalloc_clear();
#endif
+ ARRAY_INIT(&windows);
+ ARRAY_INIT(&clients);
+ ARRAY_INIT(&sessions);
+ key_bindings_init();
+
+ if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) {
+ log_warnx("%s", cause);
+ exit(1);
+ }
+
logfile("server");
#ifndef NO_SETPROCTITLE
setproctitle("server (%s)", path);
#endif
log_debug("server started, pid %ld", (long) getpid());
@@ -107,23 +118,16 @@ server_start(const char *path)
fatal("fcntl failed");
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
- /* Load configuration. */
- if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) {
- log_warnx("%s", cause);
- xfree(cause);
- exit(1);
- }
-
if (daemon(1, 1) != 0)
fatal("daemon failed");
log_debug("server daemonised, pid now %ld", (long) getpid());
-
+
n = server_main(path, fd);
#ifdef DEBUG
xmalloc_report(getpid(), "server");
#endif
exit(n);
}
@@ -134,18 +138,12 @@ server_main(const char *srv_path, int srv_fd)
{
struct pollfd *pfds, *pfd;
int nfds;
u_int i;
siginit();
-
- ARRAY_INIT(&windows);
- ARRAY_INIT(&clients);
- ARRAY_INIT(&sessions);
-
- key_bindings_init();
pfds = NULL;
while (!sigterm) {
/* Initialise pollfd array. */
nfds = 1 + ARRAY_LENGTH(&windows) + ARRAY_LENGTH(&clients) * 2;
pfds = xrealloc(pfds, nfds, sizeof *pfds);
diff --git a/session.c b/session.c
index 2834fdc..64e0fd8 100644
--- a/session.c
+++ b/session.c
@@ -114,21 +114,25 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy)
if (session_new(s, NULL, cmd, -1) == NULL) {
session_destroy(s);
return (NULL);
}
session_select(s, 0);
+ log_debug("session %s created", s->name);
+
return (s);
}
/* Destroy a session. */
void
session_destroy(struct session *s)
{
u_int i;
+ log_debug("session %s destroyed", s->name);
+
if (session_index(s, &i) != 0)
fatalx("session not found");
ARRAY_SET(&sessions, i, NULL);
while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL)
ARRAY_TRUNC(&sessions, 1);
diff --git a/tmux.c b/tmux.c
index 98f0091..ac0e7fb 100644
--- a/tmux.c
+++ b/tmux.c
@@ -50,31 +50,21 @@ int debug_level;
int prefix_key = META;
u_char status_colour;
u_int history_limit;
u_int status_lines;
void sighandler(int);
+__dead void usage(void);
-void
-usage(char **ptr, const char *fmt, ...)
+__dead void
+usage(void)
{
- char *msg;
- va_list ap;
-
-#define USAGE "usage: %s [-v] [-f file] [-S socket-path]"
- if (fmt == NULL) {
- xasprintf(ptr, USAGE " command [flags]", __progname);
- } else {
- va_start(ap, fmt);
- xvasprintf(&msg, fmt, ap);
- va_end(ap);
-
- xasprintf(ptr, USAGE " %s", __progname, msg);
- xfree(msg);
- }
-#undef USAGE
+ fprintf(stderr,
+ "usage: %s [-v] [-f file] [-S socket-path] command [flags]",
+ __progname);
+ exit(1);
}
void
logfile(const char *name)
{
FILE *f;
@@ -199,19 +189,19 @@ main(int argc, char **argv)
debug_level++;
break;
case 'V':
printf("%s " BUILD "\n", __progname);
exit(0);
default:
- goto usage;
+ usage();
}
}
argc -= optind;
argv += optind;
if (argc == 0)
- goto usage;
+ usage();
log_open(stderr, LOG_USER, debug_level);
siginit();
status_lines = 1;
status_colour = 0x02;
@@ -272,14 +262,12 @@ main(int argc, char **argv)
if (shell == NULL || *shell == '\0')
shell = _PATH_BSHELL;
}
xasprintf(&default_command, "exec %s", shell);
if ((cmd = cmd_parse(argc, argv, &cause)) == NULL) {
- if (cause == NULL)
- goto usage;
log_warnx("%s", cause);
exit(1);
}
memset(&cctx, 0, sizeof cctx);
client_fill_session(&data);
@@ -351,12 +339,7 @@ out:
buffer_destroy(cctx.srv_out);
#ifdef DEBUG
xmalloc_report(getpid(), "client");
#endif
return (n);
-
-usage:
- usage(&cause, NULL);
- fprintf(stderr, "%s\n", cause);
- exit(1);
}
diff --git a/tmux.h b/tmux.h
index 3e4fcab..b146909 100644
--- a/tmux.h
+++ b/tmux.h
@@ -690,13 +690,12 @@ extern char *paste_buffer;
extern int bell_action;
extern int debug_level;
extern int prefix_key;
extern u_char status_colour;
extern u_int history_limit;
extern u_int status_lines;
-void usage(char **, const char *, ...);
void logfile(const char *);
void siginit(void);
void sigreset(void);
/* cfg.c */
int load_cfg(const char *, char **x);
@@ -756,12 +755,13 @@ extern const struct cmd_entry cmd_rename_session_entry;
extern const struct cmd_entry cmd_rename_window_entry;
extern const struct cmd_entry cmd_scroll_mode_entry;
extern const struct cmd_entry cmd_select_window_entry;
extern const struct cmd_entry cmd_send_keys_entry;
extern const struct cmd_entry cmd_send_prefix_entry;
extern const struct cmd_entry cmd_set_option_entry;
+extern const struct cmd_entry cmd_start_server_entry;
extern const struct cmd_entry cmd_swap_window_entry;
extern const struct cmd_entry cmd_switch_client_entry;
extern const struct cmd_entry cmd_unbind_key_entry;
extern const struct cmd_entry cmd_unlink_window_entry;
void cmd_select_window_default(void **, int);
@@ -806,13 +806,13 @@ void key_bindings_dispatch(int, struct client *);
/* key-string.c */
int key_string_lookup_string(const char *);
const char *key_string_lookup_key(int);
/* server.c */
extern struct clients clients;
-int server_start(const char *);
+pid_t server_start(const char *);
/* server-msg.c */
int server_msg_dispatch(struct client *);
/* server-fn.c */
struct session *server_extract_session(