sync code with last improvements from OpenBSD

This commit is contained in:
purplerain 2023-09-15 18:33:02 +00:00
parent 66d94126c9
commit 8b897ac235
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
18 changed files with 560 additions and 1276 deletions

View File

@ -116,6 +116,8 @@
/** timeout in millisec to wait for write to unblock, packets dropped after.*/
#define SEND_BLOCKED_WAIT_TIMEOUT 200
/** max number of times to wait for write to unblock, packets dropped after.*/
#define SEND_BLOCKED_MAX_RETRY 5
/** Let's make timestamping code cleaner and redefine SO_TIMESTAMP* */
#ifndef SO_TIMESTAMP
@ -402,9 +404,10 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
WSAGetLastError() == WSAENOBUFS ||
WSAGetLastError() == WSAEWOULDBLOCK) {
#endif
int retries = 0;
/* if we set the fd blocking, other threads suddenly
* have a blocking fd that they operate on */
while(sent == -1 && (
while(sent == -1 && retries < SEND_BLOCKED_MAX_RETRY && (
#ifndef USE_WINSOCK
errno == EAGAIN || errno == EINTR ||
# ifdef EWOULDBLOCK
@ -419,6 +422,13 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
#endif
)) {
#if defined(HAVE_POLL) || defined(USE_WINSOCK)
int send_nobufs = (
#ifndef USE_WINSOCK
errno == ENOBUFS
#else
WSAGetLastError() == WSAENOBUFS
#endif
);
struct pollfd p;
int pret;
memset(&p, 0, sizeof(p));
@ -457,8 +467,48 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
log_err("poll udp out failed: %s",
sock_strerror(errno));
return 0;
} else if((pret < 0 &&
#ifndef USE_WINSOCK
errno == ENOBUFS
#else
WSAGetLastError() == WSAENOBUFS
#endif
) || (send_nobufs && retries > 0)) {
/* ENOBUFS, and poll returned without
* a timeout. Or the retried send call
* returned ENOBUFS. It is good to
* wait a bit for the error to clear. */
/* The timeout is 20*(2^(retries+1)),
* it increases exponentially, starting
* at 40 msec. After 5 tries, 1240 msec
* have passed in total, when poll
* returned the error, and 1200 msec
* when send returned the errors. */
#ifndef USE_WINSOCK
pret = poll(NULL, 0, (SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1));
#else
pret = WSAPoll(NULL, 0, (SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1));
#endif
if(pret < 0 &&
#ifndef USE_WINSOCK
errno != EAGAIN && errno != EINTR &&
# ifdef EWOULDBLOCK
errno != EWOULDBLOCK &&
# endif
errno != ENOBUFS
#else
WSAGetLastError() != WSAEINPROGRESS &&
WSAGetLastError() != WSAEINTR &&
WSAGetLastError() != WSAENOBUFS &&
WSAGetLastError() != WSAEWOULDBLOCK
#endif
) {
log_err("poll udp out timer failed: %s",
sock_strerror(errno));
}
}
#endif /* defined(HAVE_POLL) || defined(USE_WINSOCK) */
retries++;
if (!is_connected) {
sent = sendto(c->fd, (void*)sldns_buffer_begin(packet),
sldns_buffer_remaining(packet), 0,
@ -665,7 +715,8 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
WSAGetLastError() == WSAENOBUFS ||
WSAGetLastError() == WSAEWOULDBLOCK) {
#endif
while(sent == -1 && (
int retries = 0;
while(sent == -1 && retries < SEND_BLOCKED_MAX_RETRY && (
#ifndef USE_WINSOCK
errno == EAGAIN || errno == EINTR ||
# ifdef EWOULDBLOCK
@ -680,6 +731,13 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
#endif
)) {
#if defined(HAVE_POLL) || defined(USE_WINSOCK)
int send_nobufs = (
#ifndef USE_WINSOCK
errno == ENOBUFS
#else
WSAGetLastError() == WSAENOBUFS
#endif
);
struct pollfd p;
int pret;
memset(&p, 0, sizeof(p));
@ -718,8 +776,48 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
log_err("poll udp out failed: %s",
sock_strerror(errno));
return 0;
} else if((pret < 0 &&
#ifndef USE_WINSOCK
errno == ENOBUFS
#else
WSAGetLastError() == WSAENOBUFS
#endif
) || (send_nobufs && retries > 0)) {
/* ENOBUFS, and poll returned without
* a timeout. Or the retried send call
* returned ENOBUFS. It is good to
* wait a bit for the error to clear. */
/* The timeout is 20*(2^(retries+1)),
* it increases exponentially, starting
* at 40 msec. After 5 tries, 1240 msec
* have passed in total, when poll
* returned the error, and 1200 msec
* when send returned the errors. */
#ifndef USE_WINSOCK
pret = poll(NULL, 0, (SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1));
#else
pret = WSAPoll(NULL, 0, (SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1));
#endif
if(pret < 0 &&
#ifndef USE_WINSOCK
errno != EAGAIN && errno != EINTR &&
# ifdef EWOULDBLOCK
errno != EWOULDBLOCK &&
# endif
errno != ENOBUFS
#else
WSAGetLastError() != WSAEINPROGRESS &&
WSAGetLastError() != WSAEINTR &&
WSAGetLastError() != WSAENOBUFS &&
WSAGetLastError() != WSAEWOULDBLOCK
#endif
) {
log_err("poll udp out timer failed: %s",
sock_strerror(errno));
}
}
#endif /* defined(HAVE_POLL) || defined(USE_WINSOCK) */
retries++;
sent = sendmsg(c->fd, &msg, 0);
}
}

View File

@ -1,4 +1,4 @@
# $OpenBSD: bsd.regress.mk,v 1.25 2022/12/09 09:30:54 tb Exp $
# $OpenBSD: bsd.regress.mk,v 1.26 2023/09/15 07:13:35 tb Exp $
# Documented in bsd.regress.mk(5)
# No man pages for regression tests.
@ -21,7 +21,7 @@ all: regress
REGRESS_LOG?=/dev/null
REGRESS_SKIP_TARGETS?=
REGRESS_SKIP_SLOW?=no
REGRESS_FAIL_EARLY?=no
REGRESS_FAIL_EARLY?=yes
.if ! ${REGRESS_LOG:M/*}
ERRORS += "Fatal: REGRESS_LOG=${REGRESS_LOG} is not an absolute path"

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kern_clockintr.c,v 1.52 2023/09/14 22:27:09 cheloha Exp $ */
/* $OpenBSD: kern_clockintr.c,v 1.53 2023/09/15 11:48:49 deraadt Exp $ */
/*
* Copyright (c) 2003 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@ -355,9 +355,10 @@ clockintr_cancel(struct clockintr *cl)
}
struct clockintr *
clockintr_establish(struct cpu_info *ci,
clockintr_establish(void *vci,
void (*func)(struct clockintr *, void *, void *), void *arg)
{
struct cpu_info *ci = vci;
struct clockintr *cl;
struct clockintr_queue *cq = &ci->ci_queue;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clockintr.h,v 1.16 2023/09/14 22:07:11 cheloha Exp $ */
/* $OpenBSD: clockintr.h,v 1.17 2023/09/15 11:48:48 deraadt Exp $ */
/*
* Copyright (c) 2020-2022 Scott Cheloha <cheloha@openbsd.org>
*
@ -128,7 +128,7 @@ void clockintr_trigger(void);
uint64_t clockintr_advance(struct clockintr *, uint64_t);
uint64_t clockintr_advance_random(struct clockintr *, uint64_t, uint32_t);
void clockintr_cancel(struct clockintr *);
struct clockintr *clockintr_establish(struct cpu_info *,
struct clockintr *clockintr_establish(void *,
void (*)(struct clockintr *, void *, void *), void *);
void clockintr_stagger(struct clockintr *, uint64_t, uint32_t, uint32_t);
void clockqueue_init(struct clockintr_queue *);

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: awk.1,v 1.63 2021/11/08 06:46:22 jmc Exp $
.\" $OpenBSD: awk.1,v 1.64 2023/09/15 15:07:08 jsg Exp $
.\"
.\" Copyright (C) Lucent Technologies 1997
.\" All Rights Reserved
@ -22,7 +22,7 @@
.\" ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
.\" THIS SOFTWARE.
.\"
.Dd $Mdocdate: November 8 2021 $
.Dd $Mdocdate: September 15 2023 $
.Dt AWK 1
.Os
.Sh NAME
@ -1001,8 +1001,8 @@ No others do.
.%A P. J. Weinberger
.%T The AWK Programming Language
.%I Addison-Wesley
.%D 1988
.%O ISBN 0-201-07981-X
.%D 2024
.%O ISBN 0-13-826972-6
.Re
.Sh STANDARDS
The

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cfg.c,v 1.86 2022/06/20 07:59:37 nicm Exp $ */
/* $OpenBSD: cfg.c,v 1.87 2023/09/15 06:31:49 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -67,6 +67,7 @@ start_cfg(void)
{
struct client *c;
u_int i;
int flags = 0;
/*
* Configuration files are loaded without a client, so commands are run
@ -84,19 +85,17 @@ start_cfg(void)
cmdq_append(c, cfg_item);
}
for (i = 0; i < cfg_nfiles; i++) {
if (cfg_quiet)
load_cfg(cfg_files[i], c, NULL, CMD_PARSE_QUIET, NULL);
else
load_cfg(cfg_files[i], c, NULL, 0, NULL);
}
if (cfg_quiet)
flags = CMD_PARSE_QUIET;
for (i = 0; i < cfg_nfiles; i++)
load_cfg(cfg_files[i], c, NULL, NULL, flags, NULL);
cmdq_append(NULL, cmdq_get_callback(cfg_done, NULL));
}
int
load_cfg(const char *path, struct client *c, struct cmdq_item *item, int flags,
struct cmdq_item **new_item)
load_cfg(const char *path, struct client *c, struct cmdq_item *item,
struct cmd_find_state *current, int flags, struct cmdq_item **new_item)
{
FILE *f;
struct cmd_parse_input pi;
@ -135,7 +134,7 @@ load_cfg(const char *path, struct client *c, struct cmdq_item *item, int flags,
}
if (item != NULL)
state = cmdq_copy_state(cmdq_get_state(item));
state = cmdq_copy_state(cmdq_get_state(item), current);
else
state = cmdq_new_state(NULL, NULL, 0);
cmdq_add_format(state, "current_file", "%s", pi.file);
@ -155,8 +154,8 @@ load_cfg(const char *path, struct client *c, struct cmdq_item *item, int flags,
int
load_cfg_from_buffer(const void *buf, size_t len, const char *path,
struct client *c, struct cmdq_item *item, int flags,
struct cmdq_item **new_item)
struct client *c, struct cmdq_item *item, struct cmd_find_state *current,
int flags, struct cmdq_item **new_item)
{
struct cmd_parse_input pi;
struct cmd_parse_result *pr;
@ -187,7 +186,7 @@ load_cfg_from_buffer(const void *buf, size_t len, const char *path,
}
if (item != NULL)
state = cmdq_copy_state(cmdq_get_state(item));
state = cmdq_copy_state(cmdq_get_state(item), current);
else
state = cmdq_new_state(NULL, NULL, 0);
cmdq_add_format(state, "current_file", "%s", pi.file);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-queue.c,v 1.114 2023/02/05 21:15:32 nicm Exp $ */
/* $OpenBSD: cmd-queue.c,v 1.115 2023/09/15 06:31:49 nicm Exp $ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -237,8 +237,10 @@ cmdq_link_state(struct cmdq_state *state)
/* Make a copy of a state. */
struct cmdq_state *
cmdq_copy_state(struct cmdq_state *state)
cmdq_copy_state(struct cmdq_state *state, struct cmd_find_state *current)
{
if (current != NULL)
return (cmdq_new_state(current, &state->event, state->flags));
return (cmdq_new_state(&state->current, &state->event, state->flags));
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-source-file.c,v 1.53 2021/08/23 11:04:21 nicm Exp $ */
/* $OpenBSD: cmd-source-file.c,v 1.54 2023/09/15 06:31:49 nicm Exp $ */
/*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@ -36,8 +36,10 @@ const struct cmd_entry cmd_source_file_entry = {
.name = "source-file",
.alias = "source",
.args = { "Fnqv", 1, -1, NULL },
.usage = "[-Fnqv] path ...",
.args = { "t:Fnqv", 1, -1, NULL },
.usage = "[-Fnqv] " CMD_TARGET_PANE_USAGE " path ...",
.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
.flags = 0,
.exec = cmd_source_file_exec
@ -93,6 +95,7 @@ cmd_source_file_done(struct client *c, const char *path, int error,
size_t bsize = EVBUFFER_LENGTH(buffer);
u_int n;
struct cmdq_item *new_item;
struct cmd_find_state *target = cmdq_get_target(item);
if (!closed)
return;
@ -101,7 +104,7 @@ cmd_source_file_done(struct client *c, const char *path, int error,
cmdq_error(item, "%s: %s", path, strerror(error));
else if (bsize != 0) {
if (load_cfg_from_buffer(bdata, bsize, path, c, cdata->after,
cdata->flags, &new_item) < 0)
target, cdata->flags, &new_item) < 0)
cdata->retval = CMD_RETURN_ERROR;
else if (new_item != NULL)
cdata->after = new_item;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: input.c,v 1.220 2023/08/23 08:30:07 nicm Exp $ */
/* $OpenBSD: input.c,v 1.222 2023/09/15 06:31:49 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -169,6 +169,7 @@ static void input_csi_dispatch_rm(struct input_ctx *);
static void input_csi_dispatch_rm_private(struct input_ctx *);
static void input_csi_dispatch_sm(struct input_ctx *);
static void input_csi_dispatch_sm_private(struct input_ctx *);
static void input_csi_dispatch_sm_graphics(struct input_ctx *);
static void input_csi_dispatch_winops(struct input_ctx *);
static void input_csi_dispatch_sgr_256(struct input_ctx *, int, u_int *);
static void input_csi_dispatch_sgr_rgb(struct input_ctx *, int, u_int *);
@ -203,7 +204,7 @@ enum input_esc_type {
INPUT_ESC_SCSG0_ON,
INPUT_ESC_SCSG1_OFF,
INPUT_ESC_SCSG1_ON,
INPUT_ESC_ST,
INPUT_ESC_ST
};
/* Escape command table. */
@ -259,11 +260,12 @@ enum input_csi_type {
INPUT_CSI_SGR,
INPUT_CSI_SM,
INPUT_CSI_SM_PRIVATE,
INPUT_CSI_SM_GRAPHICS,
INPUT_CSI_SU,
INPUT_CSI_TBC,
INPUT_CSI_VPA,
INPUT_CSI_WINOPS,
INPUT_CSI_XDA,
INPUT_CSI_XDA
};
/* Control (CSI) command table. */
@ -283,6 +285,7 @@ static const struct input_table_entry input_csi_table[] = {
{ 'M', "", INPUT_CSI_DL },
{ 'P', "", INPUT_CSI_DCH },
{ 'S', "", INPUT_CSI_SU },
{ 'S', "?", INPUT_CSI_SM_GRAPHICS },
{ 'T', "", INPUT_CSI_SD },
{ 'X', "", INPUT_CSI_ECH },
{ 'Z', "", INPUT_CSI_CBT },
@ -306,7 +309,7 @@ static const struct input_table_entry input_csi_table[] = {
{ 'r', "", INPUT_CSI_DECSTBM },
{ 's', "", INPUT_CSI_SCP },
{ 't', "", INPUT_CSI_WINOPS },
{ 'u', "", INPUT_CSI_RCP },
{ 'u', "", INPUT_CSI_RCP }
};
/* Input transition. */
@ -1595,6 +1598,9 @@ input_csi_dispatch(struct input_ctx *ictx)
case INPUT_CSI_SM_PRIVATE:
input_csi_dispatch_sm_private(ictx);
break;
case INPUT_CSI_SM_GRAPHICS:
input_csi_dispatch_sm_graphics(ictx);
break;
case INPUT_CSI_SU:
n = input_get(ictx, 0, 1, 1);
if (n != -1)
@ -1827,6 +1833,12 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
}
}
/* Handle CSI graphics SM. */
static void
input_csi_dispatch_sm_graphics(__unused struct input_ctx *ictx)
{
}
/* Handle CSI window operations. */
static void
input_csi_dispatch_winops(struct input_ctx *ictx)
@ -1834,6 +1846,7 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
struct screen_write_ctx *sctx = &ictx->ctx;
struct screen *s = sctx->s;
struct window_pane *wp = ictx->wp;
struct window *w = wp->window;
u_int x = screen_size_x(s), y = screen_size_y(s);
int n, m;
@ -1847,8 +1860,6 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
case 7:
case 11:
case 13:
case 14:
case 19:
case 20:
case 21:
case 24:
@ -1866,6 +1877,21 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
if (input_get(ictx, m, 0, -1) == -1)
return;
break;
case 14:
input_reply(ictx, "\033[4;%u;%ut", y * w->ypixel, x * w->xpixel);
break;
case 15:
input_reply(ictx, "\033[5;%u;%ut", y * w->ypixel, x * w->xpixel);
break;
case 16:
input_reply(ictx, "\033[6;%u;%ut", w->ypixel, w->xpixel);
break;
case 18:
input_reply(ictx, "\033[8;%u;%ut", y, x);
break;
case 19:
input_reply(ictx, "\033[9;%u;%ut", y, x);
break;
case 22:
m++;
switch (input_get(ictx, m, 0, -1)) {
@ -1893,9 +1919,6 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
break;
}
break;
case 18:
input_reply(ictx, "\033[8;%u;%ut", y, x);
break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
break;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: screen-write.c,v 1.221 2023/09/14 13:01:35 nicm Exp $ */
/* $OpenBSD: screen-write.c,v 1.222 2023/09/15 15:49:05 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -32,8 +32,8 @@ static void screen_write_collect_flush(struct screen_write_ctx *, int,
const char *);
static int screen_write_overwrite(struct screen_write_ctx *,
struct grid_cell *, u_int);
static const struct grid_cell *screen_write_combine(struct screen_write_ctx *,
const struct utf8_data *, u_int *, u_int *);
static int screen_write_combine(struct screen_write_ctx *,
const struct grid_cell *);
struct screen_write_citem {
u_int x;
@ -1742,7 +1742,6 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
if (ci->used == 0)
return;
ctx->flags &= ~SCREEN_WRITE_COMBINE;
before = screen_write_collect_trim(ctx, s->cy, s->cx, ci->used,
&wrapped);
@ -1841,65 +1840,22 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
{
struct screen *s = ctx->s;
struct grid *gd = s->grid;
struct grid_cell copy;
const struct utf8_data *ud = &gc->data, *previous = NULL, *combine;
const struct utf8_data *ud = &gc->data;
struct grid_line *gl;
struct grid_cell_entry *gce;
struct grid_cell tmp_gc, now_gc;
struct tty_ctx ttyctx;
u_int sx = screen_size_x(s), sy = screen_size_y(s);
u_int width = ud->width, xx, last, cx, cy;
u_int width = ud->width, xx, not_wrap;
int selected, skip = 1;
/* Ignore padding cells. */
if (gc->flags & GRID_FLAG_PADDING)
return;
/* Check if this cell needs to be combined with the previous cell. */
if (ctx->flags & SCREEN_WRITE_COMBINE)
previous = &ctx->previous;
switch (utf8_try_combined(ud, previous, &combine, &width)) {
case UTF8_DISCARD_NOW:
log_debug("%s: UTF8_DISCARD_NOW (width %u)", __func__, width);
ctx->flags &= ~SCREEN_WRITE_COMBINE;
/* Get the previous cell to check for combining. */
if (screen_write_combine(ctx, gc) != 0)
return;
case UTF8_WRITE_NOW:
log_debug("%s: UTF8_WRITE_NOW (width %u)", __func__, width);
ctx->flags &= ~SCREEN_WRITE_COMBINE;
break;
case UTF8_COMBINE_NOW:
log_debug("%s: UTF8_COMBINE_NOW (width %u)", __func__, width);
screen_write_collect_flush(ctx, 0, __func__);
gc = screen_write_combine(ctx, combine, &xx, &cx);
if (gc != NULL) {
cx = s->cx; cy = s->cy;
screen_write_set_cursor(ctx, xx, s->cy);
screen_write_initctx(ctx, &ttyctx, 0);
ttyctx.cell = gc;
tty_write(tty_cmd_cell, &ttyctx);
s->cx = cx; s->cy = cy;
}
ctx->flags &= ~SCREEN_WRITE_COMBINE;
return;
case UTF8_WRITE_MAYBE_COMBINE:
log_debug("%s: UTF8_WRITE_MAYBE_COMBINE (width %u)", __func__,
width);
utf8_copy(&ctx->previous, ud);
ctx->flags |= SCREEN_WRITE_COMBINE;
break;
case UTF8_DISCARD_MAYBE_COMBINE:
log_debug("%s: UTF8_DISCARD_MAYBE_COMBINE (width %u)", __func__,
width);
utf8_copy(&ctx->previous, ud);
ctx->flags |= SCREEN_WRITE_COMBINE;
return;
}
if (width != ud->width) {
memcpy(&copy, gc, sizeof copy);
copy.data.width = width;
gc = &copy;
}
ud = NULL;
/* Flush any existing scrolling. */
screen_write_collect_flush(ctx, 1, __func__);
@ -1991,11 +1947,11 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
* Move the cursor. If not wrapping, stick at the last character and
* replace it.
*/
last = !(s->mode & MODE_WRAP);
if (s->cx <= sx - last - width)
not_wrap = !(s->mode & MODE_WRAP);
if (s->cx <= sx - not_wrap - width)
screen_write_set_cursor(ctx, s->cx + width, -1);
else
screen_write_set_cursor(ctx, sx - last, -1);
screen_write_set_cursor(ctx, sx - not_wrap, -1);
/* Create space for character in insert mode. */
if (s->mode & MODE_INSERT) {
@ -2015,65 +1971,98 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
}
}
/* Combine a UTF-8 zero-width character onto the previous. */
static const struct grid_cell *
screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud,
u_int *xx, u_int *cx)
/* Combine a UTF-8 zero-width character onto the previous if necessary. */
static int
screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
{
struct screen *s = ctx->s;
struct grid *gd = s->grid;
static struct grid_cell gc;
u_int n, width;
const struct utf8_data *ud = &gc->data;
u_int n, cx = s->cx, cy = s->cy;
struct grid_cell last;
struct tty_ctx ttyctx;
int force_wide = 0, zero_width = 0;
/* Can't combine if at 0. */
if (s->cx == 0) {
*xx = 0;
return (NULL);
/*
* Is this character which makes no sense without being combined? If
* this is true then flag it here and discard the character (return 1)
* if we cannot combine it.
*/
if (utf8_is_zwj(ud))
zero_width = 1;
else if (utf8_is_vs(ud))
zero_width = force_wide = 1;
else if (ud->width == 0)
zero_width = 1;
/* Cannot combine empty character or at left. */
if (ud->size < 2 || cx == 0)
return (zero_width);
log_debug("%s: character %.*s at %u,%u (width %u)", __func__,
(int)ud->size, ud->data, cx, cy, ud->width);
/* Find the cell to combine with. */
n = 1;
grid_view_get_cell(gd, cx - n, cy, &last);
if (cx != 1 && (last.flags & GRID_FLAG_PADDING)) {
n = 2;
grid_view_get_cell(gd, cx - n, cy, &last);
}
*xx = s->cx;
if (n != last.data.width || (last.flags & GRID_FLAG_PADDING))
return (zero_width);
/* Empty data is out. */
if (ud->size == 0)
fatalx("UTF-8 data empty");
/* Retrieve the previous cell. */
for (n = 1; n <= s->cx; n++) {
grid_view_get_cell(gd, s->cx - n, s->cy, &gc);
if (~gc.flags & GRID_FLAG_PADDING)
break;
/*
* Check if we need to combine characters. This could be zero width
* (zet above), a modifier character (with an existing Unicode
* character) or a previous ZWJ.
*/
if (!zero_width) {
if (utf8_is_modifier(ud)) {
if (last.data.size < 2)
return (0);
force_wide = 1;
} else if (!utf8_has_zwj(&last.data))
return (0);
}
if (n > s->cx)
return (NULL);
/* Check there is enough space. */
if (gc.data.size + ud->size > sizeof gc.data.data)
return (NULL);
(*xx) -= n;
/* Combining; flush any pending output. */
screen_write_collect_flush(ctx, 0, __func__);
log_debug("%s: %.*s onto %.*s at %u,%u (width %u)", __func__,
(int)ud->size, ud->data, (int)gc.data.size, gc.data.data, *xx,
s->cy, gc.data.width);
log_debug("%s: %.*s -> %.*s at %u,%u (offset %u, width %u)", __func__,
(int)ud->size, ud->data, (int)last.data.size, last.data.data,
cx - n, cy, n, last.data.width);
/* Append the data. */
memcpy(gc.data.data + gc.data.size, ud->data, ud->size);
gc.data.size += ud->size;
width = gc.data.width;
memcpy(last.data.data + last.data.size, ud->data, ud->size);
last.data.size += ud->size;
/* If this is U+FE0F VARIATION SELECTOR-16, force the width to 2. */
if (gc.data.width == 1 &&
ud->size == 3 &&
memcmp(ud->data, "\357\270\217", 3) == 0) {
grid_view_set_padding(gd, (*xx) + 1, s->cy);
gc.data.width = 2;
width += 2;
}
/* Force the width to 2 for modifiers and variation selector. */
if (last.data.width == 1 && force_wide) {
last.data.width = 2;
n = 2;
cx++;
} else
force_wide = 0;
/* Set the new cell. */
grid_view_set_cell(gd, *xx, s->cy, &gc);
grid_view_set_cell(gd, cx - n, cy, &last);
if (force_wide)
grid_view_set_padding(gd, cx, cy);
*cx = (*xx) + width;
log_debug("%s: character at %u; cursor at %u", __func__, *xx, *cx);
return (&gc);
/*
* Redraw the combined cell. If forcing the cell to width 2, reset the
* cached cursor position in the tty, since we don't really know
* whether the terminal thought the character was width 1 or width 2
* and what it is going to do now.
*/
screen_write_set_cursor(ctx, cx - n, cy);
screen_write_initctx(ctx, &ttyctx, 0);
ttyctx.cell = &last;
ttyctx.num = force_wide; /* reset cached cursor position */
tty_write(tty_cmd_cell, &ttyctx);
screen_write_set_cursor(ctx, cx, cy);
return (1);
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: server.c,v 1.204 2023/09/01 14:29:11 nicm Exp $ */
/* $OpenBSD: server.c,v 1.205 2023/09/15 15:49:05 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -205,7 +205,6 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base,
fatal("pledge failed");
input_key_build();
utf8_build_combined();
RB_INIT(&windows);
RB_INIT(&all_window_panes);
TAILQ_INIT(&clients);

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: tmux.1,v 1.931 2023/09/02 09:17:23 nicm Exp $
.\" $OpenBSD: tmux.1,v 1.932 2023/09/15 06:31:49 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: September 2 2023 $
.Dd $Mdocdate: September 15 2023 $
.Dt TMUX 1
.Os
.Sh NAME
@ -1546,6 +1546,7 @@ show debugging information about jobs and terminals.
.Tg source
.It Xo Ic source-file
.Op Fl Fnqv
.Op Fl t Ar target-pane
.Ar path ...
.Xc
.D1 Pq alias: Ic source

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tmux.h,v 1.1209 2023/09/02 20:03:10 nicm Exp $ */
/* $OpenBSD: tmux.h,v 1.1211 2023/09/15 15:49:05 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -30,6 +30,7 @@
#include <stdint.h>
#include <stdio.h>
#include <termios.h>
#include <wchar.h>
#include "tmux-protocol.h"
#include "xmalloc.h"
@ -619,15 +620,6 @@ enum utf8_state {
UTF8_ERROR
};
/* UTF-8 combine state. */
enum utf8_combine_state {
UTF8_DISCARD_NOW, /* discard immediately */
UTF8_WRITE_NOW, /* do not combine, write immediately */
UTF8_COMBINE_NOW, /* combine immediately */
UTF8_WRITE_MAYBE_COMBINE, /* write but try to combine the next */
UTF8_DISCARD_MAYBE_COMBINE /* discard but try to combine the next */
};
/* Colour flags. */
#define COLOUR_FLAG_256 0x01000000
#define COLOUR_FLAG_RGB 0x02000000
@ -900,7 +892,6 @@ struct screen_write_ctx {
int flags;
#define SCREEN_WRITE_SYNC 0x1
#define SCREEN_WRITE_COMBINE 0x2
screen_write_init_ctx_cb init_ctx_cb;
void *arg;
@ -908,7 +899,6 @@ struct screen_write_ctx {
struct screen_write_citem *item;
u_int scrolled;
u_int bg;
struct utf8_data previous;
};
/* Box border lines option. */
@ -2102,10 +2092,11 @@ extern char **cfg_files;
extern u_int cfg_nfiles;
extern int cfg_quiet;
void start_cfg(void);
int load_cfg(const char *, struct client *, struct cmdq_item *, int,
struct cmdq_item **);
int load_cfg(const char *, struct client *, struct cmdq_item *,
struct cmd_find_state *, int, struct cmdq_item **);
int load_cfg_from_buffer(const void *, size_t, const char *,
struct client *, struct cmdq_item *, int, struct cmdq_item **);
struct client *, struct cmdq_item *, struct cmd_find_state *,
int, struct cmdq_item **);
void printflike(1, 2) cfg_add_cause(const char *, ...);
void cfg_print_causes(struct cmdq_item *);
void cfg_show_causes(struct session *);
@ -2551,7 +2542,8 @@ struct cmd_parse_result *cmd_parse_from_arguments(struct args_value *, u_int,
struct cmdq_state *cmdq_new_state(struct cmd_find_state *, struct key_event *,
int);
struct cmdq_state *cmdq_link_state(struct cmdq_state *);
struct cmdq_state *cmdq_copy_state(struct cmdq_state *);
struct cmdq_state *cmdq_copy_state(struct cmdq_state *,
struct cmd_find_state *);
void cmdq_free_state(struct cmdq_state *);
void printflike(3, 4) cmdq_add_format(struct cmdq_state *, const char *,
const char *, ...);
@ -3275,6 +3267,8 @@ u_int session_group_attached_count(struct session_group *);
void session_renumber_windows(struct session *);
/* utf8.c */
enum utf8_state utf8_towc (const struct utf8_data *, wchar_t *);
int utf8_in_table(wchar_t, const wchar_t *, u_int);
utf8_char utf8_build_one(u_char);
enum utf8_state utf8_from_data(const struct utf8_data *, utf8_char *);
void utf8_to_data(utf8_char, struct utf8_data *);
@ -3297,10 +3291,10 @@ char *utf8_rpadcstr(const char *, u_int);
int utf8_cstrhas(const char *, const struct utf8_data *);
/* utf8-combined.c */
void utf8_build_combined(void);
int utf8_try_combined(const struct utf8_data *,
const struct utf8_data *, const struct utf8_data **,
u_int *width);
int utf8_has_zwj(const struct utf8_data *);
int utf8_is_zwj(const struct utf8_data *);
int utf8_is_vs(const struct utf8_data *);
int utf8_is_modifier(const struct utf8_data *);
/* procname.c */
char *get_proc_name(int, char *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tty.c,v 1.434 2023/09/02 20:03:10 nicm Exp $ */
/* $OpenBSD: tty.c,v 1.435 2023/09/15 15:49:05 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -2091,6 +2091,9 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
tty_cell(tty, ctx->cell, &ctx->defaults, ctx->palette,
ctx->s->hyperlinks);
if (ctx->num == 1)
tty_invalidate(tty);
}
void

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $OpenBSD: utf8.c,v 1.63 2023/09/01 14:29:11 nicm Exp $ */
/* $OpenBSD: utf8.c,v 1.64 2023/09/15 15:49:05 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -23,10 +23,174 @@
#include <stdlib.h>
#include <string.h>
#include <vis.h>
#include <wchar.h>
#include "tmux.h"
static const wchar_t utf8_force_wide[] = {
0x0261D,
0x026F9,
0x0270A,
0x0270B,
0x0270C,
0x0270D,
0x1F1E6,
0x1F1E7,
0x1F1E8,
0x1F1E9,
0x1F1EA,
0x1F1EB,
0x1F1EC,
0x1F1ED,
0x1F1EE,
0x1F1EF,
0x1F1F0,
0x1F1F1,
0x1F1F2,
0x1F1F3,
0x1F1F4,
0x1F1F5,
0x1F1F6,
0x1F1F7,
0x1F1F8,
0x1F1F9,
0x1F1FA,
0x1F1FB,
0x1F1FC,
0x1F1FD,
0x1F1FE,
0x1F1FF,
0x1F385,
0x1F3C2,
0x1F3C3,
0x1F3C4,
0x1F3C7,
0x1F3CA,
0x1F3CB,
0x1F3CC,
0x1F3FB,
0x1F3FC,
0x1F3FD,
0x1F3FE,
0x1F3FF,
0x1F442,
0x1F443,
0x1F446,
0x1F447,
0x1F448,
0x1F449,
0x1F44A,
0x1F44B,
0x1F44C,
0x1F44D,
0x1F44E,
0x1F44F,
0x1F450,
0x1F466,
0x1F467,
0x1F468,
0x1F469,
0x1F46B,
0x1F46C,
0x1F46D,
0x1F46E,
0x1F470,
0x1F471,
0x1F472,
0x1F473,
0x1F474,
0x1F475,
0x1F476,
0x1F477,
0x1F478,
0x1F47C,
0x1F481,
0x1F482,
0x1F483,
0x1F485,
0x1F486,
0x1F487,
0x1F48F,
0x1F491,
0x1F4AA,
0x1F574,
0x1F575,
0x1F57A,
0x1F590,
0x1F595,
0x1F596,
0x1F645,
0x1F646,
0x1F647,
0x1F64B,
0x1F64C,
0x1F64D,
0x1F64E,
0x1F64F,
0x1F6A3,
0x1F6B4,
0x1F6B5,
0x1F6B6,
0x1F6C0,
0x1F6CC,
0x1F90C,
0x1F90F,
0x1F918,
0x1F919,
0x1F91A,
0x1F91B,
0x1F91C,
0x1F91D,
0x1F91E,
0x1F91F,
0x1F926,
0x1F930,
0x1F931,
0x1F932,
0x1F933,
0x1F934,
0x1F935,
0x1F936,
0x1F937,
0x1F938,
0x1F939,
0x1F93D,
0x1F93E,
0x1F977,
0x1F9B5,
0x1F9B6,
0x1F9B8,
0x1F9B9,
0x1F9BB,
0x1F9CD,
0x1F9CE,
0x1F9CF,
0x1F9D1,
0x1F9D2,
0x1F9D3,
0x1F9D4,
0x1F9D5,
0x1F9D6,
0x1F9D7,
0x1F9D8,
0x1F9D9,
0x1F9DA,
0x1F9DB,
0x1F9DC,
0x1F9DD,
0x1FAC3,
0x1FAC4,
0x1FAC5,
0x1FAF0,
0x1FAF1,
0x1FAF2,
0x1FAF3,
0x1FAF4,
0x1FAF5,
0x1FAF6,
0x1FAF7,
0x1FAF8
};
struct utf8_item {
RB_ENTRY(utf8_item) index_entry;
u_int index;
@ -123,6 +287,28 @@ utf8_put_item(const u_char *data, size_t size, u_int *index)
return (0);
}
static int
utf8_table_cmp(const void *vp1, const void *vp2)
{
const wchar_t *wc1 = vp1, *wc2 = vp2;
if (*wc1 < *wc2)
return (-1);
if (*wc1 > *wc2)
return (1);
return (0);
}
/* Check if character in table. */
int
utf8_in_table(wchar_t find, const wchar_t *table, u_int count)
{
wchar_t *found;
found = bsearch(&find, table, count, sizeof *table, utf8_table_cmp);
return (found != NULL);
}
/* Get UTF-8 character from data. */
enum utf8_state
utf8_from_data(const struct utf8_data *ud, utf8_char *uc)
@ -217,16 +403,13 @@ utf8_width(struct utf8_data *ud, int *width)
{
wchar_t wc;
switch (mbtowc(&wc, ud->data, ud->size)) {
case -1:
log_debug("UTF-8 %.*s, mbtowc() %d", (int)ud->size, ud->data,
errno);
mbtowc(NULL, NULL, MB_CUR_MAX);
return (UTF8_ERROR);
case 0:
if (utf8_towc(ud, &wc) != UTF8_DONE)
return (UTF8_ERROR);
if (utf8_in_table(wc, utf8_force_wide, nitems(utf8_force_wide))) {
*width = 2;
return (UTF8_DONE);
}
log_debug("UTF-8 %.*s is %05X", (int)ud->size, ud->data, (u_int)wc);
*width = wcwidth(wc);
log_debug("wcwidth(%05X) returned %d", (u_int)wc, *width);
if (*width < 0) {
@ -241,6 +424,23 @@ utf8_width(struct utf8_data *ud, int *width)
return (UTF8_ERROR);
}
/* Convert UTF-8 character to wide character. */
enum utf8_state
utf8_towc(const struct utf8_data *ud, wchar_t *wc)
{
switch (mbtowc(wc, ud->data, ud->size)) {
case -1:
log_debug("UTF-8 %.*s, mbtowc() %d", (int)ud->size, ud->data,
errno);
mbtowc(NULL, NULL, MB_CUR_MAX);
return (UTF8_ERROR);
case 0:
return (UTF8_ERROR);
}
log_debug("UTF-8 %.*s is %05X", (int)ud->size, ud->data, (u_int)*wc);
return (UTF8_DONE);
}
/*
* Open UTF-8 sequence.
*

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: btrace.8,v 1.8 2022/12/22 19:53:24 kn Exp $
.\" $OpenBSD: btrace.8,v 1.9 2023/09/15 10:56:46 claudio Exp $
.\"
.\" Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
.\"
@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: December 22 2022 $
.Dd $Mdocdate: September 15 2023 $
.Dt BTRACE 8
.Os
.Sh NAME
@ -24,6 +24,7 @@
.Nm btrace
.Op Fl lnv
.Op Fl e Ar program | Ar file
.Op Fl p Ar file
.Op Ar argument ...
.Sh DESCRIPTION
The
@ -47,6 +48,12 @@ List all available probes.
.It Fl n
No action.
Parse the program and then exit.
.It Fl p Ar file
Load symbols from
.Ar file
to convert
.Va ustack
addresses into function names.
.It Fl v
Verbose mode.
Causes

View File

@ -1,4 +1,4 @@
/* $OpenBSD: btrace.c,v 1.77 2023/09/13 13:47:58 mpi Exp $ */
/* $OpenBSD: btrace.c,v 1.78 2023/09/15 10:59:02 claudio Exp $ */
/*
* Copyright (c) 2019 - 2023 Martin Pieuchot <mpi@openbsd.org>
@ -233,8 +233,8 @@ main(int argc, char *argv[])
__dead void
usage(void)
{
fprintf(stderr, "usage: %s [-lnv] [-e program | file] [argument ...]\n",
getprogname());
fprintf(stderr, "usage: %s [-lnv] [-e program | file] [-p file] "
"[argument ...]\n", getprogname());
exit(1);
}