comparison common-channel.c @ 1625:79eef94ccea9

Split ChanType closehandler() and cleanup() so that dbclient doesn't lose exit status messages
author Matt Johnston <matt@ucc.asn.au>
date Wed, 14 Nov 2018 22:57:56 +0800
parents 5916af64acd4
children c584b5602bd8
comparison
equal deleted inserted replaced
1624:1f3fb83b0524 1625:79eef94ccea9
142 newchan = (struct Channel*)m_malloc(sizeof(struct Channel)); 142 newchan = (struct Channel*)m_malloc(sizeof(struct Channel));
143 newchan->type = type; 143 newchan->type = type;
144 newchan->index = i; 144 newchan->index = i;
145 newchan->sent_close = newchan->recv_close = 0; 145 newchan->sent_close = newchan->recv_close = 0;
146 newchan->sent_eof = newchan->recv_eof = 0; 146 newchan->sent_eof = newchan->recv_eof = 0;
147 newchan->close_handler_done = 0;
148 147
149 newchan->remotechan = remotechan; 148 newchan->remotechan = remotechan;
150 newchan->transwindow = transwindow; 149 newchan->transwindow = transwindow;
151 newchan->transmaxpacket = transmaxpacket; 150 newchan->transmaxpacket = transmaxpacket;
152 151
284 TRACE2(("writebuf size %d extrabuf size %d", 283 TRACE2(("writebuf size %d extrabuf size %d",
285 channel->writebuf ? cbuf_getused(channel->writebuf) : 0, 284 channel->writebuf ? cbuf_getused(channel->writebuf) : 0,
286 channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0)) 285 channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
287 286
288 if (!channel->flushing 287 if (!channel->flushing
289 && !channel->close_handler_done 288 && !channel->sent_close
290 && channel->type->check_close 289 && channel->type->check_close
291 && channel->type->check_close(channel)) 290 && channel->type->check_close(channel))
292 { 291 {
293 channel->flushing = 1; 292 channel->flushing = 1;
294 } 293 }
296 /* if a type-specific check_close is defined we will only exit 295 /* if a type-specific check_close is defined we will only exit
297 once that has been triggered. this is only used for a server "session" 296 once that has been triggered. this is only used for a server "session"
298 channel, to ensure that the shell has exited (and the exit status 297 channel, to ensure that the shell has exited (and the exit status
299 retrieved) before we close things up. */ 298 retrieved) before we close things up. */
300 if (!channel->type->check_close 299 if (!channel->type->check_close
301 || channel->close_handler_done 300 || channel->sent_close
302 || channel->type->check_close(channel)) { 301 || channel->type->check_close(channel)) {
303 close_allowed = 1; 302 close_allowed = 1;
304 } 303 }
305 304
306 if (channel->recv_close && !write_pending(channel) && close_allowed) { 305 if (channel->recv_close && !write_pending(channel) && close_allowed) {
383 382
384 /* Send the close message and set the channel as closed */ 383 /* Send the close message and set the channel as closed */
385 static void send_msg_channel_close(struct Channel *channel) { 384 static void send_msg_channel_close(struct Channel *channel) {
386 385
387 TRACE(("enter send_msg_channel_close %p", (void*)channel)) 386 TRACE(("enter send_msg_channel_close %p", (void*)channel))
388 if (channel->type->closehandler 387 if (channel->type->closehandler) {
389 && !channel->close_handler_done) {
390 channel->type->closehandler(channel); 388 channel->type->closehandler(channel);
391 channel->close_handler_done = 1;
392 } 389 }
393 390
394 CHECKCLEARTOWRITE(); 391 CHECKCLEARTOWRITE();
395 392
396 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE); 393 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE);
659 m_close(channel->readfd); 656 m_close(channel->readfd);
660 TRACE(("CLOSE errfd %d", channel->errfd)) 657 TRACE(("CLOSE errfd %d", channel->errfd))
661 m_close(channel->errfd); 658 m_close(channel->errfd);
662 } 659 }
663 660
664 if (!channel->close_handler_done 661 if (channel->type->cleanup) {
665 && channel->type->closehandler) { 662 channel->type->cleanup(channel);
666 channel->type->closehandler(channel);
667 channel->close_handler_done = 1;
668 } 663 }
669 664
670 if (channel->conn_pending) { 665 if (channel->conn_pending) {
671 cancel_connect(channel->conn_pending); 666 cancel_connect(channel->conn_pending);
672 } 667 }
688 683
689 channel = getchannel(); 684 channel = getchannel();
690 685
691 TRACE(("enter recv_msg_channel_request %p", (void*)channel)) 686 TRACE(("enter recv_msg_channel_request %p", (void*)channel))
692 687
693 if (channel->sent_close) { 688 if (channel->type->reqhandler) {
694 TRACE(("leave recv_msg_channel_request: already closed channel"))
695 return;
696 }
697
698 if (channel->type->reqhandler
699 && !channel->close_handler_done) {
700 channel->type->reqhandler(channel); 689 channel->type->reqhandler(channel);
701 } else { 690 } else {
702 int wantreply; 691 int wantreply;
703 buf_eatstring(ses.payload); 692 buf_eatstring(ses.payload);
704 wantreply = buf_getbool(ses.payload); 693 wantreply = buf_getbool(ses.payload);
1009 998
1010 /* Send a failure message */ 999 /* Send a failure message */
1011 void send_msg_channel_failure(const struct Channel *channel) { 1000 void send_msg_channel_failure(const struct Channel *channel) {
1012 1001
1013 TRACE(("enter send_msg_channel_failure")) 1002 TRACE(("enter send_msg_channel_failure"))
1003
1004 if (channel->sent_close) {
1005 TRACE(("Skipping sending msg_channel_failure for closed channel"))
1006 return;
1007 }
1014 CHECKCLEARTOWRITE(); 1008 CHECKCLEARTOWRITE();
1015 1009
1016 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE); 1010 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE);
1017 buf_putint(ses.writepayload, channel->remotechan); 1011 buf_putint(ses.writepayload, channel->remotechan);
1018 1012
1022 1016
1023 /* Send a success message */ 1017 /* Send a success message */
1024 void send_msg_channel_success(const struct Channel *channel) { 1018 void send_msg_channel_success(const struct Channel *channel) {
1025 1019
1026 TRACE(("enter send_msg_channel_success")) 1020 TRACE(("enter send_msg_channel_success"))
1021 if (channel->sent_close) {
1022 TRACE(("Skipping sending msg_channel_success for closed channel"))
1023 return;
1024 }
1027 CHECKCLEARTOWRITE(); 1025 CHECKCLEARTOWRITE();
1028 1026
1029 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS); 1027 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);
1030 buf_putint(ses.writepayload, channel->remotechan); 1028 buf_putint(ses.writepayload, channel->remotechan);
1031 1029