4 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
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.
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.
19 #include <sys/types.h>
30 * Attach existing session to the current terminal.
33 static enum cmd_retval
cmd_attach_session_exec(struct cmd
*,
36 const struct cmd_entry cmd_attach_session_entry
= {
37 .name
= "attach-session",
40 .args
= { "c:dEf:rt:x", 0, 0, NULL
},
41 .usage
= "[-dErx] [-c working-directory] [-f flags] "
42 CMD_TARGET_SESSION_USAGE
,
46 .flags
= CMD_STARTSERVER
|CMD_READONLY
,
47 .exec
= cmd_attach_session_exec
51 cmd_attach_session(struct cmdq_item
*item
, const char *tflag
, int dflag
,
52 int xflag
, int rflag
, const char *cflag
, int Eflag
, const char *fflag
)
54 struct cmd_find_state
*current
= cmdq_get_current(item
);
55 struct cmd_find_state target
;
56 enum cmd_find_type type
;
58 struct client
*c
= cmdq_get_client(item
), *c_loop
;
61 struct window_pane
*wp
;
65 if (RB_EMPTY(&sessions
)) {
66 cmdq_error(item
, "no sessions");
67 return (CMD_RETURN_ERROR
);
71 return (CMD_RETURN_NORMAL
);
73 if (server_client_check_nested(c
)) {
74 cmdq_error(item
, "sessions should be nested with care, "
75 "unset $TMUX to force");
76 return (CMD_RETURN_ERROR
);
79 if (tflag
!= NULL
&& tflag
[strcspn(tflag
, ":.")] != '\0') {
83 type
= CMD_FIND_SESSION
;
84 flags
= CMD_FIND_PREFER_UNATTACHED
;
86 if (cmd_find_target(&target
, item
, tflag
, type
, flags
) != 0)
87 return (CMD_RETURN_ERROR
);
94 window_set_active_pane(wp
->window
, wp
, 1);
95 session_set_current(s
, wl
);
97 cmd_find_from_winlink_pane(current
, wl
, wp
, 0);
99 cmd_find_from_winlink(current
, wl
, 0);
103 cwd
= format_single(item
, cflag
, c
, s
, wl
, wp
);
104 free((void *)s
->cwd
);
108 server_client_set_flags(c
, fflag
);
110 c
->flags
|= (CLIENT_READONLY
|CLIENT_IGNORESIZE
);
112 c
->last_session
= c
->session
;
113 if (c
->session
!= NULL
) {
114 if (dflag
|| xflag
) {
116 msgtype
= MSG_DETACHKILL
;
118 msgtype
= MSG_DETACH
;
119 TAILQ_FOREACH(c_loop
, &clients
, entry
) {
120 if (c_loop
->session
!= s
|| c
== c_loop
)
122 server_client_detach(c_loop
, msgtype
);
126 environ_update(s
->options
, c
->environ
, s
->environ
);
128 server_client_set_session(c
, s
);
129 if (~cmdq_get_flags(item
) & CMDQ_STATE_REPEAT
)
130 server_client_set_key_table(c
, NULL
);
132 if (server_client_open(c
, &cause
) != 0) {
133 cmdq_error(item
, "open terminal failed: %s", cause
);
135 return (CMD_RETURN_ERROR
);
138 if (dflag
|| xflag
) {
140 msgtype
= MSG_DETACHKILL
;
142 msgtype
= MSG_DETACH
;
143 TAILQ_FOREACH(c_loop
, &clients
, entry
) {
144 if (c_loop
->session
!= s
|| c
== c_loop
)
146 server_client_detach(c_loop
, msgtype
);
150 environ_update(s
->options
, c
->environ
, s
->environ
);
152 server_client_set_session(c
, s
);
153 server_client_set_key_table(c
, NULL
);
155 if (~c
->flags
& CLIENT_CONTROL
)
156 proc_send(c
->peer
, MSG_READY
, -1, NULL
, 0);
157 notify_client("client-attached", c
);
158 c
->flags
|= CLIENT_ATTACHED
;
164 return (CMD_RETURN_NORMAL
);
167 static enum cmd_retval
168 cmd_attach_session_exec(struct cmd
*self
, struct cmdq_item
*item
)
170 struct args
*args
= cmd_get_args(self
);
172 return (cmd_attach_session(item
, args_get(args
, 't'),
173 args_has(args
, 'd'), args_has(args
, 'x'), args_has(args
, 'r'),
174 args_get(args
, 'c'), args_has(args
, 'E'), args_get(args
, 'f')));