help-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Trying to understand Mach IPC


From: Manuel Menal
Subject: Re: Trying to understand Mach IPC
Date: Mon, 10 Jun 2002 12:33:04 +0200
User-agent: Gnus/5.090006 (Oort Gnus v0.06) Emacs/21.2 (i386-debian-linux-gnu)

Sun, 09 Jun 2002 22:56:35 +0200, you wrote: 

 > Hello! I would need some help with Mach IPC ( without using MIG, only the
 > syscalls for IPC ); I was writing
 > some example programs with the purpose to learn about Mach IPC, and now I'm
 > blocked and don't know
 > how to continue. I hope that somewhat could help me in this mailing list.

That is probably a good place to ask help. :-)

 > I had used for trying to program mach IPC, the OSF manuals ( IMHO not very 
 > good
 > for programming learning; either they are reference manuals, either they 
 > explain
 > you only the ideas behind Mach; they are better suitted
 > for those who already know mach )

Well, I do think they are quite good for learning how to use Mach IPC. 
Though, they probably contain more informations about how to use Mach
IPC via MiG than directly, because it's the way you generally do it -
it's so much easier!
 
 >  the gnumach reference manuals, and "A
 > programmer's guide to the mach
 > system calls", that treats about mach 2.5 IPC wo MIG;

Never heard of that book. Is it still published?

 > then I tried to adapt what in this last text is said to the Mach 3.0
 > system calls and message data  structures , described in the
 > gnumach reference manual and
 > in the "Mach 3 Kernel Interfaces" of the OSF, but whithout success, :-(

It seems the Right Way(tm).

 > Then my questions are :

 >     (i) who do I construct a message in C language ?

 >         I tried the following ( just a mach 3 adaption of some sample code 
 > of "A
 > programmer's guide.... " ) :

 >         make a structure like that :

[snip]

 >         and so on..... but I think that it is not the way.

That seems the right way to me. At least, the idea is correct. Not sure
you filled the right fields with the correct values, though ;-)

 >     (ii) Once I have a well formed message, who do I send this message 
 > correctly
 > ?

 >             I tried in this case the following :         msg_return_code =
 > mach_msg( &(my_message.head), MACH_SEND_MSG, my_message.head.msgh_size,
 > 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL );

 >             but I suspect it didn't work!!!

Seems a correct call. Well, at least it works with some example I wrote,
so it must be correct :-)

 >     I put the sample source code I was preparing as an attachment; I will
 > continue trying by mi own, but
 >     some help will help me very much!

 >        Thanks!!

Just before I try to see what's wrong with your code: could you please
use the GNU Coding Standards[1] ? That would make your code so easier :). 

 > /*
 >  *   Mach IPC "hello, world!"
 >  */

Heh, where is the GPL header? ;P
 
 > #include <mach.h>

 > #include <stdio.h>

 > int main( void )
 > {
 >     mach_port_t my_port;
 >     kern_return_t error;

We generally use « err » as an identifier here, because error is already
a commonly-used function - a GNU extension, see info
libc<RET>ierror<RET> :) Furthermore, we generally use error_t too,
because this way the err variable can be used to store the result of
many other calls, not just Mach ones.
    
 >     mach_msg_return_t msg_return_code;

I guess you could use a « err » variable for that one too, since
<mach/message.h> defines mach_msg_return_t as 
typedef kern_return_t mach_msg_return_t;

    
[snip, seems correct]   
    
 >     error = mach_port_allocate( mach_task_self(), MACH_PORT_RIGHT_RECEIVE, 
 > &my_port );

Hmm.. What's the point with storing the error value if you don't test
it. You should probably have something like:

  if (err)
    error (1, err, "E: mach_port_allocate_failed"); 

here. (don't forget #include <error.h>, and to define _GNU_SOURCE)

 >     /* ejem!, I don't make comprobations in this case */
 >     printf( "The port %d was created\n", my_port );

Printing a mach_port_t as an integer is quite .. uncommon =)

 >     /* Header of the message : */    
        
 >     my_message.head.msgh_size = sizeof(struct simple_message);
        
 >     /* my_message.head.msgh_local_port = mach_task_self(); */
 >     my_message.head.msgh_local_port = MACH_PORT_NULL;
 >     my_message.head.msgh_remote_port = my_port;
 >     /* my_message.head.msgh_id = 0x1234; */

You must fill some other fields too. msgh_bits _must_ be filled with the
appropriate value. You should read « Mach 3 Kernel Interfaces » [2],
page 327.

 >     /* Type of the message : */
    
 >     my_message.type.msgt_name = MACH_MSG_TYPE_INTEGER_32;
 >     my_message.type.msgt_size = 32;
 >     my_message.type.msgt_inline = TRUE;
 >     my_message.type.msgt_longform = FALSE;

Same, IIRC you must fill the msgt_number field, described in page 330 of
the same manual.
    
[snip]
    
 >     /* OK, time to send the message : */
    
 >     msg_return_code = mach_msg( &(my_message.head), MACH_SEND_MSG, 
 > my_message.head.msgh_size, 
 >                              0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, 
 > MACH_PORT_NULL );
                        
 >     if( msg_return_code != MACH_MSG_SUCCESS ){       /* Here are some 
 > errors; let's study them later */
 >      printf( "Error : could not send the message, %d\n", msg_return_code );
 >     }
 >     else{
 >      printf( "Success : the message was queued\n" );
 >     }                        

Same. You should use error. I think:

if (err)
  error (2, err, "E: could not send message");
else
  printf ("Sucess! The message was queued.\n");

is much readable :-)
    
[snip, seems correct]
    
 >     msg_return_code = mach_msg( &(rcv_message.head), MACH_RCV_MSG, 0, 
 > rcv_message.head.msgh_size, 
 >                              my_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL 
 > );

Seems correct to me (except I would have used
rcv_message.head.msgh_local_port, but that's not important). 
                                
 >     printf( "I received the integer %d\n", rcv_message.inline_data );

Where is the return? main should _always_ return a value, remember. :)

 > }

Oh, and. Your example looks like the one described in
http://web.walfield.org/pub/people/neal/papers/hurd-misc/mach-ipc-without-mig.txt,
except that it has no threads. You should have a look at it, it has good
explainations, and good references. Don't look at the solution, that
would be cheating! :-)

Bye,

[1]: http://www.gnu.org/prep/standards_toc.html
[2]: http://www-2.cs.cmu.edu/afs/cs/project/mach/public/www/doc/osf.html

-- 
Manuel Menal



reply via email to

[Prev in Thread] Current Thread [Next in Thread]