This is the mail archive of the libc-hacker@cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

A new patch for sunrpc/clnt_udp.c


Hi,

Here is a new patch for sunrpc/clnt_udp.c. I optimized it a little.
The problem is applications may time out on call to portmap to
localhost for NIS during shutdown. Machine acts as if it hangs.
This patch tries to fix it.

Thanks.


----
Wed Apr 14 11:10:22 1999  H.J. Lu  <hjl@gnu.org>

	* sunrpc/clnt_udp.c (is_network_up): New function.
	(clntudp_call): Call is_network_up () to check if any network
	interface is up in case of timeout.

Index: sunrpc/clnt_udp.c
===================================================================
RCS file: /local/work/cvs/gnu/glibc/sunrpc/clnt_udp.c,v
retrieving revision 1.1.1.12
diff -u -p -r1.1.1.12 clnt_udp.c
--- sunrpc/clnt_udp.c	1998/11/19 18:46:59	1.1.1.12
+++ sunrpc/clnt_udp.c	1999/04/15 05:13:39
@@ -48,6 +48,7 @@ static char sccsid[] = "@(#)clnt_udp.c 1
 #include <netdb.h>
 #include <errno.h>
 #include <rpc/pmap_clnt.h>
+#include <net/if.h>
 
 extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *);
 extern u_long _create_xid (void);
@@ -214,6 +215,33 @@ clntudp_create (raddr, program, version,
 			    UDPMSGSIZE, UDPMSGSIZE);
 }
 
+static int
+is_network_up (int sock)
+{
+  struct ifconf ifc;
+  char buf [UDPMSGSIZE];
+  struct ifreq ifreq, *ifr;
+  int n;
+
+  ifc.ifc_len = sizeof (buf);
+  ifc.ifc_buf = buf;
+  if (__ioctl(sock, SIOCGIFCONF, (char *) &ifc) == 0)
+    {
+      ifr = ifc.ifc_req;
+      for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++)
+	{
+	  ifreq = *ifr;
+	  if (__ioctl (sock, SIOCGIFFLAGS, (char *) &ifreq) < 0)
+	    break;
+	    
+	  if ((ifreq.ifr_flags & IFF_UP)
+	      && ifr->ifr_addr.sa_family == AF_INET)
+	    return 1;
+	}
+    }
+  return 0;
+}
+
 static enum clnt_stat
 clntudp_call (cl, proc, xargs, argsp, xresults, resultsp, utimeout)
      CLIENT *cl;	/* client handle */
@@ -239,6 +267,7 @@ clntudp_call (cl, proc, xargs, argsp, xr
   bool_t ok;
   int nrefreshes = 2;		/* number of times to refresh cred */
   struct timeval timeout;
+  int anyup;			/* any network interface up */
 
   if (cu->cu_total.tv_usec == -1)
     {
@@ -294,12 +323,20 @@ send_again:
   reply_msg.acpted_rply.ar_results.proc = xresults;
   fd.fd = cu->cu_sock;
   fd.events = POLLIN;
+  anyup = 0;
   for (;;)
     {
       switch (__poll(&fd, 1, milliseconds))
 	{
 
 	case 0:
+	  if (anyup == 0)
+	    {
+	      anyup = is_network_up (cu->cu_sock);
+	      if (!anyup)
+		return (cu->cu_error.re_status = RPC_CANTRECV);
+	    }
+
 	  time_waited.tv_sec += cu->cu_wait.tv_sec;
 	  time_waited.tv_usec += cu->cu_wait.tv_usec;
 	  while (time_waited.tv_usec >= 1000000)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]