help-hurd
[Top][All Lists]
Advanced

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

Re: file_notice_changes RPC


From: Thomas Bushnell, BSG
Subject: Re: file_notice_changes RPC
Date: 09 May 2002 23:50:20 -0700
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Wolfgang Jährling <wolfgang@pro-linux.de> writes:

> Hi!
> 
> I tried to use the file_notice_changes() RPC. First, I created a port:
> 
>   err = mach_port_allocate (mach_task_self (),
>                             MACH_PORT_RIGHT_RECEIVE,
>                             &notify_port);
> 
> Then I opened a file on an ext2 file system:
> 
>   file = file_name_lookup ("foo", 0, 0);
> 
> But when I tried to request notification messages with
> 
>   err = file_notice_changes (file, notify_port, MACH_PORT_TYPE_SEND);
> 
> this failed with "(ipc/mig) server type check failure". What am I doing
> wrong?

You need to make a send right, and you are not.

MACH_PORT_RIGHT_* is used to name a particular type of port in kernel
calls specifically to create, modify, and such (like
mach_port_allocate).

MACH_PORT_TYPE_* is used to create bitmaps of different port types
(for things like mach_port_type); this allows the kernel to tell you
all the types you have available under some name by OR-ing the values
together.  

MACH_PORT_RIGHT_* and MACH_PORT_TYPE_* are defined in <mach/port.h>.

Neither of these are actually used in message passing.  That is,
MACH_PORT_{TYPE,RIGHT}_* are used in kernel calls that manipulate or
query port namespaces, but not to describe actual ports in transit in
messages.

Polymorphic arguments, like the port you send in file_notice_changes,
describe actual ports in transit in messages.  They get the flags
found in <mach/message.h>; and are always MACH_MSG_TYPE_*.

In this case, there are three plausible choices from those bits, all
of which pass a send right: MACH_MSG_TYPE_MOVE_SEND,
MACH_MSG_TYPE_COPY_SEND, and MACH_MSG_TYPE_MAKE_SEND.

MACH_MSG_TYPE_COPY_SEND is the most basic; you have to have a send
right, and a copy of it is created and sent in the message.  But you
can't use that one here, because you don't *have* a send right, you
only have a receive right.

MACH_MSG_TYPE_MOVE_SEND is just like .._COPY_SEND, except your
reference is transferred--you lose your existing reference instead of
a copy being made.  It's like COPY_SEND with an automatic
mach_port_deallocate.  

MACH_MSG_TYPE_MAKE_SEND requires you to have a *receive* right, makes
a brand-new send right from it, and then transfers that.  This is the
option you want.

Now, that's what will fix your bug.  But why are you getting that
confusing error?  Because you are passing some random number (whatever 
is in the variable notify_port) with a message type of
"MACH_PORT_TYPE_SEND" (bogus in that context)--but that macro has the
value 65536.  Valid MACH_MSG_TYPE_* values are all less than
MACH_MSG_TYPE_LAST (that is, 22).  The kernel mostly doesn't care what
you say in this position.  In other words, using way out-of-range
values is not an error to the kernel.  Certain values (like the
MACH_MSG_TYPE_*_SEND ones) require special handling, and all the
others are just passed through untouched by the kernel.

So it gets all the way to the recipient file system, which expects to
be getting a send right, but instead is getting something with the
ewacky type code 65536, and so it says "woah, type error", sends an
error back, and you get what you got (that is, MIG_BAD_ARGUMENTS, as
found in <mach/mig_errors.h>).

Thomas





reply via email to

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