mirror of
https://github.com/tmux/tmux.git
synced 2026-10-11 21:14:21 +00:00
Add a utmp option if built with utempter, GitHub issue 5657 from Damian Nowak.
This commit is contained in:
@@ -743,6 +743,15 @@ const struct options_table_entry options_table[] = {
|
|||||||
"'User0', 'User1' and so on."
|
"'User0', 'User1' and so on."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#ifdef HAVE_UTEMPTER
|
||||||
|
{ .name = "utmp",
|
||||||
|
.type = OPTIONS_TABLE_FLAG,
|
||||||
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
|
.default_num = 1,
|
||||||
|
.text = "Whether to maintain utmp records."
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
|
||||||
{ .name = "variation-selector-always-wide",
|
{ .name = "variation-selector-always-wide",
|
||||||
.type = OPTIONS_TABLE_FLAG,
|
.type = OPTIONS_TABLE_FLAG,
|
||||||
.scope = OPTIONS_TABLE_SERVER,
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
|
|||||||
@@ -1406,6 +1406,14 @@ options_push_changes(const char *name)
|
|||||||
tty_keys_build(&loop->tty);
|
tty_keys_build(&loop->tty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (strcmp(name, "utmp") == 0) {
|
||||||
|
RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
|
||||||
|
if (options_get_number(global_options, name))
|
||||||
|
window_pane_utmp_add(wp);
|
||||||
|
else
|
||||||
|
window_pane_utmp_remove(wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (strcmp(name, "status") == 0 ||
|
if (strcmp(name, "status") == 0 ||
|
||||||
strcmp(name, "status-interval") == 0)
|
strcmp(name, "status-interval") == 0)
|
||||||
status_timer_start_all();
|
status_timer_start_all();
|
||||||
|
|||||||
@@ -363,10 +363,7 @@ server_destroy_pane(struct window_pane *wp, int notify)
|
|||||||
u_int sy = screen_size_y(&wp->base);
|
u_int sy = screen_size_y(&wp->base);
|
||||||
|
|
||||||
if (wp->fd != -1) {
|
if (wp->fd != -1) {
|
||||||
#ifdef HAVE_UTEMPTER
|
window_pane_utmp_remove(wp);
|
||||||
utempter_remove_record(wp->fd);
|
|
||||||
kill(getpid(), SIGCHLD);
|
|
||||||
#endif
|
|
||||||
bufferevent_free(wp->event);
|
bufferevent_free(wp->event);
|
||||||
wp->event = NULL;
|
wp->event = NULL;
|
||||||
close(wp->fd);
|
close(wp->fd);
|
||||||
|
|||||||
11
spawn.c
11
spawn.c
@@ -322,6 +322,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
|||||||
sc->wp0->event = NULL;
|
sc->wp0->event = NULL;
|
||||||
}
|
}
|
||||||
if (sc->wp0->fd != -1) {
|
if (sc->wp0->fd != -1) {
|
||||||
|
window_pane_utmp_remove(sc->wp0);
|
||||||
close(sc->wp0->fd);
|
close(sc->wp0->fd);
|
||||||
sc->wp0->fd = -1;
|
sc->wp0->fd = -1;
|
||||||
}
|
}
|
||||||
@@ -579,16 +580,8 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
|||||||
_exit(1);
|
_exit(1);
|
||||||
|
|
||||||
complete:
|
complete:
|
||||||
#ifdef HAVE_UTEMPTER
|
|
||||||
if (~new_wp->flags & PANE_EMPTY) {
|
|
||||||
xasprintf(&cp, "tmux(%lu).%%%u", (long)getpid(), new_wp->id);
|
|
||||||
utempter_add_record(new_wp->fd, cp);
|
|
||||||
kill(getpid(), SIGCHLD);
|
|
||||||
free(cp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
new_wp->flags &= ~PANE_EXITED;
|
new_wp->flags &= ~PANE_EXITED;
|
||||||
|
window_pane_utmp_add(new_wp);
|
||||||
|
|
||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
window_pane_set_event(new_wp);
|
window_pane_set_event(new_wp);
|
||||||
|
|||||||
17
tmux.1
17
tmux.1
@@ -5262,6 +5262,23 @@ For example:
|
|||||||
set \-s user\-keys[0] "\ee[5;30012\[ti]"
|
set \-s user\-keys[0] "\ee[5;30012\[ti]"
|
||||||
bind User0 resize\-pane \-L 3
|
bind User0 resize\-pane \-L 3
|
||||||
.Ed
|
.Ed
|
||||||
|
.It Xo Ic utmp
|
||||||
|
.Op Ic on | off
|
||||||
|
.Xc
|
||||||
|
Maintain utmp records for panes using
|
||||||
|
.Xr utempter 3 .
|
||||||
|
The default is on.
|
||||||
|
Turning this option off asks utempter to remove existing records and prevents
|
||||||
|
new records from being added.
|
||||||
|
Turning it on asks utempter to add records for existing panes with running
|
||||||
|
commands.
|
||||||
|
Empty panes are not recorded.
|
||||||
|
Updates to wtmp are performed by
|
||||||
|
.Xr utempter 3
|
||||||
|
according to the system configuration; existing history is not erased.
|
||||||
|
This option has no effect if
|
||||||
|
.Nm
|
||||||
|
was built without utempter support.
|
||||||
.It Xo Ic variation\-selector\-always\-wide
|
.It Xo Ic variation\-selector\-always\-wide
|
||||||
.Op Cm on | off
|
.Op Cm on | off
|
||||||
.Xc
|
.Xc
|
||||||
|
|||||||
3
tmux.h
3
tmux.h
@@ -1355,6 +1355,7 @@ struct window_pane {
|
|||||||
#define PANE_CAPTUREALLKEYS 0x100000
|
#define PANE_CAPTUREALLKEYS 0x100000
|
||||||
#define PANE_FLOATOVERZOOM 0x200000
|
#define PANE_FLOATOVERZOOM 0x200000
|
||||||
#define PANE_CLOSEONCANCEL 0x400000
|
#define PANE_CLOSEONCANCEL 0x400000
|
||||||
|
#define PANE_UTMP 0x800000
|
||||||
|
|
||||||
bitstr_t *sync_dirty;
|
bitstr_t *sync_dirty;
|
||||||
u_int sync_dirty_size;
|
u_int sync_dirty_size;
|
||||||
@@ -3725,6 +3726,8 @@ struct window *window_find_by_id(u_int);
|
|||||||
void window_update_activity(struct window *);
|
void window_update_activity(struct window *);
|
||||||
struct window *window_create(u_int, u_int, u_int, u_int);
|
struct window *window_create(u_int, u_int, u_int, u_int);
|
||||||
void window_pane_set_event(struct window_pane *);
|
void window_pane_set_event(struct window_pane *);
|
||||||
|
void window_pane_utmp_add(struct window_pane *);
|
||||||
|
void window_pane_utmp_remove(struct window_pane *);
|
||||||
void window_pane_wait_finish(struct window_pane *);
|
void window_pane_wait_finish(struct window_pane *);
|
||||||
struct window_pane *window_get_active_at(struct window *, u_int, u_int);
|
struct window_pane *window_get_active_at(struct window *, u_int, u_int);
|
||||||
struct window_pane *window_find_string(struct window *, const char *);
|
struct window_pane *window_find_string(struct window *, const char *);
|
||||||
|
|||||||
45
window.c
45
window.c
@@ -1579,6 +1579,46 @@ window_pane_scrollbar_redraw_visibility(struct window_pane *wp)
|
|||||||
server_redraw_window(wp->window);
|
server_redraw_window(wp->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_UTEMPTER
|
||||||
|
void
|
||||||
|
window_pane_utmp_add(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (wp->fd == -1 ||
|
||||||
|
(wp->flags & (PANE_EMPTY|PANE_EXITED|PANE_UTMP)) ||
|
||||||
|
!options_get_number(global_options, "utmp"))
|
||||||
|
return;
|
||||||
|
xasprintf(&cp, "tmux(%lu).%%%u", (long)getpid(), wp->id);
|
||||||
|
utempter_add_record(wp->fd, cp);
|
||||||
|
kill(getpid(), SIGCHLD);
|
||||||
|
wp->flags |= PANE_UTMP;
|
||||||
|
free(cp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
window_pane_utmp_add(__unused struct window_pane *wp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_UTEMPTER
|
||||||
|
void
|
||||||
|
window_pane_utmp_remove(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
if (~wp->flags & PANE_UTMP)
|
||||||
|
return;
|
||||||
|
utempter_remove_record(wp->fd);
|
||||||
|
kill(getpid(), SIGCHLD);
|
||||||
|
wp->flags &= ~PANE_UTMP;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
window_pane_utmp_remove(__unused struct window_pane *wp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
window_pane_destroy(struct window_pane *wp)
|
window_pane_destroy(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
@@ -1597,10 +1637,7 @@ window_pane_destroy(struct window_pane *wp)
|
|||||||
wp->event = NULL;
|
wp->event = NULL;
|
||||||
}
|
}
|
||||||
if (wp->fd != -1) {
|
if (wp->fd != -1) {
|
||||||
#ifdef HAVE_UTEMPTER
|
window_pane_utmp_remove(wp);
|
||||||
utempter_remove_record(wp->fd);
|
|
||||||
kill(getpid(), SIGCHLD);
|
|
||||||
#endif
|
|
||||||
close(wp->fd);
|
close(wp->fd);
|
||||||
wp->fd = -1;
|
wp->fd = -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user