sync code with last improvements from OpenBSD
This commit is contained in:
parent
66d94126c9
commit
8b897ac235
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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(©, gc, sizeof copy);
|
||||
copy.data.width = width;
|
||||
gc = ©
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
||||
|
@ -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
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user