4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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 enum cmd_retval
cmd_attach_session_exec(struct cmd
*, struct cmd_q
*);
35 const struct cmd_entry cmd_attach_session_entry
= {
36 "attach-session", "attach",
38 "[-dr] [-c working-directory] " CMD_TARGET_SESSION_USAGE
,
39 CMD_CANTNEST
|CMD_STARTSERVER
,
41 cmd_attach_session_exec
45 cmd_attach_session(struct cmd_q
*cmdq
, const char *tflag
, int dflag
, int rflag
,
54 struct format_tree
*ft
;
57 if (RB_EMPTY(&sessions
)) {
58 cmdq_error(cmdq
, "no sessions");
59 return (CMD_RETURN_ERROR
);
62 if ((s
= cmd_find_session(cmdq
, tflag
, 1)) == NULL
)
63 return (CMD_RETURN_ERROR
);
65 if (cmdq
->client
== NULL
)
66 return (CMD_RETURN_NORMAL
);
68 if (cmdq
->client
->session
!= NULL
) {
71 * Can't use server_write_session in case attaching to
72 * the same session as currently attached to.
74 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
75 c
= ARRAY_ITEM(&clients
, i
);
76 if (c
== NULL
|| c
->session
!= s
)
78 if (c
== cmdq
->client
)
80 server_write_client(c
, MSG_DETACH
, NULL
, 0);
86 if ((c
= cmd_find_client(cmdq
, NULL
, 1)) != NULL
)
88 format_session(ft
, s
);
89 format_winlink(ft
, s
, s
->curw
);
90 format_window_pane(ft
, s
->curw
->window
->active
);
91 cp
= format_expand(ft
, cflag
);
94 fd
= open(cp
, O_RDONLY
|O_DIRECTORY
);
97 cmdq_error(cmdq
, "bad working directory: %s",
99 return (CMD_RETURN_ERROR
);
105 cmdq
->client
->session
= s
;
106 notify_attached_session_changed(cmdq
->client
);
107 session_update_activity(s
);
108 server_redraw_client(cmdq
->client
);
109 s
->curw
->flags
&= ~WINLINK_ALERTFLAGS
;
111 if (server_client_open(cmdq
->client
, s
, &cause
) != 0) {
112 cmdq_error(cmdq
, "open terminal failed: %s", cause
);
114 return (CMD_RETURN_ERROR
);
118 ft
= format_create();
119 if ((c
= cmd_find_client(cmdq
, NULL
, 1)) != NULL
)
120 format_client(ft
, c
);
121 format_session(ft
, s
);
122 format_winlink(ft
, s
, s
->curw
);
123 format_window_pane(ft
, s
->curw
->window
->active
);
124 cp
= format_expand(ft
, cflag
);
127 fd
= open(cp
, O_RDONLY
|O_DIRECTORY
);
130 cmdq_error(cmdq
, "bad working directory: %s",
132 return (CMD_RETURN_ERROR
);
139 cmdq
->client
->flags
|= CLIENT_READONLY
;
142 server_write_session(s
, MSG_DETACH
, NULL
, 0);
144 update
= options_get_string(&s
->options
, "update-environment");
145 environ_update(update
, &cmdq
->client
->environ
, &s
->environ
);
147 cmdq
->client
->session
= s
;
148 notify_attached_session_changed(cmdq
->client
);
149 session_update_activity(s
);
150 server_redraw_client(cmdq
->client
);
151 s
->curw
->flags
&= ~WINLINK_ALERTFLAGS
;
153 server_write_ready(cmdq
->client
);
154 cmdq
->client_exit
= 0;
157 server_update_socket();
159 return (CMD_RETURN_NORMAL
);
163 cmd_attach_session_exec(struct cmd
*self
, struct cmd_q
*cmdq
)
165 struct args
*args
= self
->args
;
167 return (cmd_attach_session(cmdq
, args_get(args
, 't'),
168 args_has(args
, 'd'), args_has(args
, 'r'), args_get(args
, 'c')));