Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/tmux merge conflicts



details:   https://anonhg.NetBSD.org/src/rev/69f0dc82fbe8
branches:  trunk
changeset: 941907:69f0dc82fbe8
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Nov 01 15:16:04 2020 +0000

description:
merge conflicts

diffstat:

 external/bsd/tmux/dist/client.c             |   357 +++++-
 external/bsd/tmux/dist/cmd-attach-session.c |     2 +
 external/bsd/tmux/dist/cmd-capture-pane.c   |    24 +-
 external/bsd/tmux/dist/cmd-load-buffer.c    |   160 +--
 external/bsd/tmux/dist/cmd-new-session.c    |    36 +-
 external/bsd/tmux/dist/cmd-new-window.c     |     4 +-
 external/bsd/tmux/dist/cmd-parse.y          |    63 +-
 external/bsd/tmux/dist/cmd-queue.c          |    55 +-
 external/bsd/tmux/dist/cmd-resize-window.c  |     2 +-
 external/bsd/tmux/dist/cmd-send-keys.c      |    19 +-
 external/bsd/tmux/dist/cmd-split-window.c   |    37 +-
 external/bsd/tmux/dist/compat.h             |     2 +
 external/bsd/tmux/dist/format.c             |   412 +++++++-
 external/bsd/tmux/dist/grid.c               |    24 +-
 external/bsd/tmux/dist/input-keys.c         |    30 +-
 external/bsd/tmux/dist/input.c              |   137 ++-
 external/bsd/tmux/dist/key-bindings.c       |   233 ++--
 external/bsd/tmux/dist/log.c                |     3 +
 external/bsd/tmux/dist/mode-tree.c          |    31 +-
 external/bsd/tmux/dist/notify.c             |     4 +-
 external/bsd/tmux/dist/options.c            |    56 +-
 external/bsd/tmux/dist/proc.c               |     2 +-
 external/bsd/tmux/dist/regsub.c             |     6 +
 external/bsd/tmux/dist/resize.c             |     2 +-
 external/bsd/tmux/dist/screen-write.c       |    26 +-
 external/bsd/tmux/dist/screen.c             |    15 +-
 external/bsd/tmux/dist/server-client.c      |   377 +++----
 external/bsd/tmux/dist/server-fn.c          |    30 -
 external/bsd/tmux/dist/session.c            |    15 +-
 external/bsd/tmux/dist/spawn.c              |    68 +-
 external/bsd/tmux/dist/status.c             |     8 +-
 external/bsd/tmux/dist/style.c              |    39 +-
 external/bsd/tmux/dist/tmux.1               |   448 ++++++--
 external/bsd/tmux/dist/tmux.c               |    16 +-
 external/bsd/tmux/dist/tmux.h               |   217 +++-
 external/bsd/tmux/dist/tty-keys.c           |   126 +-
 external/bsd/tmux/dist/tty-term.c           |    33 +-
 external/bsd/tmux/dist/tty.c                |   131 +-
 external/bsd/tmux/dist/utf8.c               |    23 +-
 external/bsd/tmux/dist/window-buffer.c      |    95 +-
 external/bsd/tmux/dist/window-client.c      |   108 +-
 external/bsd/tmux/dist/window-copy.c        |  1348 ++++++++++++++++++++++----
 external/bsd/tmux/dist/window-tree.c        |   176 +-
 external/bsd/tmux/dist/window.c             |   139 ++-
 external/bsd/tmux/dist/xmalloc.h            |     1 +
 external/bsd/tmux/usr.bin/tmux/Makefile     |    15 +-
 46 files changed, 3553 insertions(+), 1602 deletions(-)

diffs (truncated from 9419 to 300 lines):

diff -r 693c5f41efae -r 69f0dc82fbe8 external/bsd/tmux/dist/client.c
--- a/external/bsd/tmux/dist/client.c   Sun Nov 01 14:52:00 2020 +0000
+++ b/external/bsd/tmux/dist/client.c   Sun Nov 01 15:16:04 2020 +0000
@@ -35,7 +35,6 @@
 static struct tmuxproc *client_proc;
 static struct tmuxpeer *client_peer;
 static int              client_flags;
-static struct event     client_stdin;
 static enum {
        CLIENT_EXIT_NONE,
        CLIENT_EXIT_DETACHED,
@@ -46,19 +45,19 @@
        CLIENT_EXIT_EXITED,
        CLIENT_EXIT_SERVER_EXITED,
 } client_exitreason = CLIENT_EXIT_NONE;
+static int              client_exitflag;
 static int              client_exitval;
 static enum msgtype     client_exittype;
 static const char      *client_exitsession;
 static const char      *client_execshell;
 static const char      *client_execcmd;
 static int              client_attached;
+static struct client_files client_files = RB_INITIALIZER(&client_files);
 
 static __dead void      client_exec(const char *,const char *);
 static int              client_get_lock(char *);
 static int              client_connect(struct event_base *, const char *, int);
 static void             client_send_identify(const char *, const char *);
-static void             client_stdin_callback(int, short, void *);
-static void             client_write(int, const char *, size_t);
 static void             client_signal(int);
 static void             client_dispatch(struct imsg *, void *);
 static void             client_dispatch_attached(struct imsg *);
@@ -211,13 +210,34 @@
        return ("unknown reason");
 }
 
+/* Exit if all streams flushed. */
+static void
+client_exit(void)
+{
+       struct client_file      *cf;
+       size_t                   left;
+       int                      waiting = 0;
+
+       RB_FOREACH (cf, client_files, &client_files) {
+               if (cf->event == NULL)
+                       continue;
+               left = EVBUFFER_LENGTH(cf->event->output);
+               if (left != 0) {
+                       waiting++;
+                       log_debug("file %u %zu bytes left", cf->stream, left);
+               }
+       }
+       if (waiting == 0)
+               proc_exit(client_proc);
+}
+
 /* Client main loop. */
 int
 client_main(struct event_base *base, int argc, char **argv, int flags)
 {
        struct cmd_parse_result *pr;
        struct cmd              *cmd;
-       struct msg_command_data *data;
+       struct msg_command      *data;
        int                      cmdflags, fd, i;
        const char              *ttynam, *cwd;
        pid_t                    ppid;
@@ -291,7 +311,9 @@
         *
         * "sendfd" is dropped later in client_dispatch_wait().
         */
-       if (pledge("stdio unix sendfd proc exec tty", NULL) != 0)
+       if (pledge(
+           "stdio rpath wpath cpath unix sendfd proc exec tty",
+           NULL) != 0)
                fatal("pledge failed");
 
        /* Free stuff that is not used in the client. */
@@ -302,10 +324,7 @@
        options_free(global_w_options);
        environ_free(global_environ);
 
-       /* Create stdin handler. */
-       setblocking(STDIN_FILENO, 0);
-       event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST,
-           client_stdin_callback, NULL);
+       /* Set up control mode. */
        if (client_flags & CLIENT_CONTROLCONTROL) {
                if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) {
                        fprintf(stderr, "tcgetattr failed: %s\n",
@@ -428,39 +447,255 @@
        proc_send(client_peer, MSG_IDENTIFY_DONE, -1, NULL, 0);
 }
 
-/* Callback for client stdin read events. */
+/* File write error callback. */
+static void
+client_write_error_callback(__unused struct bufferevent *bev,
+    __unused short what, void *arg)
+{
+       struct client_file      *cf = arg;
+
+       log_debug("write error file %d", cf->stream);
+
+       bufferevent_free(cf->event);
+       cf->event = NULL;
+
+       close(cf->fd);
+       cf->fd = -1;
+
+       if (client_exitflag)
+               client_exit();
+}
+
+/* File write callback. */
 static void
-client_stdin_callback(__unused int fd, __unused short events,
-    __unused void *arg)
+client_write_callback(__unused struct bufferevent *bev, void *arg)
 {
-       struct msg_stdin_data   data;
+       struct client_file      *cf = arg;
+
+       if (cf->closed && EVBUFFER_LENGTH(cf->event->output) == 0) {
+               bufferevent_free(cf->event);
+               close(cf->fd);
+               RB_REMOVE(client_files, &client_files, cf);
+               file_free(cf);
+       }
+
+       if (client_exitflag)
+               client_exit();
+}
+
+/* Open write file. */
+static void
+client_write_open(void *data, size_t datalen)
+{
+       struct msg_write_open   *msg = data;
+       const char              *path;
+       struct msg_write_ready   reply;
+       struct client_file       find, *cf;
+       const int                flags = O_NONBLOCK|O_WRONLY|O_CREAT;
+       int                      error = 0;
+
+       if (datalen < sizeof *msg)
+               fatalx("bad MSG_WRITE_OPEN size");
+       if (datalen == sizeof *msg)
+               path = "-";
+       else
+               path = (const char *)(msg + 1);
+       log_debug("open write file %d %s", msg->stream, path);
 
-       data.size = read(STDIN_FILENO, data.data, sizeof data.data);
-       if (data.size == -1 && (errno == EINTR || errno == EAGAIN))
-               return;
+       find.stream = msg->stream;
+       if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) {
+               cf = file_create(NULL, msg->stream, NULL, NULL);
+               RB_INSERT(client_files, &client_files, cf);
+       } else {
+               error = EBADF;
+               goto reply;
+       }
+       if (cf->closed) {
+               error = EBADF;
+               goto reply;
+       }
 
-       proc_send(client_peer, MSG_STDIN, -1, &data, sizeof data);
-       if (data.size <= 0)
-               event_del(&client_stdin);
+       cf->fd = -1;
+       if (msg->fd == -1)
+               cf->fd = open(path, msg->flags|flags, 0644);
+       else {
+               if (msg->fd != STDOUT_FILENO && msg->fd != STDERR_FILENO)
+                       errno = EBADF;
+               else {
+                       cf->fd = dup(msg->fd);
+                       if (~client_flags & CLIENT_CONTROL)
+                               close(msg->fd); /* can only be used once */
+               }
+       }
+       if (cf->fd == -1) {
+               error = errno;
+               goto reply;
+       }
+
+       cf->event = bufferevent_new(cf->fd, NULL, client_write_callback,
+           client_write_error_callback, cf);
+       bufferevent_enable(cf->event, EV_WRITE);
+       goto reply;
+
+reply:
+       reply.stream = msg->stream;
+       reply.error = error;
+       proc_send(client_peer, MSG_WRITE_READY, -1, &reply, sizeof reply);
+}
+
+/* Write to client file. */
+static void
+client_write_data(void *data, size_t datalen)
+{
+       struct msg_write_data   *msg = data;
+       struct client_file       find, *cf;
+       size_t                   size = datalen - sizeof *msg;
+
+       if (datalen < sizeof *msg)
+               fatalx("bad MSG_WRITE size");
+       find.stream = msg->stream;
+       if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL)
+               fatalx("unknown stream number");
+       log_debug("write %zu to file %d", size, cf->stream);
+
+       if (cf->event != NULL)
+               bufferevent_write(cf->event, msg + 1, size);
 }
 
-/* Force write to file descriptor. */
+/* Close client file. */
+static void
+client_write_close(void *data, size_t datalen)
+{
+       struct msg_write_close  *msg = data;
+       struct client_file       find, *cf;
+
+       if (datalen != sizeof *msg)
+               fatalx("bad MSG_WRITE_CLOSE size");
+       find.stream = msg->stream;
+       if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL)
+               fatalx("unknown stream number");
+       log_debug("close file %d", cf->stream);
+
+       if (cf->event == NULL || EVBUFFER_LENGTH(cf->event->output) == 0) {
+               if (cf->event != NULL)
+                       bufferevent_free(cf->event);
+               if (cf->fd != -1)
+                       close(cf->fd);
+               RB_REMOVE(client_files, &client_files, cf);
+               file_free(cf);
+       }
+}
+
+/* File read callback. */
 static void
-client_write(int fd, const char *data, size_t size)
+client_read_callback(__unused struct bufferevent *bev, void *arg)
 {
-       ssize_t used;
+       struct client_file      *cf = arg;
+       void                    *bdata;
+       size_t                   bsize;
+       struct msg_read_data    *msg;
+       size_t                   msglen;
+
+       msg = xmalloc(sizeof *msg);
+       for (;;) {
+               bdata = EVBUFFER_DATA(cf->event->input);
+               bsize = EVBUFFER_LENGTH(cf->event->input);
+
+               if (bsize == 0)
+                       break;
+               if (bsize > MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof *msg)
+                       bsize = MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof *msg;
+               log_debug("read %zu from file %d", bsize, cf->stream);
+
+               msglen = (sizeof *msg) + bsize;
+               msg = xrealloc(msg, msglen);
+               msg->stream = cf->stream;
+               memcpy(msg + 1, bdata, bsize);
+               proc_send(client_peer, MSG_READ, -1, msg, msglen);
+
+               evbuffer_drain(cf->event->input, bsize);
+       }
+       free(msg);
+}
+
+/* File read error callback. */
+static void
+client_read_error_callback(__unused struct bufferevent *bev,
+    __unused short what, void *arg)
+{
+       struct client_file      *cf = arg;
+       struct msg_read_done     msg;
+
+       log_debug("read error file %d", cf->stream);
 
-       log_debug("%s: %.*s", __func__, (int)size, data);
-       while (size != 0) {
-               used = write(fd, data, size);
-               if (used == -1) {
-                       if (errno == EINTR || errno == EAGAIN)
-                               continue;
-                       break;
+       msg.stream = cf->stream;
+       msg.error = 0;
+       proc_send(client_peer, MSG_READ_DONE, -1, &msg, sizeof msg);



Home | Main Index | Thread Index | Old Index