> 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.