]> granicus.if.org Git - pdns/commitdiff
make rec_control not block indefinitely
authorBert Hubert <bert.hubert@netherlabs.nl>
Sun, 14 Jan 2007 13:37:08 +0000 (13:37 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sun, 14 Jan 2007 13:37:08 +0000 (13:37 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@945 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/misc.cc
pdns/rec_channel.cc

index 7fb60f88e343e0c24cd9803ace04a0aa4a8c2309..995cf17da81b7a67a894ec4eaf769d60654db34f 100644 (file)
@@ -264,6 +264,7 @@ void parseService(const string &descr, ServiceTuple &st)
   }
 }
 
+// returns -1 in case if error, 0 if no data is available, 1 if there is. In the first two cases, errno is set
 int waitForData(int fd, int seconds, int useconds)
 {
   struct timeval tv;
index b3df25c01c159289ce7ca0316efa4aed513441ed..0ac5b528b50072319d567a49d5f98443bcd3cc74 100644 (file)
@@ -120,14 +120,35 @@ void RecursorControlChannel::send(const std::string& msg, const std::string* rem
     throw AhuException("Unable to send message over control channel: "+string(strerror(errno)));
 }
 
+// returns -1 in case if error, 0 if no data is available, 1 if there is. In the first two cases, errno is set
+static int waitForData(int fd, int seconds, int useconds)
+{
+  struct timeval tv;
+  int ret;
+
+  tv.tv_sec   = seconds;
+  tv.tv_usec  = useconds;
+
+  fd_set readfds;
+  FD_ZERO( &readfds );
+  FD_SET( fd, &readfds );
+
+  ret = select( fd + 1, &readfds, NULL, NULL, &tv );
+  if ( ret == 0 )
+    errno = ETIMEDOUT;
+
+  return ret;
+}
+
+
 string RecursorControlChannel::recv(std::string* remote)
 {
   char buffer[16384];
   ssize_t len;
   struct sockaddr_un remoteaddr;
   socklen_t addrlen=sizeof(remoteaddr);
-
-  if((len=::recvfrom(d_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&remoteaddr, &addrlen)) < 0)
+    
+  if((waitForData(d_fd, 5, 0 ) != 1) || (len=::recvfrom(d_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&remoteaddr, &addrlen)) < 0)
     throw AhuException("Unable to receive message over control channel: "+string(strerror(errno)));
 
   if(remote)