#include <netdb.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
+#include <sys/fcntl.h>
#include <errno.h>
#ifdef _LIBC
# include <libintl.h>
#else
-# include "config.h"
# ifndef _
# define _(s) (s)
# endif
# define __close(f) close ((f))
#endif
-#if !defined HAVE_SVCTCP_SOCKET || !defined HAVE_SVCUDP_SOCKET
static int
svc_socket (u_long number, int type, int protocol, int reuse)
{
socklen_t len = sizeof (struct sockaddr_in);
char rpcdata [1024], servdata [1024];
struct rpcent rpcbuf, *rpcp;
- struct servent servbuf, *servp;
+ struct servent servbuf, *servp = NULL;
int sock, ret;
const char *proto = protocol == IPPROTO_TCP ? "tcp" : "udp";
}
}
+ if (sock >= 0 && protocol == IPPROTO_TCP)
+ {
+ /* Make the TCP rendezvous socket non-block to avoid
+ * problems with blocking in accept() after a spurious
+ * wakeup from the kernel */
+ int flags;
+ if ((flags = fcntl(sock, F_GETFL)) < 0)
+ {
+ perror (_("svc_socket: can't get socket flags"));
+ (void) __close (sock);
+ sock = -1;
+ }
+ else if (fcntl(sock, F_SETFL, flags|O_NONBLOCK) < 0)
+ {
+ perror (_("svc_socket: can't set socket flags"));
+ (void) __close (sock);
+ sock = -1;
+ }
+ }
+
return sock;
}
-#endif
-#ifndef HAVE_SVCTCP_SOCKET
/*
* Create and bind a TCP socket based on program number
*/
{
return svc_socket (number, SOCK_STREAM, IPPROTO_TCP, reuse);
}
-#endif
-#ifndef HAVE_SVCUDP_SOCKET
/*
* Create and bind a UDP socket based on program number
*/
{
return svc_socket (number, SOCK_DGRAM, IPPROTO_UDP, reuse);
}
-#endif
#ifdef TEST
static int