This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: uSTL hello world


[ NB Nick, see below... ]

John Dallaway wrote:
Uwe Kindler wrote:
If printf is not present in main, then both functions will not get
called for stdin and stdout and I think I now know why. In the ustl
package in ofstream.cpp the streams are not created because the streams
(cout, cin, cerr) are declared this way:

ifstream cin  (STDIN_FILENO);
ofstream cout (STDOUT_FILENO);
ofstream cerr (STDERR_FILENO);

That means they use the fileno to open the streams - they do not create
them. But the streams are not present, because no function uses stdout,
stdin, that means there are no references and the linker throws stdout
and stdin away. This is the reason why the static constructors of stdout
and stdin are never get called.

Here is my proposal to solve this problem. I changed the declaration of
cout, cin and cerr this way:

ifstream cin  (((Cyg_StdioStream *)stdin)->get_dev());
ofstream cout (((Cyg_StdioStream *)stdout)->get_dev());
ofstream cerr (((Cyg_StdioStream *)stderr)->get_dev());

This ensures that stdout, stdin and stderr are created. After this
change cyg_fd_assign() and cyg_fd_alloc() will get called if there is no
printf function in main.cpp. The call cout << "Hello world!\n" works
now. I noticed that the message is already printed before cout.flush()
is called. So it seems cout.flush() is not required if a proper serial
driver is used. If I use the diagnostic serial driver, then I always
needed to call cout.flush().

If you agree to my proposal then I will provide a patch.


Uwe, congratulations on tracking this down. Your analysis makes good sense.

Jifl, is there a preferred way to ensure initialisation of the stdio
streams in the file descriptor table? I note that open() in the file I/O
package uses:

    CYG_REFERENCE_OBJECT(stdin);
    CYG_REFERENCE_OBJECT(stdout);
    CYG_REFERENCE_OBJECT(stderr);

Is this addressing the same issue that we're observing with uSTL?

I think there's a more fundamental problem, not specific to uSTL (so I think Uwe's workaround isn't really appropriate). That is that something like:


write(STDOUT_FILENO, buf, n);

can't be guaranteed to just work, at present. That's a bug.

I think those CYG_REFERENCE_OBJECT lines (and surrounding ifdef) need to move out of open() and into cyg_fd_init(). Theoretically cyg_fp_get() would be slightly better, but that is called a lot, and there is a trivial but non-zero overhead to CYG_REFERENCE_OBJECT. I'd appreciate Nick's opinion on this proposal if possible though. It does mean that including the fileio package at all in a configuration would then guarantee pulling in stdin/stdout/stderr, even irrespective of use. Maybe the number of people this would affect is too small to care about. Maybe there should be a default-enabled option, to allow it to be turned off to remove that dependency.

Taking the usual principle of "leave it to the user", I think I'd personally lean towards the latter.

Jifl
--
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]