summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c110
1 files changed, 62 insertions, 48 deletions
diff --git a/channels.c b/channels.c
index 1f9b515c3..bd8c337ee 100644
--- a/channels.c
+++ b/channels.c
@@ -17,7 +17,7 @@
17 */ 17 */
18 18
19#include "includes.h" 19#include "includes.h"
20RCSID("$Id: channels.c,v 1.27 2000/04/30 00:00:53 damien Exp $"); 20RCSID("$Id: channels.c,v 1.28 2000/05/01 23:23:45 damien Exp $");
21 21
22#include "ssh.h" 22#include "ssh.h"
23#include "packet.h" 23#include "packet.h"
@@ -148,17 +148,13 @@ channel_lookup(int id)
148} 148}
149 149
150/* 150/*
151 * Allocate a new channel object and set its type and socket. This will cause 151 * register filedescriptors for a channel, used when allocating a channel or
152 * remote_name to be freed. 152 * when the channel consumer/producer is ready, e.g. shell exec'd
153 */ 153 */
154 154
155int 155void
156channel_new(char *ctype, int type, int rfd, int wfd, int efd, 156channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage)
157 int window, int maxpack, int extended_usage, char *remote_name)
158{ 157{
159 int i, found;
160 Channel *c;
161
162 /* Update the maximum file descriptor value. */ 158 /* Update the maximum file descriptor value. */
163 if (rfd > channel_max_fd_value) 159 if (rfd > channel_max_fd_value)
164 channel_max_fd_value = rfd; 160 channel_max_fd_value = rfd;
@@ -167,6 +163,24 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
167 if (efd > channel_max_fd_value) 163 if (efd > channel_max_fd_value)
168 channel_max_fd_value = efd; 164 channel_max_fd_value = efd;
169 /* XXX set close-on-exec -markus */ 165 /* XXX set close-on-exec -markus */
166 c->rfd = rfd;
167 c->wfd = wfd;
168 c->sock = (rfd == wfd) ? rfd : -1;
169 c->efd = efd;
170 c->extended_usage = extusage;
171}
172
173/*
174 * Allocate a new channel object and set its type and socket. This will cause
175 * remote_name to be freed.
176 */
177
178int
179channel_new(char *ctype, int type, int rfd, int wfd, int efd,
180 int window, int maxpack, int extusage, char *remote_name)
181{
182 int i, found;
183 Channel *c;
170 184
171 /* Do initial allocation if this is the first call. */ 185 /* Do initial allocation if this is the first call. */
172 if (channels_alloc == 0) { 186 if (channels_alloc == 0) {
@@ -203,14 +217,10 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
203 buffer_init(&c->output); 217 buffer_init(&c->output);
204 buffer_init(&c->extended); 218 buffer_init(&c->extended);
205 chan_init_iostates(c); 219 chan_init_iostates(c);
220 channel_register_fds(c, rfd, wfd, efd, extusage);
206 c->self = found; 221 c->self = found;
207 c->type = type; 222 c->type = type;
208 c->ctype = ctype; 223 c->ctype = ctype;
209 c->rfd = rfd;
210 c->wfd = wfd;
211 c->sock = (rfd == wfd) ? rfd : -1;
212 c->efd = efd;
213 c->extended_usage = extended_usage;
214 c->local_window = window; 224 c->local_window = window;
215 c->local_window_max = window; 225 c->local_window_max = window;
216 c->local_consumed = 0; 226 c->local_consumed = 0;
@@ -226,13 +236,38 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
226 debug("channel %d: new [%s]", found, remote_name); 236 debug("channel %d: new [%s]", found, remote_name);
227 return found; 237 return found;
228} 238}
239/* old interface XXX */
229int 240int
230channel_allocate(int type, int sock, char *remote_name) 241channel_allocate(int type, int sock, char *remote_name)
231{ 242{
232 return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name); 243 return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name);
233} 244}
234 245
235/* Free the channel and close its socket. */ 246
247/* Close all channel fd/socket. */
248
249void
250channel_close_fds(Channel *c)
251{
252 if (c->sock != -1) {
253 close(c->sock);
254 c->sock = -1;
255 }
256 if (c->rfd != -1) {
257 close(c->rfd);
258 c->rfd = -1;
259 }
260 if (c->wfd != -1) {
261 close(c->wfd);
262 c->wfd = -1;
263 }
264 if (c->efd != -1) {
265 close(c->efd);
266 c->efd = -1;
267 }
268}
269
270/* Free the channel and close its fd/socket. */
236 271
237void 272void
238channel_free(int id) 273channel_free(int id)
@@ -245,25 +280,9 @@ channel_free(int id)
245 debug("channel_free: channel %d: dettaching channel user", id); 280 debug("channel_free: channel %d: dettaching channel user", id);
246 c->dettach_user(c->self, NULL); 281 c->dettach_user(c->self, NULL);
247 } 282 }
248 if (c->sock != -1) { 283 if (c->sock != -1)
249 shutdown(c->sock, SHUT_RDWR); 284 shutdown(c->sock, SHUT_RDWR);
250 close(c->sock); 285 channel_close_fds(c);
251 c->sock = -1;
252 }
253 if (compat20) {
254 if (c->rfd != -1) {
255 close(c->rfd);
256 c->rfd = -1;
257 }
258 if (c->wfd != -1) {
259 close(c->wfd);
260 c->wfd = -1;
261 }
262 if (c->efd != -1) {
263 close(c->efd);
264 c->efd = -1;
265 }
266 }
267 buffer_free(&c->input); 286 buffer_free(&c->input);
268 buffer_free(&c->output); 287 buffer_free(&c->output);
269 buffer_free(&c->extended); 288 buffer_free(&c->extended);
@@ -614,6 +633,8 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
614 if (c->rfd != -1 && 633 if (c->rfd != -1 &&
615 FD_ISSET(c->rfd, readset)) { 634 FD_ISSET(c->rfd, readset)) {
616 len = read(c->rfd, buf, sizeof(buf)); 635 len = read(c->rfd, buf, sizeof(buf));
636 if (len < 0 && (errno == EINTR || errno == EAGAIN))
637 return 1;
617 if (len <= 0) { 638 if (len <= 0) {
618 debug("channel %d: read<=0 rfd %d len %d", 639 debug("channel %d: read<=0 rfd %d len %d",
619 c->self, c->rfd, len); 640 c->self, c->rfd, len);
@@ -640,7 +661,9 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
640 FD_ISSET(c->wfd, writeset) && 661 FD_ISSET(c->wfd, writeset) &&
641 buffer_len(&c->output) > 0) { 662 buffer_len(&c->output) > 0) {
642 len = write(c->wfd, buffer_ptr(&c->output), 663 len = write(c->wfd, buffer_ptr(&c->output),
643 buffer_len(&c->output)); 664 buffer_len(&c->output));
665 if (len < 0 && (errno == EINTR || errno == EAGAIN))
666 return 1;
644 if (len <= 0) { 667 if (len <= 0) {
645 if (compat13) { 668 if (compat13) {
646 buffer_consume(&c->output, buffer_len(&c->output)); 669 buffer_consume(&c->output, buffer_len(&c->output));
@@ -1267,7 +1290,7 @@ channel_stop_listening()
1267} 1290}
1268 1291
1269/* 1292/*
1270 * Closes the sockets of all channels. This is used to close extra file 1293 * Closes the sockets/fds of all channels. This is used to close extra file
1271 * descriptors after a fork. 1294 * descriptors after a fork.
1272 */ 1295 */
1273 1296
@@ -1275,10 +1298,9 @@ void
1275channel_close_all() 1298channel_close_all()
1276{ 1299{
1277 int i; 1300 int i;
1278 for (i = 0; i < channels_alloc; i++) { 1301 for (i = 0; i < channels_alloc; i++)
1279 if (channels[i].type != SSH_CHANNEL_FREE) 1302 if (channels[i].type != SSH_CHANNEL_FREE)
1280 close(channels[i].sock); 1303 channel_close_fds(&channels[i]);
1281 }
1282} 1304}
1283 1305
1284/* Returns the maximum file descriptor number used by the channels. */ 1306/* Returns the maximum file descriptor number used by the channels. */
@@ -2269,17 +2291,9 @@ channel_set_fds(int id, int rfd, int wfd, int efd, int extusage)
2269 Channel *c = channel_lookup(id); 2291 Channel *c = channel_lookup(id);
2270 if (c == NULL || c->type != SSH_CHANNEL_LARVAL) 2292 if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
2271 fatal("channel_activate for non-larval channel %d.", id); 2293 fatal("channel_activate for non-larval channel %d.", id);
2272 if (rfd > channel_max_fd_value) 2294
2273 channel_max_fd_value = rfd; 2295 channel_register_fds(c, rfd, wfd, efd, extusage);
2274 if (wfd > channel_max_fd_value)
2275 channel_max_fd_value = wfd;
2276 if (efd > channel_max_fd_value)
2277 channel_max_fd_value = efd;
2278 c->type = SSH_CHANNEL_OPEN; 2296 c->type = SSH_CHANNEL_OPEN;
2279 c->rfd = rfd;
2280 c->wfd = wfd;
2281 c->efd = efd;
2282 c->extended_usage = extusage;
2283 /* XXX window size? */ 2297 /* XXX window size? */
2284 c->local_window = c->local_window_max = c->local_maxpacket/2; 2298 c->local_window = c->local_window_max = c->local_maxpacket/2;
2285 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); 2299 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);