[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: