/[rtmk]/rtmk/ipc-kmsg.c
ViewVC logotype

Diff of /rtmk/ipc-kmsg.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by jrydberg, Sun Feb 24 23:09:48 2002 UTC revision 1.13 by jrydberg, Wed Mar 6 00:55:01 2002 UTC
# Line 118  copyin_header (struct task *task, struct Line 118  copyin_header (struct task *task, struct
118    if (! RTMK_MSG_TYPE_PORT_ANY_SEND (remote_type))    if (! RTMK_MSG_TYPE_PORT_ANY_SEND (remote_type))
119      return KERN_INVALID_RIGHT;      return KERN_INVALID_RIGHT;
120    
   if (local_type || local_name)  
     {  
       if (! RTMK_MSG_TYPE_PORT_ANY_SEND (local_type))  
         return KERN_INVALID_RIGHT;  
     }  
   
121    /* Fetch remote port from IPC object.   */    /* Fetch remote port from IPC object.   */
122    
123    kr = ipc_object_lookup (task->ipc_object, remote_name, &entry);    kr = ipc_object_lookup (task->ipc_object, remote_name, &entry);
# Line 142  copyin_header (struct task *task, struct Line 136  copyin_header (struct task *task, struct
136    msgh->msgh_local_port = (rtmk_port_t) entry->ie_port;    msgh->msgh_local_port = (rtmk_port_t) entry->ie_port;
137    
138    /* Fetch local port from IPC object.  */    /* Fetch local port from IPC object.  */
139    if (local_name)    if (local_type)
140      {      {
141          if (! RTMK_MSG_TYPE_PORT_ANY_SEND (local_type))
142            return KERN_INVALID_RIGHT;
143    
144        kr = ipc_object_lookup (task->ipc_object, local_name, &entry);        kr = ipc_object_lookup (task->ipc_object, local_name, &entry);
145        if (kr)        if (kr)
146          return kr;          return kr;
# Line 486  convert_intermediate_to_user (struct tas Line 483  convert_intermediate_to_user (struct tas
483              }              }
484            else            else
485              {              {
486                assert (0);                struct vm_map_copy *copy = *(struct vm_map_copy **) data_ptr;
487              }                vm_offset_t dst_addr;
         }  
   
       /* Calulcat length of inline data and skip over it.   */  
       if (LIKELY (type->msgt_inline))  
         start = WORD_ALIGN (data_ptr + length);  
       else  
         start = data_ptr + sizeof (vm_offset_t);  
     }  
   return KERN_SUCCESS;  
 }  
   
 /* Convert message stored in KMSG to intermedate format where port  
    names are resolved to ipc_port structures and out-of-line data  
    in mapped into kernel address space.  */  
 kern_return_t  
 copyin_body (struct task *task, struct ipc_kmsg *kmsg)  
 {  
   struct rtmk_msg_type_long *type_long;  
   struct rtmk_msg_type *type;  
   struct ipc_entry *entry;  
   vm_offset_t start, end;  
   kern_return_t kr;  
   
   start = (vm_offset_t)  (&kmsg->header + 1);  
   end   = ((vm_offset_t) (&kmsg->header)) + kmsg->header.msgh_length;  
   
   /* Loop through all type elements of the message body.  */  
488    
489    while (start < end)                kr = vm_map_copyout (task->map, copy, & dst_addr);
490      {                if (kr)
491        unsigned int header_size, number, length, size, i;                  assert (kr == KERN_SUCCESS);
492        vm_offset_t data_ptr;                *(vm_offset_t *) data_ptr = dst_addr;
   
       /* If we we have a long format message type header we  
          get length and number fields from long structure. */  
       type = (struct rtmk_msg_type *) start;  
       size = type->msgt_length;  
   
       if (LIKELY (! type->msgt_long))  
         {  
           header_size = sizeof (struct rtmk_msg_type);  
           number = type->msgt_number;  
         }  
       else  
         {  
           type_long = (struct rtmk_msg_type_long *) type;  
           header_size = sizeof (struct rtmk_msg_type_long);  
           number = type_long->msgtl_number;  
         }  
   
       /* DATA_PTR points to where the inline data begins.  */  
       data_ptr = ((vm_offset_t) type) + header_size;  
   
       /* If TYPE->MSGT_TYPE specifys any port type we must  
          handle right manipulation.  This is a pretty common case.  */  
       if (RTMK_MSG_TYPE_PORT_ANY (type->msgt_type))  
         {  
           rtmk_port_t *port_name;  
           struct ipc_port *port;  
             
           /* ??? ports can not be in out-of-line memory?  */  
           assert (type->msgt_inline == true);  
           port_name = (rtmk_port_t *) data_ptr;  
             
           /* Loop through all elements and take actions upon them.  */  
           for (i = 0; i < number; i++)  
             {  
               if (port_name [i])  
                 {  
                   kr = ipc_object_lookup (task->ipc_object, port_name [i],  
                                           & entry);  
                   if (kr != KERN_SUCCESS)  
                     return kr;  
                   
                   port = entry->ie_port;  
                 }  
               else  
                 port = 0;  
             
               /* Store pointer to port structure in place for port name.  */  
               port_name [i] = (rtmk_port_t) port;  
493              }              }
494          }          }
         
       /* Out-of-line memory.  ??? not supported yet, just skip it.  */  
       else if (type->msgt_inline == false)  
         {  
           /* ??? handle OOL memory here.  */  
         }  
495    
496        /* Calulcat length of inline data and skip over it.   */        /* Calulcat length of inline data and skip over it.   */
       length = ((number * size) + 7) >> 3;  
497        if (LIKELY (type->msgt_inline))        if (LIKELY (type->msgt_inline))
498          start = WORD_ALIGN (data_ptr + length);          start = WORD_ALIGN (data_ptr + length);
499        else        else
500          start = data_ptr + sizeof (rtmk_port_t *); /* ??? ptr */          start = data_ptr + sizeof (vm_offset_t);
501      }      }
502    return KERN_SUCCESS;    return KERN_SUCCESS;
503  }  }
504    
 /* Convert message stored in KMSG from intermedate format to format  
    that can be directly copied to user-land task.  Out-of-line data  
    is mapped in TASK's addres space, and ports are resolved.  */  
 static kern_return_t  
 copyout_body (struct task *task, struct ipc_kmsg *kmsg)  
 {  
   struct rtmk_msg_type_long *type_long;  
   struct rtmk_msg_type *type;  
   vm_offset_t start, end;  
   kern_return_t kr;  
   
   start = (vm_offset_t)  (&kmsg->header + 1);  
   end   = ((vm_offset_t) (&kmsg->header)) + kmsg->header.msgh_length;  
   
   /* Loop through all type elements of the message body.  */  
   
   while (start < end)  
     {  
       unsigned int header_size, number, length, size, i;  
       vm_offset_t data_ptr;  
   
       /* If we we have a long format message type header we  
          get length and number fields from long structure. */  
       type = (struct rtmk_msg_type *) start;  
       size = type->msgt_length;  
   
       if (LIKELY (! type->msgt_long))  
         {  
           header_size = sizeof (struct rtmk_msg_type);  
           number = type->msgt_number;  
         }  
       else  
         {  
           type_long = (struct rtmk_msg_type_long *) type;  
           header_size = sizeof (struct rtmk_msg_type_long);  
           number = type_long->msgtl_number;  
         }  
   
       /* DATA_PTR points to where the inline data begins.  */  
       data_ptr = ((vm_offset_t) type) + header_size;  
   
       /* If TYPE->MSGT_TYPE specifys any port type we must  
          handle right manipulation.  This is a pretty common case.  */  
       if (RTMK_MSG_TYPE_PORT_ANY (type->msgt_type))  
         {  
           struct ipc_port **port;  
           rtmk_port_t *port_name;  
             
           /* ??? ports can not be in out-of-line memory?  */  
           assert (type->msgt_inline == true);  
             
           port_name = (rtmk_port_t *) data_ptr;  
           port      = (struct ipc_port **) data_ptr;  
   
           /* Loop through all elements and take actions upon them.  */  
           for (i = 0; i < number; i++)  
             {      
               if (port [i])  
                 {  
                   kr = ipc_object_copyout (task->ipc_object, port [i],  
                                            type->msgt_type, & port_name [i]);  
                   if (kr != KERN_SUCCESS)  
                     return kr;  
                 }  
               else  
                 port_name [i] = RTMK_PORT_NULL;  
             }  
         }  
         
       /* Out-of-line memory.  ??? not supported yet, just skip it.  */  
       else if (type->msgt_inline == false)  
         {  
           /* ??? */  
         }  
   
       /* Calulcat length of inline data and skip over it.   */  
       length = ((number * size) + 7) >> 3;  
       if (LIKELY (type->msgt_inline))  
         start = WORD_ALIGN (data_ptr + length);  
       else  
         start = data_ptr + sizeof (rtmk_port_t *); /* ??? ptr */  
     }  
   return KERN_SUCCESS;  
 }  
505    
506  static kern_return_t  static kern_return_t
507  copyout_header (struct task *task, struct ipc_kmsg *kmsg)  copyout_header (struct task *task, struct ipc_kmsg *kmsg)

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26