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 }