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
,
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
);
72 if (server_client_check_nested(c
)) {
73 cmdq_error(item
, "sessions should be nested with care, "
74 "unset $TMUX to force");
75 return (CMD_RETURN_ERROR
);
78 if (tflag
!= NULL
&& tflag
[strcspn(tflag
, ":.")] != '\0') {
82 type
= CMD_FIND_SESSION
;
83 flags
= CMD_FIND_PREFER_UNATTACHED
;
85 if (cmd_find_target(&target
, item
, tflag
, type
, flags
) != 0)
86 return (CMD_RETURN_ERROR
);
93 window_set_active_pane(wp
->window
, wp
, 1);
94 session_set_current(s
, wl
);
96 cmd_find_from_winlink_pane(current
, wl
, wp
, 0);
98 cmd_find_from_winlink(current
, wl
, 0);
102 cwd
= format_single(item
, cflag
, c
, s
, wl
, wp
);
103 free((void *)s
->cwd
);
107 server_client_set_flags(c
, fflag
);
109 c
->flags
|= (CLIENT_READONLY
|CLIENT_IGNORESIZE
);
111 c
->last_session
= c
->session
;
112 if (c
->session
!= NULL
) {
113 if (dflag
|| xflag
) {
115 msgtype
= MSG_DETACHKILL
;
117 msgtype
= MSG_DETACH
;
118 TAILQ_FOREACH(c_loop
, &clients
, entry
) {
119 if (c_loop
->session
!= s
|| c
== c_loop
)
121 server_client_detach(c_loop
, msgtype
);
125 environ_update(s
->options
, c
->environ
, s
->environ
);
127 server_client_set_session(c
, s
);
128 if (~cmdq_get_flags(item
) & CMDQ_STATE_REPEAT
)
129 server_client_set_key_table(c
, NULL
);
131 if (server_client_open(c
, &cause
) != 0) {
132 cmdq_error(item
, "open terminal failed: %s", cause
);
134 return (CMD_RETURN_ERROR
);
137 if (dflag
|| xflag
) {
139 msgtype
= MSG_DETACHKILL
;
141 msgtype
= MSG_DETACH
;
142 TAILQ_FOREACH(c_loop
, &clients
, entry
) {
143 if (c_loop
->session
!= s
|| c
== c_loop
)
145 server_client_detach(c_loop
, msgtype
);
149 environ_update(s
->options
, c
->environ
, s
->environ
);
151 server_client_set_session(c
, s
);
152 server_client_set_key_table(c
, NULL
);
154 if (~c
->flags
& CLIENT_CONTROL
)
155 proc_send(c
->peer
, MSG_READY
, -1, NULL
, 0);
156 notify_client("client-attached", c
);
157 c
->flags
|= CLIENT_ATTACHED
;
160 return (CMD_RETURN_NORMAL
);
163 static enum cmd_retval
164 cmd_attach_session_exec(struct cmd
*self
, struct cmdq_item
*item
)
166 struct args
*args
= cmd_get_args(self
);
168 return (cmd_attach_session(item
, args_get(args
, 't'),
169 args_has(args
, 'd'), args_has(args
, 'x'), args_has(args
, 'r'),
170 args_get(args
, 'c'), args_has(args
, 'E'), args_get(args
, 'f')));