mirror of
https://github.com/tmux/tmux.git
synced 2026-10-09 11:44:23 +00:00
Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master: If writing a file fails, propagate the error to the server via a new message. Use a client flag rather than bumping the protocol version. GitHub issue 5451. Add default terminal features for Rio, GitHub issue 5489 from Raphael Amorim.
This commit is contained in:
4
client.c
4
client.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: client.c,v 1.166 2026/07/10 15:45:11 nicm Exp $ */
|
/* $OpenBSD: client.c,v 1.167 2026/08/17 07:56:56 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -276,7 +276,7 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
|
|||||||
proc_set_signals(client_proc, client_signal);
|
proc_set_signals(client_proc, client_signal);
|
||||||
|
|
||||||
/* Save the flags. */
|
/* Save the flags. */
|
||||||
client_flags = flags;
|
client_flags = flags|CLIENT_WRITE_ACK;
|
||||||
log_debug("flags are %#llx", (unsigned long long)client_flags);
|
log_debug("flags are %#llx", (unsigned long long)client_flags);
|
||||||
|
|
||||||
/* Initialize the client socket and start the server. */
|
/* Initialize the client socket and start the server. */
|
||||||
|
|||||||
86
file.c
86
file.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: file.c,v 1.21 2026/07/26 15:08:15 nicm Exp $ */
|
/* $OpenBSD: file.c,v 1.22 2026/08/17 07:56:56 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -502,7 +502,8 @@ file_push(struct client_file *cf)
|
|||||||
} else if (cf->stream > 2) {
|
} else if (cf->stream > 2) {
|
||||||
close.stream = cf->stream;
|
close.stream = cf->stream;
|
||||||
proc_send(cf->peer, MSG_WRITE_CLOSE, -1, &close, sizeof close);
|
proc_send(cf->peer, MSG_WRITE_CLOSE, -1, &close, sizeof close);
|
||||||
file_fire_done(cf);
|
if (cf->c == NULL || (~cf->c->flags & CLIENT_WRITE_ACK))
|
||||||
|
file_fire_done(cf);
|
||||||
}
|
}
|
||||||
free(msg);
|
free(msg);
|
||||||
}
|
}
|
||||||
@@ -527,14 +528,48 @@ file_write_left(struct client_files *files)
|
|||||||
return (waiting != 0);
|
return (waiting != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Finish writing a client file. */
|
||||||
|
static void
|
||||||
|
file_write_finished(struct client_file *cf)
|
||||||
|
{
|
||||||
|
struct msg_write_done msg;
|
||||||
|
|
||||||
|
if (cf->event != NULL) {
|
||||||
|
bufferevent_free(cf->event);
|
||||||
|
cf->event = NULL;
|
||||||
|
}
|
||||||
|
if (cf->fd != -1) {
|
||||||
|
if (close(cf->fd) != 0 && cf->error == 0)
|
||||||
|
cf->error = errno;
|
||||||
|
cf->fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.stream = cf->stream;
|
||||||
|
msg.error = cf->error;
|
||||||
|
proc_send(cf->peer, MSG_WRITE_DONE, -1, &msg, sizeof msg);
|
||||||
|
|
||||||
|
if (cf->cb != NULL)
|
||||||
|
cf->cb(NULL, NULL, 0, -1, NULL, cf->data);
|
||||||
|
file_free(cf);
|
||||||
|
}
|
||||||
|
|
||||||
/* Client file write error callback. */
|
/* Client file write error callback. */
|
||||||
static void
|
static void
|
||||||
file_write_error_callback(__unused struct bufferevent *bev, __unused short what,
|
file_write_error_callback(__unused struct bufferevent *bev, short what,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
struct client_file *cf = arg;
|
struct client_file *cf = arg;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (what & EVBUFFER_ERROR)
|
||||||
|
error = errno;
|
||||||
|
else
|
||||||
|
error = EIO;
|
||||||
|
if (error == 0)
|
||||||
|
error = EIO;
|
||||||
|
|
||||||
log_debug("write error file %d", cf->stream);
|
log_debug("write error file %d", cf->stream);
|
||||||
|
cf->error = error;
|
||||||
|
|
||||||
bufferevent_free(cf->event);
|
bufferevent_free(cf->event);
|
||||||
cf->event = NULL;
|
cf->event = NULL;
|
||||||
@@ -542,7 +577,9 @@ file_write_error_callback(__unused struct bufferevent *bev, __unused short what,
|
|||||||
close(cf->fd);
|
close(cf->fd);
|
||||||
cf->fd = -1;
|
cf->fd = -1;
|
||||||
|
|
||||||
if (cf->cb != NULL)
|
if (cf->closed)
|
||||||
|
file_write_finished(cf);
|
||||||
|
else if (cf->cb != NULL)
|
||||||
cf->cb(NULL, NULL, 0, -1, NULL, cf->data);
|
cf->cb(NULL, NULL, 0, -1, NULL, cf->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,15 +591,10 @@ file_write_callback(__unused struct bufferevent *bev, void *arg)
|
|||||||
|
|
||||||
log_debug("write check file %d", cf->stream);
|
log_debug("write check file %d", cf->stream);
|
||||||
|
|
||||||
if (cf->cb != NULL)
|
if (cf->closed && EVBUFFER_LENGTH(cf->event->output) == 0)
|
||||||
|
file_write_finished(cf);
|
||||||
|
else if (cf->cb != NULL)
|
||||||
cf->cb(NULL, NULL, 0, -1, NULL, cf->data);
|
cf->cb(NULL, NULL, 0, -1, NULL, cf->data);
|
||||||
|
|
||||||
if (cf->closed && EVBUFFER_LENGTH(cf->event->output) == 0) {
|
|
||||||
bufferevent_free(cf->event);
|
|
||||||
close(cf->fd);
|
|
||||||
RB_REMOVE(client_files, cf->tree, cf);
|
|
||||||
file_free(cf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle a file write open message (client). */
|
/* Handle a file write open message (client). */
|
||||||
@@ -663,14 +695,10 @@ file_write_close(struct client_files *files, struct imsg *imsg)
|
|||||||
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
||||||
fatalx("unknown stream number");
|
fatalx("unknown stream number");
|
||||||
log_debug("close file %d", cf->stream);
|
log_debug("close file %d", cf->stream);
|
||||||
|
cf->closed = 1;
|
||||||
|
|
||||||
if (cf->event == NULL || EVBUFFER_LENGTH(cf->event->output) == 0) {
|
if (cf->event == NULL || EVBUFFER_LENGTH(cf->event->output) == 0) {
|
||||||
if (cf->event != NULL)
|
file_write_finished(cf);
|
||||||
bufferevent_free(cf->event);
|
|
||||||
if (cf->fd != -1)
|
|
||||||
close(cf->fd);
|
|
||||||
RB_REMOVE(client_files, files, cf);
|
|
||||||
file_free(cf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,6 +857,28 @@ file_write_ready(struct client_files *files, struct imsg *imsg)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle a write done message (server). */
|
||||||
|
int
|
||||||
|
file_write_done(struct client_files *files, struct imsg *imsg)
|
||||||
|
{
|
||||||
|
struct msg_write_done *msg = imsg->data;
|
||||||
|
size_t msglen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||||
|
struct client_file find, *cf;
|
||||||
|
|
||||||
|
if (msglen != sizeof *msg)
|
||||||
|
return (-1);
|
||||||
|
find.stream = msg->stream;
|
||||||
|
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
||||||
|
return (0);
|
||||||
|
if (cf->c == NULL || (~cf->c->flags & CLIENT_WRITE_ACK))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
log_debug("file %d write done", cf->stream);
|
||||||
|
cf->error = msg->error;
|
||||||
|
file_fire_done(cf);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle read data message (server). */
|
/* Handle read data message (server). */
|
||||||
int
|
int
|
||||||
file_read_data(struct client_files *files, struct imsg *imsg)
|
file_read_data(struct client_files *files, struct imsg *imsg)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: server-client.c,v 1.502 2026/08/04 11:18:22 nicm Exp $ */
|
/* $OpenBSD: server-client.c,v 1.503 2026/08/17 07:56:56 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -2695,6 +2695,10 @@ server_client_dispatch(struct imsg *imsg, void *arg)
|
|||||||
if (file_write_ready(&c->files, imsg) != 0)
|
if (file_write_ready(&c->files, imsg) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
|
case MSG_WRITE_DONE:
|
||||||
|
if (file_write_done(&c->files, imsg) != 0)
|
||||||
|
goto bad;
|
||||||
|
break;
|
||||||
case MSG_READ:
|
case MSG_READ:
|
||||||
if (file_read_data(&c->files, imsg) != 0)
|
if (file_read_data(&c->files, imsg) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tmux-protocol.h,v 1.2 2023/01/06 07:09:27 nicm Exp $ */
|
/* $OpenBSD: tmux-protocol.h,v 1.3 2026/08/17 07:56:56 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2021 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -67,7 +67,8 @@ enum msgtype {
|
|||||||
MSG_WRITE,
|
MSG_WRITE,
|
||||||
MSG_WRITE_READY,
|
MSG_WRITE_READY,
|
||||||
MSG_WRITE_CLOSE,
|
MSG_WRITE_CLOSE,
|
||||||
MSG_READ_CANCEL
|
MSG_READ_CANCEL,
|
||||||
|
MSG_WRITE_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -116,4 +117,9 @@ struct msg_write_close {
|
|||||||
int stream;
|
int stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct msg_write_done {
|
||||||
|
int stream;
|
||||||
|
int error;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* TMUX_PROTOCOL_H */
|
#endif /* TMUX_PROTOCOL_H */
|
||||||
|
|||||||
5
tmux.h
5
tmux.h
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tmux.h,v 1.1422 2026/08/05 08:54:56 nicm Exp $ */
|
/* $OpenBSD: tmux.h,v 1.1423 2026/08/17 07:56:56 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -2293,7 +2293,7 @@ struct client {
|
|||||||
/* 0x800000000ULL unused */
|
/* 0x800000000ULL unused */
|
||||||
#define CLIENT_BRACKETPASTING 0x1000000000ULL
|
#define CLIENT_BRACKETPASTING 0x1000000000ULL
|
||||||
#define CLIENT_ASSUMEPASTING 0x2000000000ULL
|
#define CLIENT_ASSUMEPASTING 0x2000000000ULL
|
||||||
/* 0x4000000000ULL unused */
|
#define CLIENT_WRITE_ACK 0x4000000000ULL
|
||||||
#define CLIENT_NO_DETACH_ON_DESTROY 0x8000000000ULL
|
#define CLIENT_NO_DETACH_ON_DESTROY 0x8000000000ULL
|
||||||
#define CLIENT_ALLREDRAWFLAGS \
|
#define CLIENT_ALLREDRAWFLAGS \
|
||||||
(CLIENT_REDRAWWINDOW| \
|
(CLIENT_REDRAWWINDOW| \
|
||||||
@@ -3280,6 +3280,7 @@ void file_write_close(struct client_files *, struct imsg *);
|
|||||||
void file_read_open(struct client_files *, struct tmuxpeer *, struct imsg *,
|
void file_read_open(struct client_files *, struct tmuxpeer *, struct imsg *,
|
||||||
int, int, client_file_cb, void *);
|
int, int, client_file_cb, void *);
|
||||||
int file_write_ready(struct client_files *, struct imsg *);
|
int file_write_ready(struct client_files *, struct imsg *);
|
||||||
|
int file_write_done(struct client_files *, struct imsg *);
|
||||||
int file_read_data(struct client_files *, struct imsg *);
|
int file_read_data(struct client_files *, struct imsg *);
|
||||||
int file_read_done(struct client_files *, struct imsg *);
|
int file_read_done(struct client_files *, struct imsg *);
|
||||||
void file_read_cancel(struct client_files *, struct imsg *);
|
void file_read_cancel(struct client_files *, struct imsg *);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tty-features.c,v 1.40 2026/07/01 06:17:58 nicm Exp $ */
|
/* $OpenBSD: tty-features.c,v 1.41 2026/08/17 07:52:16 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -596,6 +596,18 @@ tty_default_features(int *feat, const char *name, u_int version)
|
|||||||
"usstyle,"
|
"usstyle,"
|
||||||
"progressbar"
|
"progressbar"
|
||||||
},
|
},
|
||||||
|
{ .name = "Rio",
|
||||||
|
.features = TTY_FEATURES_BASE_MODERN_XTERM ","
|
||||||
|
"ccolour,"
|
||||||
|
"cstyle,"
|
||||||
|
"focus,"
|
||||||
|
"overline,"
|
||||||
|
"hyperlinks,"
|
||||||
|
"osc7,"
|
||||||
|
"sync,"
|
||||||
|
"usstyle,"
|
||||||
|
"progressbar"
|
||||||
|
},
|
||||||
{ .name = "XTerm",
|
{ .name = "XTerm",
|
||||||
/*
|
/*
|
||||||
* xterm also supports DECSLRM and DECFRA, but they can be
|
* xterm also supports DECSLRM and DECFRA, but they can be
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tty-keys.c,v 1.211 2026/07/21 07:12:49 nicm Exp $ */
|
/* $OpenBSD: tty-keys.c,v 1.212 2026/08/17 07:52:16 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1667,6 +1667,8 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
|
|||||||
tty_default_features(features, "WezTerm", 0);
|
tty_default_features(features, "WezTerm", 0);
|
||||||
else if (strncmp(tmp, "ghostty ", 8) == 0)
|
else if (strncmp(tmp, "ghostty ", 8) == 0)
|
||||||
tty_default_features(features, "ghostty", 0);
|
tty_default_features(features, "ghostty", 0);
|
||||||
|
else if (strncmp(tmp, "Rio ", 4) == 0)
|
||||||
|
tty_default_features(features, "Rio", 0);
|
||||||
log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf);
|
log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf);
|
||||||
|
|
||||||
free(c->term_type);
|
free(c->term_type);
|
||||||
|
|||||||
Reference in New Issue
Block a user