aboutsummaryrefslogtreecommitdiff
path: root/sunrpc
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>1999-03-19 02:01:36 +0000
committerAndreas Schwab <schwab@suse.de>1999-03-19 02:01:36 +0000
commitd1275afec4c36467edc1da9c0ebcbf54f89ef262 (patch)
tree7821f9f4a2be05fd9f193c7e819500b60bd828b8 /sunrpc
parent6fc8f783a45396d43d0fdda10a310ddd8de9a752 (diff)
downloadglibc-d1275afec4c36467edc1da9c0ebcbf54f89ef262.tar
glibc-d1275afec4c36467edc1da9c0ebcbf54f89ef262.tar.gz
glibc-d1275afec4c36467edc1da9c0ebcbf54f89ef262.tar.bz2
glibc-d1275afec4c36467edc1da9c0ebcbf54f89ef262.zip
1999-03-18 Thorsten Kukuk <kukuk@suse.de>
* sunrpc/clnt_unix.c: Fix creation of parameters for sendmsg/recvmsg on non intel platforms. * sunrpc/svc_unix.c: Likewise. 1999-03-18 Thorsten Kukuk <kukuk@suse.de> * sunrpc/clnt_unix.c: Fix creation of parameters for sendmsg/recvmsg on non intel platforms. * sunrpc/svc_unix.c: Likewise.
Diffstat (limited to 'sunrpc')
-rw-r--r--sunrpc/clnt_unix.c80
-rw-r--r--sunrpc/svc_unix.c80
2 files changed, 101 insertions, 59 deletions
diff --git a/sunrpc/clnt_unix.c b/sunrpc/clnt_unix.c
index 240cdbbce4..761ecafb05 100644
--- a/sunrpc/clnt_unix.c
+++ b/sunrpc/clnt_unix.c
@@ -434,32 +434,26 @@ clntunix_destroy (CLIENT *h)
mem_free ((caddr_t) h, sizeof (CLIENT));
}
-#ifdef SCM_CREDENTIALS
-struct cmessage {
- struct cmsghdr cmsg;
- struct ucred cmcred;
-};
-#endif
-
static int
-__msgread (int sock, void *buf, size_t cnt)
+__msgread (int sock, void *data, size_t cnt)
{
- struct iovec iov[1];
+ struct iovec iov;
struct msghdr msg;
#ifdef SCM_CREDENTIALS
- struct cmessage cm;
+ static char cm[CMSG_SPACE(sizeof (struct ucred))];
#endif
+ int len;
- iov[0].iov_base = buf;
- iov[0].iov_len = cnt;
+ iov.iov_base = data;
+ iov.iov_len = cnt;
- msg.msg_iov = iov;
+ msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
#ifdef SCM_CREDENTIALS
- msg.msg_control = (caddr_t)&cm;
- msg.msg_controllen = sizeof(struct cmessage);
+ msg.msg_control = (caddr_t) &cm;
+ msg.msg_controllen = CMSG_SPACE(sizeof (struct ucred));
#endif
msg.msg_flags = 0;
@@ -471,43 +465,65 @@ __msgread (int sock, void *buf, size_t cnt)
}
#endif
- return recvmsg (sock, &msg, 0);
+ restart:
+ len = recvmsg (sock, &msg, 0);
+ if (len >= 0)
+ {
+ if (msg.msg_flags & MSG_CTRUNC || len == 0)
+ return 0;
+ else
+ return len;
+ }
+ if (errno == EINTR)
+ goto restart;
+ return -1;
}
static int
-__msgwrite (int sock, void *buf, size_t cnt)
+__msgwrite (int sock, void *data, size_t cnt)
{
#ifndef SCM_CREDENTIALS
/* We cannot implement this reliably. */
__set_errno (ENOSYS);
return -1;
#else
- struct iovec iov[1];
+ struct iovec iov;
struct msghdr msg;
- struct cmessage cm;
-
- iov[0].iov_base = buf;
- iov[0].iov_len = cnt;
+ struct cmsghdr *cmsg = alloca (CMSG_SPACE(sizeof (struct ucred)));
+ struct ucred cred;
+ int len;
- cm.cmsg.cmsg_type = SCM_CREDENTIALS;
- cm.cmsg.cmsg_level = SOL_SOCKET;
- cm.cmsg.cmsg_len = sizeof (struct cmessage);
/* XXX I'm not sure, if gete?id() is always correct, or if we should use
get?id(). But since keyserv needs geteuid(), we have no other chance.
It would be much better, if the kernel could pass both to the server. */
- cm.cmcred.pid = __getpid ();
- cm.cmcred.uid = __geteuid ();
- cm.cmcred.gid = __getegid ();
+ cred.pid = __getpid ();
+ cred.uid = __geteuid ();
+ cred.gid = __getegid ();
+
+ memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_CREDENTIALS;
+ cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred);
- msg.msg_iov = iov;
+ iov.iov_base = data;
+ iov.iov_len = cnt;
+
+ msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
- msg.msg_control = (caddr_t) &cm;
- msg.msg_controllen = sizeof (struct cmessage);
+ msg.msg_control = cmsg;
+ msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len);
msg.msg_flags = 0;
- return sendmsg (sock, &msg, 0);
+ restart:
+ len = sendmsg (sock, &msg, 0);
+ if (len >= 0)
+ return len;
+ if (errno == EINTR)
+ goto restart;
+ return -1;
+
#endif
}
diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c
index 0ff26aaaba..a34e54dd71 100644
--- a/sunrpc/svc_unix.c
+++ b/sunrpc/svc_unix.c
@@ -284,6 +284,8 @@ svcunix_destroy (SVCXPRT *xprt)
struct cmessage {
struct cmsghdr cmsg;
struct ucred cmcred;
+ /* hack to make sure we have enough memory */
+ char dummy[(CMSG_ALIGN (sizeof (struct ucred)) - sizeof (struct ucred) + sizeof (long))];
};
/* XXX This is not thread safe, but since the main functions in svc.c
@@ -293,15 +295,16 @@ static struct cmessage cm;
#endif
static int
-__msgread (int sock, void *buf, size_t cnt)
+__msgread (int sock, void *data, size_t cnt)
{
- struct iovec iov[1];
+ struct iovec iov;
struct msghdr msg;
+ int len;
- iov[0].iov_base = buf;
- iov[0].iov_len = cnt;
+ iov.iov_base = data;
+ iov.iov_len = cnt;
- msg.msg_iov = iov;
+ msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
@@ -319,42 +322,65 @@ __msgread (int sock, void *buf, size_t cnt)
}
#endif
- return recvmsg (sock, &msg, 0);
+ restart:
+ len = recvmsg (sock, &msg, 0);
+ if (len >= 0)
+ {
+ if (msg.msg_flags & MSG_CTRUNC || len == 0)
+ return 0;
+ else
+ return len;
+ }
+ if (errno == EINTR)
+ goto restart;
+ return -1;
}
static int
-__msgwrite (int sock, void *buf, size_t cnt)
+__msgwrite (int sock, void *data, size_t cnt)
{
#ifndef SCM_CREDENTIALS
/* We cannot implement this reliably. */
__set_errno (ENOSYS);
return -1;
#else
- struct iovec iov[1];
+ struct iovec iov;
struct msghdr msg;
-
- iov[0].iov_base = buf;
- iov[0].iov_len = cnt;
-
- cm.cmsg.cmsg_type = SCM_CREDENTIALS;
- cm.cmsg.cmsg_level = SOL_SOCKET;
- cm.cmsg.cmsg_len = sizeof (struct cmessage);
- /* XXX I'm not sure, if we really should use gete?id(), or get?id().
- It would be much better, if the kernel could pass both to the
- client. */
- cm.cmcred.pid = __getpid ();
- cm.cmcred.uid = __geteuid ();
- cm.cmcred.gid = __getegid ();
-
- msg.msg_iov = iov;
+ struct cmsghdr *cmsg = &cm.cmsg;
+ struct ucred cred;
+ int len;
+
+ /* XXX I'm not sure, if gete?id() is always correct, or if we should use
+ get?id(). But since keyserv needs geteuid(), we have no other chance.
+ It would be much better, if the kernel could pass both to the server. */
+ cred.pid = __getpid ();
+ cred.uid = __geteuid ();
+ cred.gid = __getegid ();
+
+ memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_CREDENTIALS;
+ cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred);
+
+ iov.iov_base = data;
+ iov.iov_len = cnt;
+
+ msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
- msg.msg_control = (caddr_t) &cm;
- msg.msg_controllen = sizeof (struct cmessage);
+ msg.msg_control = cmsg;
+ msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len);
msg.msg_flags = 0;
- return sendmsg (sock, &msg, 0);
+ restart:
+ len = sendmsg (sock, &msg, 0);
+ if (len >= 0)
+ return len;
+ if (errno == EINTR)
+ goto restart;
+ return -1;
+
#endif
}
@@ -446,8 +472,8 @@ svcunix_recv (SVCXPRT *xprt, struct rpc_msg *msg)
{
cd->x_id = msg->rm_xid;
/* set up verifiers */
- msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
#ifdef SCM_CREDENTIALS
+ msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
msg->rm_call.cb_verf.oa_base = (caddr_t) &cm;
msg->rm_call.cb_verf.oa_length = sizeof (cm);
#endif