about summary refs log tree commit diff
path: root/sysdeps/mach/hurd/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach/hurd/ioctl.c')
-rw-r--r--sysdeps/mach/hurd/ioctl.c79
1 files changed, 64 insertions, 15 deletions
diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c
index 6927906507..08389968df 100644
--- a/sysdeps/mach/hurd/ioctl.c
+++ b/sysdeps/mach/hurd/ioctl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,93,94,95,96,97,99,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1992,93,94,95,96,97,99,2000,02 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -39,12 +39,14 @@
 int
 __ioctl (int fd, unsigned long int request, ...)
 {
+#ifdef MACH_MSG_TYPE_CHAR
   /* Map individual type fields to Mach IPC types.  */
   static const int mach_types[] =
     { MACH_MSG_TYPE_CHAR, MACH_MSG_TYPE_INTEGER_16, MACH_MSG_TYPE_INTEGER_32,
       MACH_MSG_TYPE_INTEGER_64 };
 #define io2mach_type(count, type) \
   ((mach_msg_type_t) { mach_types[type], typesize (type) * 8, count, 1, 0, 0 })
+#endif
 
   /* Extract the type information encoded in the request.  */
   unsigned int type = _IOC_TYPE (request);
@@ -53,17 +55,29 @@ __ioctl (int fd, unsigned long int request, ...)
 #define msg_align(x) \
   (((x) + sizeof (mach_msg_type_t) - 1) & ~(sizeof (mach_msg_type_t) - 1))
   struct
-    {
-      mig_reply_header_t header;
-      char data[3 * sizeof (mach_msg_type_t) +
-		msg_align (_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type))) +
-		msg_align (_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type))) +
-		_IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
-    } msg;
+  {
+#ifdef MACH_MSG_TYPE_BIT
+    mig_reply_header_t header;
+    char data[3 * sizeof (mach_msg_type_t) +
+	     msg_align (_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type))) +
+	     msg_align (_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type))) +
+	     _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+#else  /* Untyped Mach IPC format.  */
+    mig_reply_error_t header;
+    char data[_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type)) +
+	     _IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type)) +
+	     _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+    mach_msg_trailer_t trailer;
+#endif
+  } msg;
   mach_msg_header_t *const m = &msg.header.Head;
-  mach_msg_type_t *t;
   mach_msg_id_t msgid;
   unsigned int reply_size;
+#ifdef MACH_MSG_TYPE_BIT
+  mach_msg_type_t *t;
+#else
+  void *p;
+#endif
 
   void *arg;
 
@@ -74,7 +88,11 @@ __ioctl (int fd, unsigned long int request, ...)
   error_t send_rpc (io_t ioport)
     {
       error_t err;
+#ifdef MACH_MSG_TYPE_BIT
       mach_msg_type_t *t = &msg.header.RetCodeType;
+#else
+      void *p = &msg.header.RetCode;
+#endif
 
       /* Marshal the request arguments into the message buffer.
 	 We must redo this work each time we retry the RPC after a SIGTTOU,
@@ -92,14 +110,18 @@ __ioctl (int fd, unsigned long int request, ...)
 	    {
 	      if (count > 0)
 		{
-		  void *p = &t[1];
 		  const size_t len = count * typesize ((unsigned int) type);
+#ifdef MACH_MSG_TYPE_BIT
+		  void *p = &t[1];
 		  *t = io2mach_type (count, type);
 		  p = __mempcpy (p, argptr, len);
-		  argptr += len;
 		  p = (void *) (((uintptr_t) p + sizeof (*t) - 1)
 				& ~(sizeof (*t) - 1));
 		  t = p;
+#else
+		  p = __mempcpy (p, argptr, len);
+#endif
+		  argptr += len;
 		}
 	    }
 
@@ -112,14 +134,24 @@ __ioctl (int fd, unsigned long int request, ...)
 	{
 	  /* The RPC takes a single integer_t argument.
 	     Rather than pointing to the value, ARG is the value itself.  */
+#ifdef MACH_MSG_TYPE_BIT
 	  *t++ = io2mach_type (1, _IOTS (int));
 	  *((int *) t)++ = (int) arg;
+#else
+	  *((int *) p)++ = (int) arg;
+#endif
 	}
 
-      m->msgh_size = (char *) t - (char *) &msg;
+      memset (m, 0, sizeof *m);	/* Clear unused fields.  */
+      m->msgh_size = (
+#ifdef MACH_MSG_TYPE_BIT
+		      (char *) t
+#else
+		      (char *) p
+#endif
+		      - (char *) &msg);
       m->msgh_remote_port = ioport;
       m->msgh_local_port = __mig_get_reply_port ();
-      m->msgh_seqno = 0;
       m->msgh_id = msgid;
       m->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
 				     MACH_MSG_TYPE_MAKE_SEND_ONCE);
@@ -153,13 +185,15 @@ __ioctl (int fd, unsigned long int request, ...)
 		MIG_SERVER_DIED : MIG_REPLY_MISMATCH);
 
       if (m->msgh_size != reply_size &&
-	  m->msgh_size != sizeof (mig_reply_header_t))
+	  m->msgh_size != sizeof msg.header)
 	return MIG_TYPE_ERROR;
 
+#ifdef MACH_MSG_TYPE_BIT
       if (*(int *) &msg.header.RetCodeType !=
 	  ((union { mach_msg_type_t t; int i; })
 	   { t: io2mach_type (1, _IOTS (sizeof msg.header.RetCode)) }).i)
 	return MIG_TYPE_ERROR;
+#endif
       return msg.header.RetCode;
     }
 
@@ -193,7 +227,7 @@ __ioctl (int fd, unsigned long int request, ...)
   /* Compute the expected size of the reply.  There is a standard header
      consisting of the message header and the reply code.  Then, for out
      and in/out ioctls, there come the data with their type headers.  */
-  reply_size = sizeof (mig_reply_header_t);
+  reply_size = sizeof msg.header;
 
   if (_IOC_INOUT (request) & IOC_OUT)
     {
@@ -201,11 +235,15 @@ __ioctl (int fd, unsigned long int request, ...)
 	{
 	  if (count > 0)
 	    {
+#ifdef MACH_MSG_TYPE_BIT
 	      /* Add the size of the type and data.  */
 	      reply_size += sizeof (mach_msg_type_t) + typesize (type) * count;
 	      /* Align it to word size.  */
 	      reply_size += sizeof (mach_msg_type_t) - 1;
 	      reply_size &= ~(sizeof (mach_msg_type_t) - 1);
+#else
+	      reply_size += typesize (type) * count;
+#endif
 	    }
 	}
       figure_reply (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
@@ -218,7 +256,11 @@ __ioctl (int fd, unsigned long int request, ...)
      into either SIGTTOU or EIO.  */
   err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc));
 
+#ifdef MACH_MSG_TYPE_BIT
   t = (mach_msg_type_t *) msg.data;
+#else
+  p = (void *) msg.data;
+#endif
   switch (err)
     {
       /* Unpack the message buffer into the argument location.  */
@@ -228,6 +270,7 @@ __ioctl (int fd, unsigned long int request, ...)
 	  if (count > 0)
 	    {
 	      const size_t len = count * typesize (type);
+#ifdef MACH_MSG_TYPE_BIT
 	      union { mach_msg_type_t t; int i; } ipctype;
 	      ipctype.t = io2mach_type (count, type);
 	      if (*(int *) t != ipctype.i)
@@ -238,6 +281,12 @@ __ioctl (int fd, unsigned long int request, ...)
 		*update += len;
 	      t = (void *) (((uintptr_t) t + len + sizeof (*t) - 1)
 			    & ~(sizeof (*t) - 1));
+#else
+	      memcpy (store, p, len);
+	      p += len;
+	      if (update != NULL)
+		*update += len;
+#endif
 	    }
 	  return 0;
 	}