Annotation of embedaddon/tmux/cmd-attach-session.c, revision 1.1
1.1 ! misho 1: /* $OpenBSD$ */
! 2:
! 3: /*
! 4: * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
! 5: *
! 6: * Permission to use, copy, modify, and distribute this software for any
! 7: * purpose with or without fee is hereby granted, provided that the above
! 8: * copyright notice and this permission notice appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
! 15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
! 16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: */
! 18:
! 19: #include <sys/types.h>
! 20:
! 21: #include <errno.h>
! 22: #include <fcntl.h>
! 23: #include <stdlib.h>
! 24: #include <string.h>
! 25: #include <unistd.h>
! 26:
! 27: #include "tmux.h"
! 28:
! 29: /*
! 30: * Attach existing session to the current terminal.
! 31: */
! 32:
! 33: static enum cmd_retval cmd_attach_session_exec(struct cmd *,
! 34: struct cmdq_item *);
! 35:
! 36: const struct cmd_entry cmd_attach_session_entry = {
! 37: .name = "attach-session",
! 38: .alias = "attach",
! 39:
! 40: .args = { "c:dErt:", 0, 0 },
! 41: .usage = "[-dEr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
! 42:
! 43: .tflag = CMD_SESSION_WITHPANE,
! 44:
! 45: .flags = CMD_STARTSERVER,
! 46: .exec = cmd_attach_session_exec
! 47: };
! 48:
! 49: enum cmd_retval
! 50: cmd_attach_session(struct cmdq_item *item, int dflag, int rflag,
! 51: const char *cflag, int Eflag)
! 52: {
! 53: struct session *s = item->state.tflag.s;
! 54: struct client *c = item->client, *c_loop;
! 55: struct winlink *wl = item->state.tflag.wl;
! 56: struct window_pane *wp = item->state.tflag.wp;
! 57: char *cause;
! 58:
! 59: if (RB_EMPTY(&sessions)) {
! 60: cmdq_error(item, "no sessions");
! 61: return (CMD_RETURN_ERROR);
! 62: }
! 63:
! 64: if (c == NULL)
! 65: return (CMD_RETURN_NORMAL);
! 66: if (server_client_check_nested(c)) {
! 67: cmdq_error(item, "sessions should be nested with care, "
! 68: "unset $TMUX to force");
! 69: return (CMD_RETURN_ERROR);
! 70: }
! 71:
! 72: if (wl != NULL) {
! 73: if (wp != NULL)
! 74: window_set_active_pane(wp->window, wp);
! 75: session_set_current(s, wl);
! 76: }
! 77:
! 78: if (cflag != NULL) {
! 79: free((void *)s->cwd);
! 80: s->cwd = format_single(item, cflag, c, s, wl, wp);
! 81: }
! 82:
! 83: if (c->session != NULL) {
! 84: if (dflag) {
! 85: TAILQ_FOREACH(c_loop, &clients, entry) {
! 86: if (c_loop->session != s || c == c_loop)
! 87: continue;
! 88: server_client_detach(c_loop, MSG_DETACH);
! 89: }
! 90: }
! 91: if (!Eflag)
! 92: environ_update(s->options, c->environ, s->environ);
! 93:
! 94: c->session = s;
! 95: if (!item->repeat)
! 96: server_client_set_key_table(c, NULL);
! 97: status_timer_start(c);
! 98: notify_client("client-session-changed", c);
! 99: session_update_activity(s, NULL);
! 100: gettimeofday(&s->last_attached_time, NULL);
! 101: server_redraw_client(c);
! 102: s->curw->flags &= ~WINLINK_ALERTFLAGS;
! 103: } else {
! 104: if (server_client_open(c, &cause) != 0) {
! 105: cmdq_error(item, "open terminal failed: %s", cause);
! 106: free(cause);
! 107: return (CMD_RETURN_ERROR);
! 108: }
! 109: if (rflag)
! 110: c->flags |= CLIENT_READONLY;
! 111:
! 112: if (dflag) {
! 113: TAILQ_FOREACH(c_loop, &clients, entry) {
! 114: if (c_loop->session != s || c == c_loop)
! 115: continue;
! 116: server_client_detach(c_loop, MSG_DETACH);
! 117: }
! 118: }
! 119: if (!Eflag)
! 120: environ_update(s->options, c->environ, s->environ);
! 121:
! 122: c->session = s;
! 123: server_client_set_key_table(c, NULL);
! 124: status_timer_start(c);
! 125: notify_client("client-session-changed", c);
! 126: session_update_activity(s, NULL);
! 127: gettimeofday(&s->last_attached_time, NULL);
! 128: server_redraw_client(c);
! 129: s->curw->flags &= ~WINLINK_ALERTFLAGS;
! 130:
! 131: if (~c->flags & CLIENT_CONTROL)
! 132: proc_send(c->peer, MSG_READY, -1, NULL, 0);
! 133: notify_client("client-attached", c);
! 134: c->flags |= CLIENT_ATTACHED;
! 135: }
! 136: recalculate_sizes();
! 137: alerts_check_session(s);
! 138: server_update_socket();
! 139:
! 140: return (CMD_RETURN_NORMAL);
! 141: }
! 142:
! 143: static enum cmd_retval
! 144: cmd_attach_session_exec(struct cmd *self, struct cmdq_item *item)
! 145: {
! 146: struct args *args = self->args;
! 147:
! 148: return (cmd_attach_session(item, args_has(args, 'd'),
! 149: args_has(args, 'r'), args_get(args, 'c'), args_has(args, 'E')));
! 150: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>