On Sun, 20 Jun 2010 14:19:29 +0200, Martin Pohlack wrote:
-- like in term_con_test example for term_con server, the 3, 4, 5 descriptors are returned from open().
As there is no real fork support in l4vfs, I implemented special parameters which are evaluated and eaten before main() is executed in pkg/l4vfs/lib/libc_backends/io/operations.c:init_io(). These parameters trigger the open to the VCs for you (--stdin, --stdout, --stderr).
I checked init_io(), it seems to do the same as a fragment in term_con_test example -- it opens a terminal device and checks the file descriptors to be 0, 1, 2 (with unessential details). I forgot to mention that my program is an API server which implements an API and starts a client program using that API. I load the client program, all needed libraries for it. Then I start a function called trampoline() in a separate task, prepare an environment for the program in that function (including file descriptors). Then I just setup registers, push params for C startup code on stack, and call an entry point in a client program.
I tried to add "--stdin /dev/vc0" to API server's command line. The init_io() function opens all file descriptors successfully. Then these file descriptors seem to be inherited by a client program (if I try to open /dev/vc0 in trampoline(), it returns a fd equal to 3, 4, 5, so 0, 1, 2 are already used). But when I try calling read(0, ...); (I call it in the API call from the client program, so the task id at the moment is from the client program) it says that
os2serve| api_DosRead(): threadid: 11.0 os2serve| read(): fd = '0', buf = '0x0001afd0', count = '1'' term_con| l4vfs_common_io_read_component(): invalid read request - not owning o term_con: bject
and so on many times. I think it is because of the task number different from the API server one. (file descriptors are owned by server, not a client program).
Also, I tried to close all file descriptors (0, 1, 2) before opening them at the start of trampoline(). It fails:
os2serve| close(): local fd '0' os2serve| close(): server ret os2serve| close(): Error in close, unknown case! os2serve| close(): local fd '1' os2serve| close(): server ret os2serve| close(): Error in close, unknown case! os2serve| close(): local fd '2' os2serve| l4_exec_lx(): l4ts_create_task() returned: 0, taskid=11.0 os2serve| close(): server ret os2serve| close(): Error in close, unknown case!
No idea, why the LOG tag is 'os2server' -- it executes in the separate task.
I also tried to add init_io() call at the start of trampoline() but have no idea how to pass it the command line with --stdin, --stdout, --stderr arguments -- when a program is started via roottask, it gets its command line from GRUB command line passed through bootinfo structure. But what to do if I start task via task server?
If I not use term_con at all, and not open vc0 three times as above, read(0, ....); and write(1,....); works but strangely. For example, read() returns immediately with no error and returns a single symbol (EOF, I think). But as I tested in Linux and OS/2 operating systems, when stdin is a console, read(0,...); must block until '\n' is returned (user pressed an Enter key).
Not sure what happens here, IIRC, dietlibc behaved a bit strange when printf etc. was used on invalid FDs. These days you will probably be using uclibc, right? Maybe you are using the minimal_io backend, this may just ignore reads.
Yes, I use uCLibc. But minimal_io is not used here. I checked the linker line, it states that it links with c_be_io.o.a.
I haven't touched the source in the last two years, maybe others have a more current view on things?
Yes, I think l4vfs is a promising area. I plan trying to write a filesystem support layer for OS/2 IFS API, probably as an l4vfs server with libraries-plugins implementing different filesystems. At the first stage, it will be a ramdisk with ramfs format. Also, probably, a configuration namespace (registry) like in IBM's WorkplaceOS, could be implemented using l4vfs.
WBR, valery