[openbeosnetteam] Re: Integration Q's
- From: philippe.houdoin@xxxxxxx
- To: openbeosnetteam@xxxxxxxxxxxxx
- Date: Mon, 18 Feb 2002 17:29:57 +0100 (MET)
> I am not really sure how fds are managed (i.e. how they are
> created/destroyed), but I guess that if we are really able
> to associate an fd with a socket call (being it via /dev/socket
> or whatever) the implementation of everything else should be
> straight forward.
An fd is associate by BeOS kernel vfs layer for each open() made on a fs node.
As /dev is a fs too (devfs), any /dev/* leaf would have a fd for each open()
made on it.
It works like this at least under BeOS, last time I check, it was near the same
for NewOS... except that NewOS let driver add a new /dev/* entry any time he
want to, when BeOS only let him doing this at init time...
> There is only one caveat I can think of... The select() call. If I am not
> mistaken, select() does not work on file descriptors (or is it sockets) in
> BeOS R5.
I guess it's *BeOS net_served* sockets only, mostly because net_server's
libnet.so don't implement it properly.
Based on /boot/develop/headers/be/drivers/Drivers.h, each kernel driver can
publish any /dev/* paths they want, and bind same or different callbacks for
these *features*:
typedef struct {
device_open_hook open; /* called to open the device */
device_close_hook close; /* called to close the device */
device_free_hook free; /* called to free the cookie */
device_control_hook control; /* called to control the device */
device_read_hook read; /* reads from the device */
device_write_hook write; /* writes to the device */
device_select_hook select; /* start select */
device_deselect_hook deselect; /* stop select */
device_readv_hook readv; /* scatter-gather read from the device */
device_writev_hook writev; /* scatter-gather write to the device */
} device_hooks;
So, select() handling *should* works. AFAIR, it was introduced in BeOS R4 new
drivers API... (version 2)
But I don't know how these [de]select_hook works, as I never need to implement
them in my drivers so far...
> I am not sure if we can change that by rolling out our own select()
> implementation... Where is it implemented in BeOS? libroot.so?
select(), like all POSIXish support is in libroot.so, and rely on kernel calls,
I bet.
Maybe it could help here to look at BONE architecture
(http://www.befaqs.com/mirror/classic-be/aboutbe/benewsletter/volume_IV/Issue05.html#Insight),
because we could see that even Be Inc. choose the driver-way to *implement*
sockets as filedescriptors:
---- 8< ----------
All networking functionality visible to user programs is provided by libsocket,
which is a very thin library that opens a driver (which provides the socket
"file descriptor") and communicates with it via ioctls to provide the
networking API. The net API driver instantiates the internal data structures
associated with a socket (the bone_endpoint_t), sets up the protocol stack for
each socket, and handles all communication between the socket and the stack.
---- 8< ----------
Look at a BONIfied system under
/boot/beos/system/add-ons/kernel/drivers/dev/net/bone_api_driver, which publish
the /dev/net/api entry on which rely the BSD API provided by BONE's
libsocket.so library.
This BSD API open("/dev/net/api") to create a new socket, and then call ioctl()
on it to set socket options, bind a address, listen, etc. the read() and
write() call provided by the socket driver are simply redirect to internal
send() and recv()...
Look at /boot/develop/headers/be/bone/bone_api.h to see the libsocket.so <->
/dev/net/api bone driver protocol.
Obviously, because BONE *real* stack is in kernel land too, is far easer for
the bone_api_driver to communicate with bottom stack, by loading and calling
right BONE modules. There is also only one userland<->kernel switch context
when packets pass up or down the network stack...
With currend, userland based, OBOS net_server architecture, it will involve
some other kind of communication between /dev/net/socket|api|whatever_you_want
and the net_server.
Shared_memories (create_area/clone_area) would be a way to do it I guess, plus
some semaphores to notify the net_server...
Never an easy thing to do :-(
-Philippe.
Other related posts: