summaryrefslogtreecommitdiffstats
authornicm <nicm>2008-06-02 21:08:36 (GMT)
committer nicm <nicm>2008-06-02 21:08:36 (GMT)
commitb5ae4fba0fdc5edb3e81be98b528243a745aff4a (patch) (unidiff)
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,5 +1,43 @@
102 June 2008 102 June 2008
2 2
3* New command, start-server (alias "start"), to start the tmux server and do
4 nothing else. This is good if you have a configuration file which creates
5 windows or sessions (like me): in that case, starting the server the first
6 time tmux new is run is bad since it creates a new session and window (as
7 it is supposed to - starting the server is a side-effect).
8
9 Instead, I have a little script which does the equivalent of:
10
11 tmux has -s0 2>/dev/null || tmux start
12 tmux attach -d -s0
13
14 And I use it to start the server if necessary and attach to my primary
15 session.
16* Basic configuration file in ~/.tmux.conf or specified with -f. This is file
17 contains a set of tmux commands that are run the first time the server is
18 started. The configuration commands are executed before any others, so
19 if you have a configuration file that contains:
20
21 new -d
22 neww -s0
23
24 And you do the following without an existing server running:
25
26 tmux new
27
28 You will end up with two sessions, session 0 with two windows (created by
29 the configuration file) and your client attached to session 1 with one
30 window (created by the command-line command). I'm not completely happy with
31 this, it seems a little non-obvious, but I haven't yet decided what to do
32 about it.
33
34 There is no environment variable handling or other special stuff yet.
35
36 In the future, it might be nice to be able to have per-session configuration
37 settings, probably by having conditionals in the file (so you could, for
38 example, have commands to define a particular window layout that would only
39 be invoked if you called tmux new -smysession and mysession did not already
40 exist).
3* BIG CHANGE: -s and -c to specify session name and client name are now passed 41* BIG CHANGE: -s and -c to specify session name and client name are now passed
4 after the command rather than before it. So, for example: 42 after the command rather than before it. So, for example:
5 43
diff --git a/Makefile b/Makefile
index 6682b5e..6494a14 100644
--- a/Makefile
+++ b/Makefile
@@ -27,8 +27,9 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
27 cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \ 27 cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
28 cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \ 28 cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
29 cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \ 29 cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
30 cmd-paste-buffer.c cmd-new-session.c window-scroll.c window-more.c \ 30 cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \
31 window-copy.c tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c 31 window-scroll.c window-more.c window-copy.c \
32 tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c
32 33
33CC?= cc 34CC?= cc
34INCDIRS+= -I. -I- -I/usr/local/include 35INCDIRS+= -I. -I- -I/usr/local/include
diff --git a/TODO b/TODO
index 4fcdc6f..627da0f 100644
--- a/TODO
+++ b/TODO
@@ -69,6 +69,7 @@
69- tobiasu says it is borken on Linux with aterm + TERM=rxvt 69- tobiasu says it is borken on Linux with aterm + TERM=rxvt
70- poll(2) is broken on OS X/Darwin, a workaround for this would be nice 70- poll(2) is broken on OS X/Darwin, a workaround for this would be nice
71- different screen model? layers perhaps? hmm 71- different screen model? layers perhaps? hmm
72- cfg file improvements: * comments to EOL
72 73
73--- 74---
74[18:20] *priteau* i found something in tmux that could be tweaked to be better 75[18:20] *priteau* i found something in tmux that could be tweaked to be better
diff --git a/cfg.c b/cfg.c
index 0c8dab2..1789325 100644
--- a/cfg.c
+++ b/cfg.c
@@ -73,7 +73,7 @@ load_cfg(const char *path, char **causep)
73 buf = NULL; 73 buf = NULL;
74 len = 0; 74 len = 0;
75 75
76 line = 1; 76 line = 0;
77 while ((ch = getc(f)) != EOF) { 77 while ((ch = getc(f)) != EOF) {
78 switch (ch) { 78 switch (ch) {
79 case '#': 79 case '#':
@@ -98,17 +98,18 @@ load_cfg(const char *path, char **causep)
98 case EOF: 98 case EOF:
99 case ' ': 99 case ' ':
100 case '\t': 100 case '\t':
101 if (len == 0) 101 if (len != 0) {
102 break; 102 buf[len] = '\0';
103 buf[len] = '\0';
104
105 argv = xrealloc(argv, argc + 1, sizeof (char *));
106 argv[argc++] = buf;
107 103
108 buf = NULL; 104 argv = xrealloc(
109 len = 0; 105 argv, argc + 1, sizeof (char *));
106 argv[argc++] = buf;
107
108 buf = NULL;
109 len = 0;
110 }
110 111
111 if (ch != '\n' && ch != EOF) 112 if ((ch != '\n' && ch != EOF) || argc == 0)
112 break; 113 break;
113 line++; 114 line++;
114 115
@@ -123,7 +124,7 @@ load_cfg(const char *path, char **causep)
123 ctx.print = cfg_print; 124 ctx.print = cfg_print;
124 125
125 ctx.cmdclient = NULL; 126 ctx.cmdclient = NULL;
126 ctx.flags = CMD_KEY; 127 ctx.flags = 0;
127 128
128 cfg_cause = NULL; 129 cfg_cause = NULL;
129 cmd_exec(cmd, &ctx); 130 cmd_exec(cmd, &ctx);
diff --git a/client.c b/client.c
index 45692ab..9fc6bae 100644
--- a/client.c
+++ b/client.c
@@ -45,13 +45,15 @@ client_init(const char *path, struct client_ctx *cctx, int start_server)
45 int mode; 45 int mode;
46 u_int retries; 46 u_int retries;
47 struct buffer *b; 47 struct buffer *b;
48 pid_t pid;
48 49
50 pid = 0;
49 retries = 0; 51 retries = 0;
50retry: 52retry:
51 if (stat(path, &sb) != 0) { 53 if (stat(path, &sb) != 0) {
52 if (start_server && errno == ENOENT && retries < 10) { 54 if (start_server && errno == ENOENT && retries < 10) {
53 if (server_start(path) != 0) 55 if (pid == 0)
54 return (-1); 56 pid = server_start(path);
55 usleep(10000); 57 usleep(10000);
56 retries++; 58 retries++;
57 goto retry; 59 goto retry;
@@ -112,7 +114,7 @@ retry:
112 114
113fail: 115fail:
114 log_warn("server not found"); 116 log_warn("server not found");
115 return (-1); 117 return (1);
116} 118}
117 119
118int 120int
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
@@ -79,7 +79,7 @@ cmd_attach_session_parse(
79 return (0); 79 return (0);
80 80
81usage: 81usage:
82 usage(cause, "%s %s", self->entry->name, self->entry->usage); 82 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
83 83
84 cmd_attach_session_free(data); 84 cmd_attach_session_free(data);
85 return (-1); 85 return (-1);
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
@@ -82,7 +82,7 @@ cmd_bind_key_parse(
82 return (0); 82 return (0);
83 83
84usage: 84usage:
85 usage(cause, "%s %s", self->entry->name, self->entry->usage); 85 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
86 86
87error: 87error:
88 cmd_bind_key_free(data); 88 cmd_bind_key_free(data);
diff --git a/cmd-generic.c b/cmd-generic.c
index ecb0b36..6714ef6 100644
--- a/cmd-generic.c
+++ b/cmd-generic.c
@@ -57,7 +57,7 @@ cmd_clientonly_parse(
57 return (0); 57 return (0);
58 58
59usage: 59usage:
60 usage(cause, "%s %s", self->entry->name, self->entry->usage); 60 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
61 61
62 self->entry->free(data); 62 self->entry->free(data);
63 return (-1); 63 return (-1);
@@ -129,7 +129,7 @@ cmd_sessiononly_parse(
129 return (0); 129 return (0);
130 130
131usage: 131usage:
132 usage(cause, "%s %s", self->entry->name, self->entry->usage); 132 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
133 133
134 self->entry->free(data); 134 self->entry->free(data);
135 return (-1); 135 return (-1);
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
@@ -24,27 +24,30 @@
24#include "tmux.h" 24#include "tmux.h"
25 25
26/* 26/*
27 * Cause client to exit with 0 if session exists, or 1 if it doesn't. This 27 * Cause client to report an error and exit with 1 if session doesn't exist.
28 * is handled in the caller since this doesn't have flag CMD_NOSESSION, so
29 * all that is necessary is to exit.
30 */ 28 */
31 29
32 voidcmd_has_session_exec(void *, struct cmd_ctx *); 30 voidcmd_has_session_exec(void *, struct cmd_ctx *);
33 31
34const struct cmd_entry cmd_has_session_entry = { 32const struct cmd_entry cmd_has_session_entry = {
35 "has-session", "has", 33 "has-session", "has",
36 "", 34 CMD_SESSIONONLY_USAGE,
37 0, 35 0,
38 NULL, 36 cmd_sessiononly_parse,
39 cmd_has_session_exec, 37 cmd_has_session_exec,
40 NULL, 38 cmd_sessiononly_send,
41 NULL, 39 cmd_sessiononly_recv,
42 NULL 40 cmd_sessiononly_free
43}; 41};
44 42
45void 43void
46cmd_has_session_exec(unused void *ptr, struct cmd_ctx *ctx) 44cmd_has_session_exec(void *ptr, struct cmd_ctx *ctx)
47{ 45{
46 struct session*s;
47
48 if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
49 return;
50
48 if (ctx->cmdclient != NULL) 51 if (ctx->cmdclient != NULL)
49 server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); 52 server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
50} 53}
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
@@ -85,7 +85,7 @@ cmd_kill_window_parse(
85 return (0); 85 return (0);
86 86
87usage: 87usage:
88 usage(cause, "%s %s", self->entry->name, self->entry->usage); 88 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
89 89
90error: 90error:
91 cmd_kill_window_free(data); 91 cmd_kill_window_free(data);
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
@@ -106,7 +106,7 @@ cmd_link_window_parse(
106 return (0); 106 return (0);
107 107
108usage: 108usage:
109 usage(cause, "%s %s", self->entry->name, self->entry->usage); 109 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
110 110
111error: 111error:
112 cmd_link_window_free(data); 112 cmd_link_window_free(data);
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
@@ -89,7 +89,7 @@ cmd_new_session_parse(
89 return (0); 89 return (0);
90 90
91usage: 91usage:
92 usage(cause, "%s %s", self->entry->name, self->entry->usage); 92 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
93 93
94 cmd_new_session_free(data); 94 cmd_new_session_free(data);
95 return (-1); 95 return (-1);
@@ -101,8 +101,9 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
101 struct cmd_new_session_data*data = ptr; 101 struct cmd_new_session_data*data = ptr;
102 struct cmd_new_session_data std = { NULL, NULL, NULL, 0 }; 102 struct cmd_new_session_data std = { NULL, NULL, NULL, 0 };
103 struct client *c = ctx->cmdclient; 103 struct client *c = ctx->cmdclient;
104 struct session *s;
104 char *cmd, *cause; 105 char *cmd, *cause;
105 u_int sy; 106 u_int sx, sy;
106 107
107 if (data == NULL) 108 if (data == NULL)
108 data = &std; 109 data = &std;
@@ -110,9 +111,15 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
110 if (ctx->flags & CMD_KEY) 111 if (ctx->flags & CMD_KEY)
111 return; 112 return;
112 113
113 if (!data->flag_detached && !(c->flags & CLIENT_TERMINAL)) { 114 if (!data->flag_detached) {
114 ctx->error(ctx, "not a terminal"); 115 if (c == NULL) {
115 return; 116 ctx->error(ctx, "no client to attach to");
117 return;
118 }
119 if (!(c->flags & CLIENT_TERMINAL)) {
120 ctx->error(ctx, "not a terminal");
121 return;
122 }
116 } 123 }
117 124
118 if (data->name != NULL && session_find(data->name) != NULL) { 125 if (data->name != NULL && session_find(data->name) != NULL) {
@@ -120,7 +127,16 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
120 return; 127 return;
121 } 128 }
122 129
123 sy = c->sy; 130 cmd = data->cmd;
131 if (cmd == NULL)
132 cmd = default_command;
133
134 sx = 80;
135 sy = 25;
136 if (!data->flag_detached) {
137 sx = c->sx;
138 sy = c->sy;
139 }
124 if (sy < status_lines) 140 if (sy < status_lines)
125 sy = status_lines + 1; 141 sy = status_lines + 1;
126 sy -= status_lines; 142 sy -= status_lines;
@@ -131,21 +147,19 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
131 return; 147 return;
132 } 148 }
133 149
134 cmd = data->cmd;
135 if (cmd == NULL)
136 cmd = default_command;
137 150
138 c->session = session_create(data->name, cmd, c->sx, sy); 151 if ((s = session_create(data->name, cmd, sx, sy)) == NULL)
139 if (c->session == NULL)
140 fatalx("session_create failed"); 152 fatalx("session_create failed");
141 if (data->winname != NULL) { 153 if (data->winname != NULL) {
142 xfree(c->session->curw->window->name); 154 xfree(s->curw->window->name);
143 c->session->curw->window->name = xstrdup(data->winname); 155 s->curw->window->name = xstrdup(data->winname);
144 } 156 }
145 157
146 if (data->flag_detached) 158 if (data->flag_detached) {
147 server_write_client(c, MSG_EXIT, NULL, 0); 159 if (c != NULL)
148 else { 160 server_write_client(c, MSG_EXIT, NULL, 0);
161 } else {
162 c->session = s;
149 server_write_client(c, MSG_READY, NULL, 0); 163 server_write_client(c, MSG_READY, NULL, 0);
150 server_redraw_client(c); 164 server_redraw_client(c);
151 } 165 }
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
@@ -100,7 +100,7 @@ cmd_new_window_parse(
100 return (0); 100 return (0);
101 101
102usage: 102usage:
103 usage(cause, "%s %s", self->entry->name, self->entry->usage); 103 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
104 104
105error: 105error:
106 cmd_new_window_free(data); 106 cmd_new_window_free(data);
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
@@ -79,7 +79,7 @@ cmd_rename_session_parse(
79 return (0); 79 return (0);
80 80
81usage: 81usage:
82 usage(cause, "%s %s", self->entry->name, self->entry->usage); 82 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
83 83
84 cmd_rename_session_free(data); 84 cmd_rename_session_free(data);
85 return (-1); 85 return (-1);
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
@@ -89,7 +89,7 @@ cmd_rename_window_parse(
89 return (0); 89 return (0);
90 90
91usage: 91usage:
92 usage(cause, "%s %s", self->entry->name, self->entry->usage); 92 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
93 93
94error: 94error:
95 cmd_rename_window_free(data); 95 cmd_rename_window_free(data);
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
@@ -98,7 +98,7 @@ cmd_select_window_parse(
98 return (0); 98 return (0);
99 99
100usage: 100usage:
101 usage(cause, "%s %s", self->entry->name, self->entry->usage); 101 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
102 102
103error: 103error:
104 cmd_select_window_free(data); 104 cmd_select_window_free(data);
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
@@ -95,7 +95,7 @@ cmd_send_keys_parse(
95 return (0); 95 return (0);
96 96
97usage: 97usage:
98 usage(cause, "%s %s", self->entry->name, self->entry->usage); 98 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
99 99
100 cmd_send_keys_free(data); 100 cmd_send_keys_free(data);
101 return (-1); 101 return (-1);
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
@@ -79,7 +79,7 @@ cmd_set_option_parse(
79 return (0); 79 return (0);
80 80
81usage: 81usage:
82 usage(cause, "%s %s", self->entry->name, self->entry->usage); 82 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
83 83
84 cmd_set_option_free(data); 84 cmd_set_option_free(data);
85 return (-1); 85 return (-1);
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
@@ -101,7 +101,7 @@ cmd_swap_window_parse(
101 return (0); 101 return (0);
102 102
103usage: 103usage:
104 usage(cause, "%s %s", self->entry->name, self->entry->usage); 104 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
105 105
106error: 106error:
107 cmd_swap_window_free(data); 107 cmd_swap_window_free(data);
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
@@ -80,7 +80,7 @@ cmd_switch_client_parse(
80 return (0); 80 return (0);
81 81
82usage: 82usage:
83 usage(cause, "%s %s", self->entry->name, self->entry->usage); 83 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
84 84
85 cmd_switch_client_free(data); 85 cmd_switch_client_free(data);
86 return (-1); 86 return (-1);
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
@@ -75,7 +75,7 @@ cmd_unbind_key_parse(
75 return (0); 75 return (0);
76 76
77usage: 77usage:
78 usage(cause, "%s %s", self->entry->name, self->entry->usage); 78 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
79 79
80error: 80error:
81 xfree(data); 81 xfree(data);
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
@@ -85,7 +85,7 @@ cmd_unlink_window_parse(
85 return (0); 85 return (0);
86 86
87usage: 87usage:
88 usage(cause, "%s %s", self->entry->name, self->entry->usage); 88 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
89 89
90error: 90error:
91 cmd_unlink_window_free(data); 91 cmd_unlink_window_free(data);
diff --git a/cmd.c b/cmd.c
index 42e6a90..5f5a93c 100644
--- a/cmd.c
+++ b/cmd.c
@@ -51,6 +51,7 @@ const struct cmd_entry *cmd_table[] = {
51 &cmd_send_keys_entry, 51 &cmd_send_keys_entry,
52 &cmd_send_prefix_entry, 52 &cmd_send_prefix_entry,
53 &cmd_set_option_entry, 53 &cmd_set_option_entry,
54 &cmd_start_server_entry,
54 &cmd_swap_window_entry, 55 &cmd_swap_window_entry,
55 &cmd_switch_client_entry, 56 &cmd_switch_client_entry,
56 &cmd_unbind_key_entry, 57 &cmd_unbind_key_entry,
@@ -128,7 +129,7 @@ ambiguous:
128 return (NULL); 129 return (NULL);
129 130
130usage: 131usage:
131 usage(cause, "%s %s", entry->name, entry->usage); 132 xasprintf(cause, "usage: %s %s", entry->name, entry->usage);
132 return (NULL); 133 return (NULL);
133} 134}
134 135
diff --git a/server.c b/server.c
index cc3270e..df1aecb 100644
--- a/server.c
+++ b/server.c
@@ -55,28 +55,39 @@ void server_lost_client(struct client *);
55 void server_lost_window(struct window *); 55 void server_lost_window(struct window *);
56 56
57/* Fork new server. */ 57/* Fork new server. */
58int 58pid_t
59server_start(const char *path) 59server_start(const char *path)
60{ 60{
61 struct sockaddr_unsa; 61 struct sockaddr_unsa;
62 size_t size; 62 size_t size;
63 mode_t mask; 63 mode_t mask;
64 int n, fd, mode; 64 int n, fd, mode;
65 pid_t pid;
65 char *cause; 66 char *cause;
66 67
67 switch (fork()) { 68 switch (pid = fork()) {
68 case -1: 69 case -1:
69 fatal("fork"); 70 fatal("fork");
70 case 0: 71 case 0:
71 break; 72 break;
72 default: 73 default:
73 return (0); 74 return (pid);
74 } 75 }
75 76
76#ifdef DEBUG 77#ifdef DEBUG
77 xmalloc_clear(); 78 xmalloc_clear();
78#endif 79#endif
79 80
81 ARRAY_INIT(&windows);
82 ARRAY_INIT(&clients);
83 ARRAY_INIT(&sessions);
84 key_bindings_init();
85
86 if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) {
87 log_warnx("%s", cause);
88 exit(1);
89 }
90
80 logfile("server"); 91 logfile("server");
81#ifndef NO_SETPROCTITLE 92#ifndef NO_SETPROCTITLE
82 setproctitle("server (%s)", path); 93 setproctitle("server (%s)", path);
@@ -110,17 +121,10 @@ server_start(const char *path)
110 if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) 121 if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
111 fatal("fcntl failed"); 122 fatal("fcntl failed");
112 123
113 /* Load configuration. */
114 if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) {
115 log_warnx("%s", cause);
116 xfree(cause);
117 exit(1);
118 }
119
120 if (daemon(1, 1) != 0) 124 if (daemon(1, 1) != 0)
121 fatal("daemon failed"); 125 fatal("daemon failed");
122 log_debug("server daemonised, pid now %ld", (long) getpid()); 126 log_debug("server daemonised, pid now %ld", (long) getpid());
123 127
124 n = server_main(path, fd); 128 n = server_main(path, fd);
125#ifdef DEBUG 129#ifdef DEBUG
126 xmalloc_report(getpid(), "server"); 130 xmalloc_report(getpid(), "server");
@@ -137,12 +141,6 @@ server_main(const char *srv_path, int srv_fd)
137 u_int i; 141 u_int i;
138 142
139 siginit(); 143 siginit();
140
141 ARRAY_INIT(&windows);
142 ARRAY_INIT(&clients);
143 ARRAY_INIT(&sessions);
144
145 key_bindings_init();
146 144
147 pfds = NULL; 145 pfds = NULL;
148 while (!sigterm) { 146 while (!sigterm) {
diff --git a/session.c b/session.c
index 2834fdc..64e0fd8 100644
--- a/session.c
+++ b/session.c
@@ -117,6 +117,8 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy)
117 } 117 }
118 session_select(s, 0); 118 session_select(s, 0);
119 119
120 log_debug("session %s created", s->name);
121
120 return (s); 122 return (s);
121} 123}
122 124
@@ -126,6 +128,8 @@ session_destroy(struct session *s)
126{ 128{
127 u_inti; 129 u_inti;
128 130
131 log_debug("session %s destroyed", s->name);
132
129 if (session_index(s, &i) != 0) 133 if (session_index(s, &i) != 0)
130 fatalx("session not found"); 134 fatalx("session not found");
131 ARRAY_SET(&sessions, i, NULL); 135 ARRAY_SET(&sessions, i, NULL);
diff --git a/tmux.c b/tmux.c
index 98f0091..ac0e7fb 100644
--- a/tmux.c
+++ b/tmux.c
@@ -53,25 +53,15 @@ u_int history_limit;
53 u_int status_lines; 53 u_int status_lines;
54 54
55 void sighandler(int); 55 void sighandler(int);
56 __dead void usage(void);
56 57
57void 58__dead void
58usage(char **ptr, const char *fmt, ...) 59usage(void)
59{ 60{
60 char*msg; 61 fprintf(stderr,
61 va_list ap; 62 "usage: %s [-v] [-f file] [-S socket-path] command [flags]",
62 63 __progname);
63#define USAGE "usage: %s [-v] [-f file] [-S socket-path]" 64 exit(1);
64 if (fmt == NULL) {
65 xasprintf(ptr, USAGE " command [flags]", __progname);
66 } else {
67 va_start(ap, fmt);
68 xvasprintf(&msg, fmt, ap);
69 va_end(ap);
70
71 xasprintf(ptr, USAGE " %s", __progname, msg);
72 xfree(msg);
73 }
74#undef USAGE
75} 65}
76 66
77void 67void
@@ -202,13 +192,13 @@ main(int argc, char **argv)
202 printf("%s " BUILD "\n", __progname); 192 printf("%s " BUILD "\n", __progname);
203 exit(0); 193 exit(0);
204 default: 194 default:
205 goto usage; 195 usage();
206 } 196 }
207 } 197 }
208 argc -= optind; 198 argc -= optind;
209 argv += optind; 199 argv += optind;
210 if (argc == 0) 200 if (argc == 0)
211 goto usage; 201 usage();
212 202
213 log_open(stderr, LOG_USER, debug_level); 203 log_open(stderr, LOG_USER, debug_level);
214 siginit(); 204 siginit();
@@ -275,8 +265,6 @@ main(int argc, char **argv)
275 xasprintf(&default_command, "exec %s", shell); 265 xasprintf(&default_command, "exec %s", shell);
276 266
277 if ((cmd = cmd_parse(argc, argv, &cause)) == NULL) { 267 if ((cmd = cmd_parse(argc, argv, &cause)) == NULL) {
278 if (cause == NULL)
279 goto usage;
280 log_warnx("%s", cause); 268 log_warnx("%s", cause);
281 exit(1); 269 exit(1);
282 } 270 }
@@ -354,9 +342,4 @@ out:
354 xmalloc_report(getpid(), "client"); 342 xmalloc_report(getpid(), "client");
355#endif 343#endif
356 return (n); 344 return (n);
357
358usage:
359 usage(&cause, NULL);
360 fprintf(stderr, "%s\n", cause);
361 exit(1);
362} 345}
diff --git a/tmux.h b/tmux.h
index 3e4fcab..b146909 100644
--- a/tmux.h
+++ b/tmux.h
@@ -693,7 +693,6 @@ extern int prefix_key;
693 extern u_char status_colour; 693 extern u_char status_colour;
694 extern u_int history_limit; 694 extern u_int history_limit;
695 extern u_int status_lines; 695 extern u_int status_lines;
696 void usage(char **, const char *, ...);
697 void logfile(const char *); 696 void logfile(const char *);
698 void siginit(void); 697 void siginit(void);
699 void sigreset(void); 698 void sigreset(void);
@@ -759,6 +758,7 @@ extern const struct cmd_entry cmd_select_window_entry;
759extern const struct cmd_entry cmd_send_keys_entry; 758extern const struct cmd_entry cmd_send_keys_entry;
760extern const struct cmd_entry cmd_send_prefix_entry; 759extern const struct cmd_entry cmd_send_prefix_entry;
761extern const struct cmd_entry cmd_set_option_entry; 760extern const struct cmd_entry cmd_set_option_entry;
761extern const struct cmd_entry cmd_start_server_entry;
762extern const struct cmd_entry cmd_swap_window_entry; 762extern const struct cmd_entry cmd_swap_window_entry;
763extern const struct cmd_entry cmd_switch_client_entry; 763extern const struct cmd_entry cmd_switch_client_entry;
764extern const struct cmd_entry cmd_unbind_key_entry; 764extern const struct cmd_entry cmd_unbind_key_entry;
@@ -809,7 +809,7 @@ const char *key_string_lookup_key(int);
809 809
810/* server.c */ 810/* server.c */
811extern struct clients clients; 811extern struct clients clients;
812 int server_start(const char *); 812 pid_t server_start(const char *);
813 813
814/* server-msg.c */ 814/* server-msg.c */
815 int server_msg_dispatch(struct client *); 815 int server_msg_dispatch(struct client *);