mirror of
				https://github.com/clearml/dropbear
				synced 2025-06-26 18:17:32 +00:00 
			
		
		
		
	Add some code for testing whether a writefd is closed (by read()ing from it)
--HG-- branch : channel-fix extra : convert_revision : 1dfbc5ef92391d01b576c8506061927869a89887
This commit is contained in:
		
							parent
							
								
									e1d3a8a6e9
								
							
						
					
					
						commit
						4e09d27c6f
					
				| @ -186,6 +186,29 @@ struct Channel* getchannel() { | |||||||
| 	return getchannel_msg(NULL); | 	return getchannel_msg(NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* In order to tell if a writefd is closed, we put it in the readfd FD_SET.
 | ||||||
|  |    We then just try reading a single byte from it. It'll give EAGAIN or something | ||||||
|  |    if the socket is still alive (but the FD probably shouldn't be set anyway?)*/ | ||||||
|  | static void check_closed_writefd(struct Channel* channel, int fd) { | ||||||
|  | 	char c; | ||||||
|  | 	int ret; | ||||||
|  | 	TRACE(("enter check_closed_writefd fd %d", fd)) | ||||||
|  | 	if (fd < 0)	{ | ||||||
|  | 		TRACE(("leave check_closed_writefd.")) | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Read something. doing read(fd,x,0) seems to become a NOP on some platforms */ | ||||||
|  | 	ret = read(fd, &c, 1); | ||||||
|  | 	TRACE(("ret %d errno %d", ret, errno)) | ||||||
|  | 	if (ret > 0 || (ret < 0 && (errno == EINTR || errno == EAGAIN)))	{ | ||||||
|  | 		TRACE(("leave check_closed_writefd")) | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	close_chan_fd(channel, fd, SHUT_WR); | ||||||
|  | 	TRACE(("leave check_closed_writefd after closing %d", fd)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Iterate through the channels, performing IO if available */ | /* Iterate through the channels, performing IO if available */ | ||||||
| void channelio(fd_set *readfds, fd_set *writefds) { | void channelio(fd_set *readfds, fd_set *writefds) { | ||||||
| 
 | 
 | ||||||
| @ -229,6 +252,16 @@ void channelio(fd_set *readfds, fd_set *writefds) { | |||||||
| 			writechannel(channel, channel->errfd, channel->extrabuf); | 			writechannel(channel, channel->errfd, channel->extrabuf); | ||||||
| 		} | 		} | ||||||
| 	 | 	 | ||||||
|  | 		/* Check writefds for close, even if we don't have anything 
 | ||||||
|  | 		   to write into them. */ | ||||||
|  | 		if (channel->writefd >= 0) { | ||||||
|  | 			check_closed_writefd(channel, channel->writefd); | ||||||
|  | 		} | ||||||
|  | 		if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0) { | ||||||
|  | 			check_closed_writefd(channel, channel->errfd); | ||||||
|  | 		} | ||||||
|  | 	 | ||||||
|  | 	 | ||||||
| 		/* handle any channel closing etc */ | 		/* handle any channel closing etc */ | ||||||
| 		check_close(channel); | 		check_close(channel); | ||||||
| 
 | 
 | ||||||
| @ -439,6 +472,16 @@ void setchannelfds(fd_set *readfds, fd_set *writefds) { | |||||||
| 				FD_SET(channel->errfd, writefds); | 				FD_SET(channel->errfd, writefds); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		/* We also set the writefds for reading, so that we will be notified of close */ | ||||||
|  | 		if (channel->writefd >= 0) { | ||||||
|  | 			FD_SET(channel->writefd, readfds); | ||||||
|  | 		}		 | ||||||
|  | 		if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0) { | ||||||
|  | 			FD_SET(channel->errfd, readfds); | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		 | ||||||
|  | 
 | ||||||
| 	} /* foreach channel */ | 	} /* foreach channel */ | ||||||
| 
 | 
 | ||||||
| #ifdef USING_LISTENERS | #ifdef USING_LISTENERS | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user