Mercurial > dropbear
comparison common-channel.c @ 414:c53a26c430e5 channel-fix
disapproval of revision '1dfbc5ef92391d01b576c8506061927869a89887'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 06 Feb 2007 15:59:54 +0000 |
parents | 4f2dbd1c3685 |
children | 8b9aba1d5fa4 |
comparison
equal
deleted
inserted
replaced
376:4f2dbd1c3685 | 414:c53a26c430e5 |
---|---|
184 | 184 |
185 struct Channel* getchannel() { | 185 struct Channel* getchannel() { |
186 return getchannel_msg(NULL); | 186 return getchannel_msg(NULL); |
187 } | 187 } |
188 | 188 |
189 /* In order to tell if a writefd is closed, we put it in the readfd FD_SET. | |
190 We then just try reading a single byte from it. It'll give EAGAIN or something | |
191 if the socket is still alive (but the FD probably shouldn't be set anyway?)*/ | |
192 static void check_closed_writefd(struct Channel* channel, int fd) { | |
193 char c; | |
194 int ret; | |
195 TRACE(("enter check_closed_writefd fd %d", fd)) | |
196 if (fd < 0) { | |
197 TRACE(("leave check_closed_writefd.")) | |
198 return; | |
199 } | |
200 | |
201 /* Read something. doing read(fd,x,0) seems to become a NOP on some platforms */ | |
202 ret = read(fd, &c, 1); | |
203 TRACE(("ret %d errno %d", ret, errno)) | |
204 if (ret > 0 || (ret < 0 && (errno == EINTR || errno == EAGAIN))) { | |
205 TRACE(("leave check_closed_writefd")) | |
206 return; | |
207 } | |
208 close_chan_fd(channel, fd, SHUT_WR); | |
209 TRACE(("leave check_closed_writefd after closing %d", fd)) | |
210 } | |
211 | |
212 /* Iterate through the channels, performing IO if available */ | 189 /* Iterate through the channels, performing IO if available */ |
213 void channelio(fd_set *readfds, fd_set *writefds) { | 190 void channelio(fd_set *readfds, fd_set *writefds) { |
214 | 191 |
215 struct Channel *channel; | 192 struct Channel *channel; |
216 unsigned int i; | 193 unsigned int i; |
249 /* stderr for client mode */ | 226 /* stderr for client mode */ |
250 if (ERRFD_IS_WRITE(channel) | 227 if (ERRFD_IS_WRITE(channel) |
251 && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) { | 228 && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) { |
252 writechannel(channel, channel->errfd, channel->extrabuf); | 229 writechannel(channel, channel->errfd, channel->extrabuf); |
253 } | 230 } |
254 | |
255 /* Check writefds for close, even if we don't have anything | |
256 to write into them. */ | |
257 if (channel->writefd >= 0) { | |
258 check_closed_writefd(channel, channel->writefd); | |
259 } | |
260 if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0) { | |
261 check_closed_writefd(channel, channel->errfd); | |
262 } | |
263 | |
264 | 231 |
265 /* handle any channel closing etc */ | 232 /* handle any channel closing etc */ |
266 check_close(channel); | 233 check_close(channel); |
267 | 234 |
268 } | 235 } |
470 if (ERRFD_IS_WRITE(channel) != NULL && channel->errfd >= 0 | 437 if (ERRFD_IS_WRITE(channel) != NULL && channel->errfd >= 0 |
471 && cbuf_getused(channel->extrabuf) > 0 ) { | 438 && cbuf_getused(channel->extrabuf) > 0 ) { |
472 FD_SET(channel->errfd, writefds); | 439 FD_SET(channel->errfd, writefds); |
473 } | 440 } |
474 | 441 |
475 /* We also set the writefds for reading, so that we will be notified of close */ | |
476 if (channel->writefd >= 0) { | |
477 FD_SET(channel->writefd, readfds); | |
478 } | |
479 if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0) { | |
480 FD_SET(channel->errfd, readfds); | |
481 } | |
482 | |
483 | |
484 | |
485 } /* foreach channel */ | 442 } /* foreach channel */ |
486 | 443 |
487 #ifdef USING_LISTENERS | 444 #ifdef USING_LISTENERS |
488 set_listener_fds(readfds); | 445 set_listener_fds(readfds); |
489 #endif | 446 #endif |