mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Update imsg and remove workaround.
This commit is contained in:
parent
db771ec6e3
commit
252f41818e
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: imsg-buffer.c,v 1.30 2024/11/22 07:20:50 tb Exp $ */
|
/* $OpenBSD: imsg-buffer.c,v 1.31 2024/11/26 13:57:31 claudio Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
|
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
|
||||||
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <endian.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -51,7 +52,7 @@ struct msgbuf {
|
|||||||
uint32_t queued;
|
uint32_t queued;
|
||||||
char *rbuf;
|
char *rbuf;
|
||||||
struct ibuf *rpmsg;
|
struct ibuf *rpmsg;
|
||||||
ssize_t (*readhdr)(struct ibuf *, void *);
|
struct ibuf *(*readhdr)(struct ibuf *, void *, int *);
|
||||||
void *rarg;
|
void *rarg;
|
||||||
size_t roff;
|
size_t roff;
|
||||||
size_t hdrsize;
|
size_t hdrsize;
|
||||||
@ -587,8 +588,8 @@ msgbuf_new(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct msgbuf *
|
struct msgbuf *
|
||||||
msgbuf_new_reader(size_t hdrsz, ssize_t (*readhdr)(struct ibuf *, void *),
|
msgbuf_new_reader(size_t hdrsz,
|
||||||
void *arg)
|
struct ibuf *(*readhdr)(struct ibuf *, void *, int *), void *arg)
|
||||||
{
|
{
|
||||||
struct msgbuf *msgbuf;
|
struct msgbuf *msgbuf;
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -771,33 +772,16 @@ ibuf_read_process(struct msgbuf *msgbuf, int fd)
|
|||||||
|
|
||||||
ibuf_from_buffer(&rbuf, msgbuf->rbuf, msgbuf->roff);
|
ibuf_from_buffer(&rbuf, msgbuf->rbuf, msgbuf->roff);
|
||||||
|
|
||||||
/* fds must be passed at start of message of at least hdrsize bytes */
|
|
||||||
if (msgbuf->rpmsg != NULL && fd != -1) {
|
|
||||||
close(fd);
|
|
||||||
fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (msgbuf->rpmsg == NULL) {
|
if (msgbuf->rpmsg == NULL) {
|
||||||
if (ibuf_size(&rbuf) < msgbuf->hdrsize) {
|
if (ibuf_size(&rbuf) < msgbuf->hdrsize)
|
||||||
if (fd != -1) {
|
|
||||||
close(fd);
|
|
||||||
fd = -1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
/* get size from header */
|
/* get size from header */
|
||||||
ibuf_from_buffer(&msg, ibuf_data(&rbuf),
|
ibuf_from_buffer(&msg, ibuf_data(&rbuf),
|
||||||
msgbuf->hdrsize);
|
msgbuf->hdrsize);
|
||||||
sz = msgbuf->readhdr(&msg, msgbuf->rarg);
|
if ((msgbuf->rpmsg = msgbuf->readhdr(&msg,
|
||||||
if (sz == -1)
|
msgbuf->rarg, &fd)) == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
if ((msgbuf->rpmsg = ibuf_open(sz)) == NULL)
|
|
||||||
goto fail;
|
|
||||||
if (fd != -1) {
|
|
||||||
ibuf_fd_set(msgbuf->rpmsg, fd);
|
|
||||||
fd = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibuf_left(msgbuf->rpmsg) <= ibuf_size(&rbuf))
|
if (ibuf_left(msgbuf->rpmsg) <= ibuf_size(&rbuf))
|
||||||
@ -820,10 +804,14 @@ ibuf_read_process(struct msgbuf *msgbuf, int fd)
|
|||||||
memmove(msgbuf->rbuf, ibuf_data(&rbuf), ibuf_size(&rbuf));
|
memmove(msgbuf->rbuf, ibuf_data(&rbuf), ibuf_size(&rbuf));
|
||||||
msgbuf->roff = ibuf_size(&rbuf);
|
msgbuf->roff = ibuf_size(&rbuf);
|
||||||
|
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* XXX cleanup */
|
/* XXX how to properly clean up is unclear */
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: imsg.c,v 1.36 2024/11/21 13:03:21 claudio Exp $ */
|
/* $OpenBSD: imsg.c,v 1.37 2024/11/26 13:57:31 claudio Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
|
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -30,8 +31,9 @@
|
|||||||
#include "imsg.h"
|
#include "imsg.h"
|
||||||
|
|
||||||
#define IMSG_ALLOW_FDPASS 0x01
|
#define IMSG_ALLOW_FDPASS 0x01
|
||||||
|
#define IMSG_FD_MARK 0x80000000U
|
||||||
|
|
||||||
static ssize_t imsg_parse_hdr(struct ibuf *, void *);
|
static struct ibuf *imsg_parse_hdr(struct ibuf *, void *, int *);
|
||||||
|
|
||||||
int
|
int
|
||||||
imsgbuf_init(struct imsgbuf *imsgbuf, int fd)
|
imsgbuf_init(struct imsgbuf *imsgbuf, int fd)
|
||||||
@ -53,12 +55,15 @@ imsgbuf_allow_fdpass(struct imsgbuf *imsgbuf)
|
|||||||
imsgbuf->flags |= IMSG_ALLOW_FDPASS;
|
imsgbuf->flags |= IMSG_ALLOW_FDPASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
imsgbuf_set_maxsize(struct imsgbuf *imsgbuf, uint32_t maxsize)
|
imsgbuf_set_maxsize(struct imsgbuf *imsgbuf, uint32_t maxsize)
|
||||||
{
|
{
|
||||||
if (maxsize < IMSG_HEADER_SIZE)
|
if (maxsize < IMSG_HEADER_SIZE || maxsize & IMSG_FD_MARK) {
|
||||||
return;
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
imsgbuf->maxsize = maxsize;
|
imsgbuf->maxsize = maxsize;
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -119,6 +124,7 @@ imsg_get(struct imsgbuf *imsgbuf, struct imsg *imsg)
|
|||||||
else
|
else
|
||||||
m.data = NULL;
|
m.data = NULL;
|
||||||
m.buf = buf;
|
m.buf = buf;
|
||||||
|
m.hdr.len &= ~IMSG_FD_MARK;
|
||||||
|
|
||||||
*imsg = m;
|
*imsg = m;
|
||||||
return (ibuf_size(buf) + IMSG_HEADER_SIZE);
|
return (ibuf_size(buf) + IMSG_HEADER_SIZE);
|
||||||
@ -267,7 +273,7 @@ int
|
|||||||
imsg_forward(struct imsgbuf *imsgbuf, struct imsg *msg)
|
imsg_forward(struct imsgbuf *imsgbuf, struct imsg *msg)
|
||||||
{
|
{
|
||||||
struct ibuf *wbuf;
|
struct ibuf *wbuf;
|
||||||
size_t len = 0;
|
size_t len;
|
||||||
|
|
||||||
ibuf_rewind(msg->buf);
|
ibuf_rewind(msg->buf);
|
||||||
ibuf_skip(msg->buf, sizeof(msg->hdr));
|
ibuf_skip(msg->buf, sizeof(msg->hdr));
|
||||||
@ -277,7 +283,7 @@ imsg_forward(struct imsgbuf *imsgbuf, struct imsg *msg)
|
|||||||
msg->hdr.pid, len)) == NULL)
|
msg->hdr.pid, len)) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
if (msg->buf != NULL) {
|
if (len != 0) {
|
||||||
if (ibuf_add_ibuf(wbuf, msg->buf) == -1) {
|
if (ibuf_add_ibuf(wbuf, msg->buf) == -1) {
|
||||||
ibuf_free(wbuf);
|
ibuf_free(wbuf);
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -329,9 +335,12 @@ void
|
|||||||
imsg_close(struct imsgbuf *imsgbuf, struct ibuf *msg)
|
imsg_close(struct imsgbuf *imsgbuf, struct ibuf *msg)
|
||||||
{
|
{
|
||||||
struct imsg_hdr *hdr;
|
struct imsg_hdr *hdr;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
hdr = (struct imsg_hdr *)msg->buf;
|
len = ibuf_size(msg);
|
||||||
hdr->len = ibuf_size(msg);
|
if (ibuf_fd_avail(msg))
|
||||||
|
len |= IMSG_FD_MARK;
|
||||||
|
(void)ibuf_set_h32(msg, offsetof(struct imsg_hdr, len), len);
|
||||||
ibuf_close(imsgbuf->w, msg);
|
ibuf_close(imsgbuf->w, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,18 +350,29 @@ imsg_free(struct imsg *imsg)
|
|||||||
ibuf_free(imsg->buf);
|
ibuf_free(imsg->buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static struct ibuf *
|
||||||
imsg_parse_hdr(struct ibuf *buf, void *arg)
|
imsg_parse_hdr(struct ibuf *buf, void *arg, int *fd)
|
||||||
{
|
{
|
||||||
struct imsgbuf *imsgbuf = arg;
|
struct imsgbuf *imsgbuf = arg;
|
||||||
struct imsg_hdr hdr;
|
struct imsg_hdr hdr;
|
||||||
|
struct ibuf *b;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
if (ibuf_get(buf, &hdr, sizeof(hdr)) == -1)
|
if (ibuf_get(buf, &hdr, sizeof(hdr)) == -1)
|
||||||
return -1;
|
return (NULL);
|
||||||
if (hdr.len < IMSG_HEADER_SIZE ||
|
|
||||||
hdr.len > imsgbuf->maxsize) {
|
len = hdr.len & ~IMSG_FD_MARK;
|
||||||
|
|
||||||
|
if (len < IMSG_HEADER_SIZE || len > imsgbuf->maxsize) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return (-1);
|
return (NULL);
|
||||||
}
|
}
|
||||||
return hdr.len;
|
if ((b = ibuf_open(len)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
if (hdr.len & IMSG_FD_MARK) {
|
||||||
|
ibuf_fd_set(b, *fd);
|
||||||
|
*fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: imsg.h,v 1.18 2024/11/21 13:03:21 claudio Exp $ */
|
/* $OpenBSD: imsg.h,v 1.19 2024/11/26 13:57:31 claudio Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
|
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
|
||||||
@ -110,8 +110,8 @@ int ibuf_fd_avail(struct ibuf *);
|
|||||||
int ibuf_fd_get(struct ibuf *);
|
int ibuf_fd_get(struct ibuf *);
|
||||||
void ibuf_fd_set(struct ibuf *, int);
|
void ibuf_fd_set(struct ibuf *, int);
|
||||||
struct msgbuf *msgbuf_new(void);
|
struct msgbuf *msgbuf_new(void);
|
||||||
struct msgbuf *msgbuf_new_reader(size_t, ssize_t (*)(struct ibuf *, void *),
|
struct msgbuf *msgbuf_new_reader(size_t,
|
||||||
void *);
|
struct ibuf *(*)(struct ibuf *, void *, int *), void *);
|
||||||
void msgbuf_free(struct msgbuf *);
|
void msgbuf_free(struct msgbuf *);
|
||||||
void msgbuf_clear(struct msgbuf *);
|
void msgbuf_clear(struct msgbuf *);
|
||||||
uint32_t msgbuf_queuelen(struct msgbuf *);
|
uint32_t msgbuf_queuelen(struct msgbuf *);
|
||||||
@ -124,7 +124,7 @@ struct ibuf *msgbuf_get(struct msgbuf *);
|
|||||||
/* imsg.c */
|
/* imsg.c */
|
||||||
int imsgbuf_init(struct imsgbuf *, int);
|
int imsgbuf_init(struct imsgbuf *, int);
|
||||||
void imsgbuf_allow_fdpass(struct imsgbuf *imsgbuf);
|
void imsgbuf_allow_fdpass(struct imsgbuf *imsgbuf);
|
||||||
void imsgbuf_set_maxsize(struct imsgbuf *, uint32_t);
|
int imsgbuf_set_maxsize(struct imsgbuf *, uint32_t);
|
||||||
int imsgbuf_read(struct imsgbuf *);
|
int imsgbuf_read(struct imsgbuf *);
|
||||||
int imsgbuf_write(struct imsgbuf *);
|
int imsgbuf_write(struct imsgbuf *);
|
||||||
int imsgbuf_flush(struct imsgbuf *);
|
int imsgbuf_flush(struct imsgbuf *);
|
||||||
|
24
proc.c
24
proc.c
@ -55,7 +55,6 @@ struct tmuxpeer {
|
|||||||
struct tmuxproc *parent;
|
struct tmuxproc *parent;
|
||||||
|
|
||||||
struct imsgbuf ibuf;
|
struct imsgbuf ibuf;
|
||||||
int lastfd;
|
|
||||||
struct event event;
|
struct event event;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
|
|
||||||
@ -72,7 +71,7 @@ static int peer_check_version(struct tmuxpeer *, struct imsg *);
|
|||||||
static void proc_update_event(struct tmuxpeer *);
|
static void proc_update_event(struct tmuxpeer *);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proc_event_cb(int fd, short events, void *arg)
|
proc_event_cb(__unused int fd, short events, void *arg)
|
||||||
{
|
{
|
||||||
struct tmuxpeer *peer = arg;
|
struct tmuxpeer *peer = arg;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
@ -90,14 +89,7 @@ proc_event_cb(int fd, short events, void *arg)
|
|||||||
}
|
}
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
break;
|
break;
|
||||||
fd = imsg_get_fd(&imsg);
|
log_debug("peer %p message %d", peer, imsg.hdr.type);
|
||||||
log_debug("peer %p message %d fd %d", peer,
|
|
||||||
imsg.hdr.type, fd);
|
|
||||||
if (fd != -1) {
|
|
||||||
if (peer->lastfd != -1)
|
|
||||||
close(peer->lastfd);
|
|
||||||
peer->lastfd = fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (peer_check_version(peer, &imsg) != 0) {
|
if (peer_check_version(peer, &imsg) != 0) {
|
||||||
imsg_free(&imsg);
|
imsg_free(&imsg);
|
||||||
@ -313,7 +305,6 @@ proc_add_peer(struct tmuxproc *tp, int fd,
|
|||||||
|
|
||||||
peer = xcalloc(1, sizeof *peer);
|
peer = xcalloc(1, sizeof *peer);
|
||||||
peer->parent = tp;
|
peer->parent = tp;
|
||||||
peer->lastfd = -1;
|
|
||||||
|
|
||||||
peer->dispatchcb = dispatchcb;
|
peer->dispatchcb = dispatchcb;
|
||||||
peer->arg = arg;
|
peer->arg = arg;
|
||||||
@ -342,8 +333,6 @@ proc_remove_peer(struct tmuxpeer *peer)
|
|||||||
event_del(&peer->event);
|
event_del(&peer->event);
|
||||||
imsgbuf_clear(&peer->ibuf);
|
imsgbuf_clear(&peer->ibuf);
|
||||||
|
|
||||||
if (peer->lastfd != -1)
|
|
||||||
close(peer->lastfd);
|
|
||||||
close(peer->ibuf.fd);
|
close(peer->ibuf.fd);
|
||||||
free(peer);
|
free(peer);
|
||||||
}
|
}
|
||||||
@ -395,12 +384,3 @@ proc_get_peer_uid(struct tmuxpeer *peer)
|
|||||||
{
|
{
|
||||||
return (peer->uid);
|
return (peer->uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
proc_get_last_fd(struct tmuxpeer *peer)
|
|
||||||
{
|
|
||||||
int fd = peer->lastfd;
|
|
||||||
|
|
||||||
peer->lastfd = -1;
|
|
||||||
return (fd);
|
|
||||||
}
|
|
||||||
|
@ -3559,13 +3559,13 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
|
|||||||
case MSG_IDENTIFY_STDIN:
|
case MSG_IDENTIFY_STDIN:
|
||||||
if (datalen != 0)
|
if (datalen != 0)
|
||||||
fatalx("bad MSG_IDENTIFY_STDIN size");
|
fatalx("bad MSG_IDENTIFY_STDIN size");
|
||||||
c->fd = proc_get_last_fd(c->peer);
|
c->fd = imsg_get_fd(imsg);
|
||||||
log_debug("client %p IDENTIFY_STDIN %d", c, c->fd);
|
log_debug("client %p IDENTIFY_STDIN %d", c, c->fd);
|
||||||
break;
|
break;
|
||||||
case MSG_IDENTIFY_STDOUT:
|
case MSG_IDENTIFY_STDOUT:
|
||||||
if (datalen != 0)
|
if (datalen != 0)
|
||||||
fatalx("bad MSG_IDENTIFY_STDOUT size");
|
fatalx("bad MSG_IDENTIFY_STDOUT size");
|
||||||
c->out_fd = proc_get_last_fd(c->peer);
|
c->out_fd = imsg_get_fd(imsg);
|
||||||
log_debug("client %p IDENTIFY_STDOUT %d", c, c->out_fd);
|
log_debug("client %p IDENTIFY_STDOUT %d", c, c->out_fd);
|
||||||
break;
|
break;
|
||||||
case MSG_IDENTIFY_ENVIRON:
|
case MSG_IDENTIFY_ENVIRON:
|
||||||
|
1
tmux.h
1
tmux.h
@ -2225,7 +2225,6 @@ void proc_flush_peer(struct tmuxpeer *);
|
|||||||
void proc_toggle_log(struct tmuxproc *);
|
void proc_toggle_log(struct tmuxproc *);
|
||||||
pid_t proc_fork_and_daemon(int *);
|
pid_t proc_fork_and_daemon(int *);
|
||||||
uid_t proc_get_peer_uid(struct tmuxpeer *);
|
uid_t proc_get_peer_uid(struct tmuxpeer *);
|
||||||
int proc_get_last_fd(struct tmuxpeer *);
|
|
||||||
|
|
||||||
/* cfg.c */
|
/* cfg.c */
|
||||||
extern int cfg_finished;
|
extern int cfg_finished;
|
||||||
|
Loading…
Reference in New Issue
Block a user