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