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
,
82 strlen(c
->session
->name
) + 1);
88 if ((c
= cmd_find_client(cmdq
, NULL
, 1)) != NULL
)
90 format_session(ft
, s
);
91 format_winlink(ft
, s
, s
->curw
);
92 format_window_pane(ft
, s
->curw
->window
->active
);
93 cp
= format_expand(ft
, cflag
);
96 fd
= open(cp
, O_RDONLY
|O_DIRECTORY
);
99 cmdq_error(cmdq
, "bad working directory: %s",
101 return (CMD_RETURN_ERROR
);
107 cmdq
->client
->session
= s
;
108 notify_attached_session_changed(cmdq
->client
);
109 session_update_activity(s
);
110 server_redraw_client(cmdq
->client
);
111 s
->curw
->flags
&= ~WINLINK_ALERTFLAGS
;
113 if (server_client_open(cmdq
->client
, s
, &cause
) != 0) {
114 cmdq_error(cmdq
, "open terminal failed: %s", cause
);
116 return (CMD_RETURN_ERROR
);
120 ft
= format_create();
121 if ((c
= cmd_find_client(cmdq
, NULL
, 1)) != NULL
)
122 format_client(ft
, c
);
123 format_session(ft
, s
);
124 format_winlink(ft
, s
, s
->curw
);
125 format_window_pane(ft
, s
->curw
->window
->active
);
126 cp
= format_expand(ft
, cflag
);
129 fd
= open(cp
, O_RDONLY
|O_DIRECTORY
);
132 cmdq_error(cmdq
, "bad working directory: %s",
134 return (CMD_RETURN_ERROR
);
141 cmdq
->client
->flags
|= CLIENT_READONLY
;
144 server_write_session(s
, MSG_DETACH
, s
->name
,
145 strlen(s
->name
) + 1);
148 update
= options_get_string(&s
->options
, "update-environment");
149 environ_update(update
, &cmdq
->client
->environ
, &s
->environ
);
151 cmdq
->client
->session
= s
;
152 notify_attached_session_changed(cmdq
->client
);
153 session_update_activity(s
);
154 server_redraw_client(cmdq
->client
);
155 s
->curw
->flags
&= ~WINLINK_ALERTFLAGS
;
157 server_write_ready(cmdq
->client
);
158 cmdq
->client_exit
= 0;
161 server_update_socket();
163 return (CMD_RETURN_NORMAL
);
167 cmd_attach_session_exec(struct cmd
*self
, struct cmd_q
*cmdq
)
169 struct args
*args
= self
->args
;
171 return (cmd_attach_session(cmdq
, args_get(args
, 't'),
172 args_has(args
, 'd'), args_has(args
, 'r'), args_get(args
, 'c')));