Support for individual session idle time locking. May be enabled by turning off

the lock-server option (it is on by default). When this is off, each session
locks when it has been idle for the lock-after-time setting. When on, the
entire server locks when ALL sessions have been idle for their individual
lock-after-time settings.

This replaces one global-only option (lock-after-time) with another
(lock-server), but the default behaviour is usually preferable so there don't
seem to be many alternatives.

Diff/idea largely from Thomas Adam, tweaked by me.
This commit is contained in:
Nicholas Marriott 2009-10-10 09:46:11 +00:00
parent 93b353d353
commit b7d031cc92
7 changed files with 81 additions and 24 deletions

View File

@ -63,6 +63,7 @@ const struct set_option_entry set_option_table[] = {
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-command", SET_OPTION_STRING, 0, 0, NULL }, { "lock-command", SET_OPTION_STRING, 0, 0, NULL },
{ "lock-server", SET_OPTION_FLAG, 0, 0, NULL },
{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },

View File

@ -105,7 +105,8 @@ server_msg_dispatch(struct client *c)
tty_start_tty(&c->tty); tty_start_tty(&c->tty);
server_redraw_client(c); server_redraw_client(c);
recalculate_sizes(); recalculate_sizes();
server_activity = time(NULL); if (c->session != NULL)
c->session->activity = time(NULL);
break; break;
case MSG_ENVIRON: case MSG_ENVIRON:
if (datalen != sizeof environdata) if (datalen != sizeof environdata)
@ -181,7 +182,8 @@ server_msg_command(struct client *c, struct msg_command_data *data)
int argc; int argc;
char **argv, *cause; char **argv, *cause;
server_activity = time(NULL); if (c->session != NULL)
c->session->activity = time(NULL);
ctx.error = server_msg_command_error; ctx.error = server_msg_command_error;
ctx.print = server_msg_command_print; ctx.print = server_msg_command_print;

View File

@ -86,6 +86,8 @@ void server_check_window(struct window *);
void server_check_redraw(struct client *); void server_check_redraw(struct client *);
void server_set_title(struct client *); void server_set_title(struct client *);
void server_check_timers(struct client *); void server_check_timers(struct client *);
void server_lock_server(void);
void server_lock_sessions(void);
void server_second_timers(void); void server_second_timers(void);
int server_update_socket(void); int server_update_socket(void);
@ -249,8 +251,6 @@ server_start(char *path)
key_bindings_init(); key_bindings_init();
utf8_build(); utf8_build();
server_activity = time(NULL);
start_time = time(NULL); start_time = time(NULL);
socket_path = path; socket_path = path;
@ -842,10 +842,10 @@ server_handle_client(struct client *c)
/* Process keys. */ /* Process keys. */
keylist = options_get_data(&c->session->options, "prefix"); keylist = options_get_data(&c->session->options, "prefix");
while (tty_keys_next(&c->tty, &key, mouse) == 0) { while (tty_keys_next(&c->tty, &key, mouse) == 0) {
server_activity = time(NULL);
if (c->session == NULL) if (c->session == NULL)
return; return;
c->session->activity = time(NULL);
w = c->session->curw->window; w = c->session->curw->window;
wp = w->active; /* could die */ wp = w->active; /* could die */
@ -1254,6 +1254,51 @@ server_check_window(struct window *w)
recalculate_sizes(); recalculate_sizes();
} }
/* Lock the server if ALL sessions have hit the time limit. */
void
server_lock_server(void)
{
struct session *s;
u_int i;
int timeout;
time_t t;
t = time(NULL);
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
timeout = options_get_number(&s->options, "lock-after-time");
if (timeout <= 0 || t <= s->activity + timeout)
return; /* not timed out */
}
server_lock();
recalculate_sizes();
}
/* Lock any sessions which have timed out. */
void
server_lock_sessions(void)
{
struct session *s;
u_int i;
int timeout;
time_t t;
t = time(NULL);
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
timeout = options_get_number(&s->options, "lock-after-time");
if (timeout > 0 && t > s->activity + timeout) {
server_lock_session(s);
recalculate_sizes();
}
}
}
/* Call any once-per-second timers. */ /* Call any once-per-second timers. */
void void
server_second_timers(void) server_second_timers(void)
@ -1261,16 +1306,11 @@ server_second_timers(void)
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
u_int i; u_int i;
int xtimeout;
time_t t;
t = time(NULL); if (options_get_number(&global_s_options, "lock-server"))
server_lock_server();
xtimeout = options_get_number(&global_s_options, "lock-after-time"); else
if (xtimeout > 0 && t > server_activity + xtimeout) { server_lock_sessions();
server_lock();
recalculate_sizes();
}
for (i = 0; i < ARRAY_LENGTH(&windows); i++) { for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
w = ARRAY_ITEM(&windows, i); w = ARRAY_ITEM(&windows, i);

View File

@ -23,6 +23,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <time.h>
#include "tmux.h" #include "tmux.h"
@ -124,6 +125,7 @@ session_create(const char *name, const char *cmd, const char *cwd,
s = xmalloc(sizeof *s); s = xmalloc(sizeof *s);
s->references = 0; s->references = 0;
s->flags = 0; s->flags = 0;
s->activity = time(NULL);
if (gettimeofday(&s->tv, NULL) != 0) if (gettimeofday(&s->tv, NULL) != 0)
fatal("gettimeofday failed"); fatal("gettimeofday failed");

25
tmux.1
View File

@ -1253,20 +1253,33 @@ Set the maximum number of lines held in window history.
This setting applies only to new windows - existing window histories are not This setting applies only to new windows - existing window histories are not
resized and retain the limit at the point they were created. resized and retain the limit at the point they were created.
.It Ic lock-after-time Ar number .It Ic lock-after-time Ar number
Lock the server (like the Lock the session (like the
.Ic lock-server .Ic lock-session
command) after command) after
.Ar number .Ar number
seconds of inactivity. seconds of inactivity, or the entire server (all sessions) if the
The default is off (set to 0). .Ic lock-server
This has no effect as a session option; it must be set as a global option using option is set.
.Fl g . The default is not to lock (set to 0).
.It Ic lock-command Ar command .It Ic lock-command Ar command
Command to run when locking each client. Command to run when locking each client.
The default is to run The default is to run
.Xr lock 1 .Xr lock 1
with with
.Fl np . .Fl np .
.It Xo Ic lock-server
.Op Ic on | off
.Xc
If this option is
.Ic on
(the default),
instead of each session locking individually as each has been
idle for
.Ic lock-after-time
, the entire server will lock after
.Em all
sessions would have locked.
This has no effect as a session option; it must be set as a global option.
.It Ic message-attr Ar attributes .It Ic message-attr Ar attributes
Set status line message attributes, where Set status line message attributes, where
.Ar attributes .Ar attributes

3
tmux.c
View File

@ -46,8 +46,6 @@ struct options global_s_options; /* session options */
struct options global_w_options; /* window options */ struct options global_w_options; /* window options */
struct environ global_environ; struct environ global_environ;
time_t server_activity;
int debug_level; int debug_level;
int be_quiet; int be_quiet;
time_t start_time; time_t start_time;
@ -379,6 +377,7 @@ main(int argc, char **argv)
options_set_number(so, "history-limit", 2000); options_set_number(so, "history-limit", 2000);
options_set_number(so, "lock-after-time", 0); options_set_number(so, "lock-after-time", 0);
options_set_string(so, "lock-command", "lock -np"); options_set_string(so, "lock-command", "lock -np");
options_set_number(so, "lock-server", 1);
options_set_number(so, "message-attr", 0); options_set_number(so, "message-attr", 0);
options_set_number(so, "message-bg", 3); options_set_number(so, "message-bg", 3);
options_set_number(so, "message-fg", 0); options_set_number(so, "message-fg", 0);

2
tmux.h
View File

@ -800,6 +800,7 @@ struct session_alert {
struct session { struct session {
char *name; char *name;
struct timeval tv; struct timeval tv;
time_t activity;
u_int sx; u_int sx;
u_int sy; u_int sy;
@ -1117,7 +1118,6 @@ extern struct options global_s_options;
extern struct options global_w_options; extern struct options global_w_options;
extern struct environ global_environ; extern struct environ global_environ;
extern char *cfg_file; extern char *cfg_file;
extern time_t server_activity;
extern int debug_level; extern int debug_level;
extern int be_quiet; extern int be_quiet;
extern time_t start_time; extern time_t start_time;