=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/client.c,v retrieving revision 1.146 retrieving revision 1.147 diff -c -r1.146 -r1.147 *** src/usr.bin/tmux/client.c 2020/06/01 09:43:00 1.146 --- src/usr.bin/tmux/client.c 2020/06/10 07:27:10 1.147 *************** *** 1,4 **** ! /* $OpenBSD: client.c,v 1.146 2020/06/01 09:43:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: client.c,v 1.147 2020/06/10 07:27:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott *************** *** 45,55 **** --- 45,57 ---- CLIENT_EXIT_LOST_SERVER, CLIENT_EXIT_EXITED, CLIENT_EXIT_SERVER_EXITED, + CLIENT_EXIT_MESSAGE_PROVIDED } client_exitreason = CLIENT_EXIT_NONE; static int client_exitflag; static int client_exitval; static enum msgtype client_exittype; static const char *client_exitsession; + static char *client_exitmessage; static const char *client_execshell; static const char *client_execcmd; static int client_attached; *************** *** 207,212 **** --- 209,216 ---- return ("exited"); case CLIENT_EXIT_SERVER_EXITED: return ("server exited"); + case CLIENT_EXIT_MESSAGE_PROVIDED: + return (client_exitmessage); } return ("unknown reason"); } *************** *** 791,803 **** client_dispatch_wait(imsg); } /* Dispatch imsgs when in wait state (before MSG_READY). */ static void client_dispatch_wait(struct imsg *imsg) { char *data; ssize_t datalen; - int retval; static int pledge_applied; /* --- 795,832 ---- client_dispatch_wait(imsg); } + /* Process an exit message. */ + static void + client_dispatch_exit_message(char *data, size_t datalen) + { + int retval; + + if (datalen < sizeof retval && datalen != 0) + fatalx("bad MSG_EXIT size"); + + if (datalen >= sizeof retval) { + memcpy(&retval, data, sizeof retval); + client_exitval = retval; + } + + if (datalen > sizeof retval) { + datalen -= sizeof retval; + data += sizeof retval; + + client_exitmessage = xmalloc(datalen); + memcpy(client_exitmessage, data, datalen); + client_exitmessage[datalen - 1] = '\0'; + + client_exitreason = CLIENT_EXIT_MESSAGE_PROVIDED; + } + } + /* Dispatch imsgs when in wait state (before MSG_READY). */ static void client_dispatch_wait(struct imsg *imsg) { char *data; ssize_t datalen; static int pledge_applied; /* *************** *** 820,831 **** switch (imsg->hdr.type) { case MSG_EXIT: case MSG_SHUTDOWN: ! if (datalen != sizeof retval && datalen != 0) ! fatalx("bad MSG_EXIT size"); ! if (datalen == sizeof retval) { ! memcpy(&retval, data, sizeof retval); ! client_exitval = retval; ! } client_exitflag = 1; client_exit(); break; --- 849,855 ---- switch (imsg->hdr.type) { case MSG_EXIT: case MSG_SHUTDOWN: ! client_dispatch_exit_message(data, datalen); client_exitflag = 1; client_exit(); break; *************** *** 916,926 **** proc_send(client_peer, MSG_EXITING, -1, NULL, 0); break; case MSG_EXIT: ! if (datalen != 0 && datalen != sizeof (int)) ! fatalx("bad MSG_EXIT size"); ! proc_send(client_peer, MSG_EXITING, -1, NULL, 0); - client_exitreason = CLIENT_EXIT_EXITED; break; case MSG_EXITED: if (datalen != 0) --- 940,949 ---- proc_send(client_peer, MSG_EXITING, -1, NULL, 0); break; case MSG_EXIT: ! client_dispatch_exit_message(data, datalen); ! if (client_exitreason == CLIENT_EXIT_NONE) ! client_exitreason = CLIENT_EXIT_EXITED; proc_send(client_peer, MSG_EXITING, -1, NULL, 0); break; case MSG_EXITED: if (datalen != 0)