summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2010-05-18 19:18:38 -0400
committerSteve Dickson <steved@redhat.com>2010-05-18 19:18:38 -0400
commite11a61532ebe21f95b074cd122cf95f014f6aaa9 (patch)
tree44b861dc5979bc15dadba7911ea2dd7b85f5200b
parentb2a9b572a85640e93667368cbf0539a236ff592a (diff)
downloadti-rpc-e11a61532ebe21f95b074cd122cf95f014f6aaa9.tar.gz
Automount with nis maps crashes and generates a core
I think I added the appropriate backward compatibility support to handle old kernels. And certainly the existing libtirpc functions are unchanged. Only one additional extenal interface (__libc_clntudp_bufcreate) is added. The remaining changes are necessary to implement it. The changes are straightforward. See https://bugzilla.redhat.com/show_bug.cgi?id=519430 Signed-off-by: Ulrich Drepper <drepper@redhat.com> Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--src/rpc_generic.c10
-rw-r--r--src/rpc_soc.c54
-rw-r--r--tirpc/rpc/rpc.h1
3 files changed, 54 insertions, 11 deletions
diff --git a/src/rpc_generic.c b/src/rpc_generic.c
index 541275c..509fb36 100644
--- a/src/rpc_generic.c
+++ b/src/rpc_generic.c
@@ -523,7 +523,7 @@ __rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
}
int
-__rpc_nconf2fd(const struct netconfig *nconf)
+__rpc_nconf2fd_flags(const struct netconfig *nconf, int flags)
{
struct __rpc_sockinfo si;
int fd;
@@ -531,7 +531,7 @@ __rpc_nconf2fd(const struct netconfig *nconf)
if (!__rpc_nconf2sockinfo(nconf, &si))
return 0;
- if ((fd = socket(si.si_af, si.si_socktype, si.si_proto)) >= 0 &&
+ if ((fd = socket(si.si_af, si.si_socktype | flags, si.si_proto)) >= 0 &&
si.si_af == AF_INET6) {
int val = 1;
@@ -541,6 +541,12 @@ __rpc_nconf2fd(const struct netconfig *nconf)
}
int
+__rpc_nconf2fd(const struct netconfig *nconf)
+{
+ return __rpc_nconf2fd_flags(nconf, 0);
+}
+
+int
__rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid)
{
int i;
diff --git a/src/rpc_soc.c b/src/rpc_soc.c
index 709a8a8..c678429 100644
--- a/src/rpc_soc.c
+++ b/src/rpc_soc.c
@@ -60,13 +60,14 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
#include "rpc_com.h"
extern mutex_t rpcsoc_lock;
static CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t,
- int *, u_int, u_int, char *);
+ int *, u_int, u_int, char *, int);
static SVCXPRT *svc_com_create(int, u_int, u_int, char *);
static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *);
@@ -78,7 +79,7 @@ static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *);
* A common clnt create routine
*/
static CLIENT *
-clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp)
+clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp, flags)
struct sockaddr_in *raddr;
rpcprog_t prog;
rpcvers_t vers;
@@ -86,6 +87,7 @@ clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp)
u_int sendsz;
u_int recvsz;
char *tp;
+ int flags;
{
CLIENT *cl;
int madefd = FALSE;
@@ -100,9 +102,21 @@ clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp)
return (NULL);
}
if (fd == RPC_ANYSOCK) {
- fd = __rpc_nconf2fd(nconf);
- if (fd == -1)
- goto syserror;
+ static int have_cloexec;
+ fd = __rpc_nconf2fd_flags(nconf, flags);
+ if (fd == -1) {
+ if ((flags & SOCK_CLOEXEC) && have_cloexec <= 0) {
+ fd = __rpc_nconf2fd(nconf);
+ if (fd == -1)
+ goto syserror;
+ if (flags & SOCK_CLOEXEC) {
+ have_cloexec = -1;
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+ }
+ } else
+ goto syserror;
+ } else if (flags & SOCK_CLOEXEC)
+ have_cloexec = 1;
madefd = TRUE;
}
@@ -154,6 +168,28 @@ err: if (madefd == TRUE)
}
CLIENT *
+__libc_clntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz, flags)
+ struct sockaddr_in *raddr;
+ u_long prog;
+ u_long vers;
+ struct timeval wait;
+ int *sockp;
+ u_int sendsz;
+ u_int recvsz;
+ int flags;
+{
+ CLIENT *cl;
+
+ cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
+ sendsz, recvsz, "udp", flags);
+ if (cl == NULL) {
+ return (NULL);
+ }
+ (void) CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait);
+ return (cl);
+}
+
+CLIENT *
clntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz)
struct sockaddr_in *raddr;
u_long prog;
@@ -166,7 +202,7 @@ clntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz)
CLIENT *cl;
cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
- sendsz, recvsz, "udp");
+ sendsz, recvsz, "udp", 0);
if (cl == NULL) {
return (NULL);
}
@@ -195,7 +231,7 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
u_int recvsz;
{
return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
- sendsz, recvsz, "tcp");
+ sendsz, recvsz, "tcp", 0);
}
/* IPv6 version of clnt*_*create */
@@ -215,7 +251,7 @@ clntudp6_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz)
CLIENT *cl;
cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
- sendsz, recvsz, "udp6");
+ sendsz, recvsz, "udp6", 0);
if (cl == NULL) {
return (NULL);
}
@@ -244,7 +280,7 @@ clnttcp6_create(raddr, prog, vers, sockp, sendsz, recvsz)
u_int recvsz;
{
return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
- sendsz, recvsz, "tcp6");
+ sendsz, recvsz, "tcp6", 0);
}
#endif
diff --git a/tirpc/rpc/rpc.h b/tirpc/rpc/rpc.h
index 29e29e9..6c0222e 100644
--- a/tirpc/rpc/rpc.h
+++ b/tirpc/rpc/rpc.h
@@ -101,6 +101,7 @@ __END_DECLS
*/
__BEGIN_DECLS
int __rpc_nconf2fd(const struct netconfig *);
+int __rpc_nconf2fd_flags(const struct netconfig *, int);
int __rpc_nconf2sockinfo(const struct netconfig *, struct __rpc_sockinfo *);
int __rpc_fd2sockinfo(int, struct __rpc_sockinfo *);
u_int __rpc_get_t_size(int, int, int);