l4vfs and stdin/stdout handles
mp26 at os.inf.tu-dresden.de
Fri Jul 2 10:25:03 CEST 2010
sorry for the delay, I was a little busy in the last days.
On 22.06.2010 22:35, Valery V. Sedletski wrote:
> On Mon, 21 Jun 2010 17:29:00 +0200, Martin Pohlack wrote:
>>> 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 think it is not so easy to transfer these FDs into another task, as
>> server state is associated with many FDs (depending on the server).
> Yes, transfer to another task is difficult but I meant to execute the same startup code as in init_io() but for client task, not a server.
> Now I specified '--stdin /dev/vc0 --stdout /dev/vc0 --stderr /dev/vc0' in server command line and mounted term_con at /dev. -- After that
> I got one l4con tab opened and all terminal i/o got in there. So, it works but the server owns the terminal. But it is desirable to do the same
> for client program. I start it using task server, so I cannot specify command line, so I must init terminal i/o other way.
I did a quick check how to specify command lines and didn't find a way.
I have probably overlooked it. Can others jump in here?
>>> 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
> I changed now the app behaviour, so all terminal reads and writes are performed in server stub but not in the context of a client. The server
> owns a terminal and works with it. But it is not the intended way. Of course, I need each client program have its own std* file descriptors.
>> I looked again in operations.c:init_io()
>> If you do not provide "--stdin x" etc. argument, dummy FDs are put into
>> place in the local FD table, e.g., here:
>> ft_fill_entry(1, file_desc); // fill in dummy entry
>> I vaguely recall doing this to prevent accidents with printf() etc. in
>> dietlibc which had no error checking regarding invalid FDs. I have not
>> revisited this code since we switched to uclibc years ago ...
> So, they're just dummy. I didn't know that ft_fill_entry() fills the local descriptor table. So, it is also needed besides just open()'ing it. But how can I
> get the file descriptor got from open() to be in a range of 0..2? It seems they are already predefined at the moment, though are dummy..
No, open uses ft_fill_entry(). But open will not reuse FDs marked as
in-use (as done by ft_fill_entry()).
* Have you tried closing them?
* Have you tried dup2()ing into them?
* You can always modify the library code to not reserve these special
FDs if you want to.
I probably cannot give you any more detailed information regarding this
problem as I stopped developing l4vfs about 2 years ago. Maybe a
current maintainer will jump into the discussion here ...
Alternatively, the Dresden L4 group released a new userland version
which may be supported more actively. Maybe this is an alternative for you?
More information about the l4-hackers