about summary refs log tree commit diff
path: root/sunrpc/clnt_unix.c
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/clnt_unix.c
parent6fc8f783a45396d43d0fdda10a310ddd8de9a752 (diff)
downloadglibc-d1275afec4c36467edc1da9c0ebcbf54f89ef262.tar.gz
glibc-d1275afec4c36467edc1da9c0ebcbf54f89ef262.tar.xz
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/clnt_unix.c')
-rw-r--r--sunrpc/clnt_unix.c80
1 files changed, 48 insertions, 32 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
 }