Mercurial > dropbear
comparison common-channel.c @ 467:0871a0b89f7c
Don't return until the shell has quit. This will ensure that an exit status
is always returned.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 21 Feb 2008 14:46:15 +0000 |
parents | 3e6c536bc023 |
children | cd02449b709c |
comparison
equal
deleted
inserted
replaced
466:f11544d96354 | 467:0871a0b89f7c |
---|---|
259 } | 259 } |
260 | 260 |
261 | 261 |
262 /* EOF/close handling */ | 262 /* EOF/close handling */ |
263 static void check_close(struct Channel *channel) { | 263 static void check_close(struct Channel *channel) { |
264 int close_allowed = 0; | |
264 | 265 |
265 TRACE(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d", | 266 TRACE(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d", |
266 channel->writefd, channel->readfd, | 267 channel->writefd, channel->readfd, |
267 channel->errfd, channel->sent_close, channel->recv_close)) | 268 channel->errfd, channel->sent_close, channel->recv_close)) |
268 TRACE(("writebuf size %d extrabuf size %d", | 269 TRACE(("writebuf size %d extrabuf size %d", |
272 if (!channel->flushing && channel->type->check_close | 273 if (!channel->flushing && channel->type->check_close |
273 && channel->type->check_close(channel)) | 274 && channel->type->check_close(channel)) |
274 { | 275 { |
275 channel->flushing = 1; | 276 channel->flushing = 1; |
276 } | 277 } |
277 | 278 |
278 if (channel->recv_close && !write_pending(channel)) { | 279 // if a type-specific check_close is defined we will only exit |
280 // once that has been triggered. this is only used for a server "session" | |
281 // channel, to ensure that the shell has exited (and the exit status | |
282 // retrieved) before we close things up. | |
283 if (!channel->type->check_close | |
284 || channel->type->check_close(channel)) { | |
285 close_allowed = 1; | |
286 } | |
287 | |
288 if (channel->recv_close && !write_pending(channel) && close_allowed) { | |
279 if (!channel->sent_close) { | 289 if (!channel->sent_close) { |
280 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")) | 290 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")) |
281 send_msg_channel_close(channel); | 291 send_msg_channel_close(channel); |
282 } | 292 } |
283 remove_channel(channel); | 293 remove_channel(channel); |
310 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)) { | 320 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)) { |
311 send_msg_channel_eof(channel); | 321 send_msg_channel_eof(channel); |
312 } | 322 } |
313 | 323 |
314 /* And if we can't receive any more data from them either, close up */ | 324 /* And if we can't receive any more data from them either, close up */ |
315 if (!channel->sent_close | 325 if (channel->readfd == FD_CLOSED |
316 && channel->readfd == FD_CLOSED | |
317 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED) | 326 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED) |
327 && !channel->sent_close | |
328 && close_allowed | |
318 && !write_pending(channel)) { | 329 && !write_pending(channel)) { |
319 TRACE(("sending close, readfd is closed")) | 330 TRACE(("sending close, readfd is closed")) |
320 send_msg_channel_close(channel); | 331 send_msg_channel_close(channel); |
321 } | 332 } |
322 } | 333 } |