www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - disabling and enabling console output

reply Alex <AJ gmail.com> writes:
I have some code that disables the console because some other 
code puts junk on it that I don't want to see... then I enable it.

stdout.close();
stderr.close();

...
stdout.open("CON", "w");
stderr.open("CON", "w");

It works but when the routine that uses this is called twice, it 
completely disables all output afterwards.

//1
stdout.close();
stderr.close();
//2
stdout.open("CON", "w");
stderr.open("CON", "w");
//3
stdout.close();
stderr.close();
//4
stdout.open("CON", "w");
stderr.open("CON", "w");
//5


So, one gets output at 1 and 3 but not 5.

Am I doing something wrong or is this a bug?


I've tried various things such as saving and restoring stdout, 
using CONOUT$, etc...

I think it might be outputting in 3 because of caching rather 
than it actually working once.

Can play around with it here:

https://run.dlang.io/is/q3kpSB
May 16 2019
next sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Thursday, 16 May 2019 at 14:53:14 UTC, Alex wrote:
 I have some code that disables the console because some other 
 code puts junk on it that I don't want to see... then I enable 
 it.
One thing you could try is going one level lower, and using dup() to save the stream to another fd, close() to close the stdout one, and dup2() to restore the saved fd over the stdout one.
May 16 2019
parent reply Alex <AJ gmail.com> writes:
On Thursday, 16 May 2019 at 15:21:48 UTC, Vladimir Panteleev 
wrote:
 On Thursday, 16 May 2019 at 14:53:14 UTC, Alex wrote:
 I have some code that disables the console because some other 
 code puts junk on it that I don't want to see... then I enable 
 it.
One thing you could try is going one level lower, and using dup() to save the stream to another fd, close() to close the stdout one, and dup2() to restore the saved fd over the stdout one.
Unfortunately D doesn't seem to have dup, dup2. On 05/10/14 22:24, MarisaLovesUsAll via Digitalmars-d-learn wrote:
 I sometimes got a useless messages in stdout from SDL_Image 
 library, and I want to temporary silence it. How do I do?
One way would be something like: import std.stdio; void writeOutput () { static c = 1; printf("%d\n", c++); } void main() { writeOutput(); { auto ex = PushFD!1("/dev/null".ptr); writeOutput(); } writeOutput(); } struct PushFD(int fd) { import core.sys.posix.fcntl, core.sys.posix.unistd; int old; this(const char* fn) { // old = dup(fd); auto nfd = open(fn, O_RDWR); dup2(nfd, fd); close(nfd); } ~this() { dup2(old, fd); close(old); } } // In real code you'll want to check for errors from dup/dup2/open/close. artur That code fails to compile on windows.
May 16 2019
parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Thursday, 16 May 2019 at 17:05:01 UTC, Alex wrote:
 One thing you could try is going one level lower, and using 
 dup() to save the stream to another fd, close() to close the 
 stdout one, and dup2() to restore the saved fd over the stdout 
 one.
Unfortunately D doesn't seem to have dup, dup2.
They are in the C library. Looks like Druntime has D declarations only for Posix: https://github.com/cybershadow/druntime/blob/issue19433/src/core/sys/posix/unistd.d#L51-L52 You can just copy those.
May 16 2019
parent reply Alex <AJ gmail.com> writes:
On Thursday, 16 May 2019 at 17:07:39 UTC, Vladimir Panteleev 
wrote:
 On Thursday, 16 May 2019 at 17:05:01 UTC, Alex wrote:
 One thing you could try is going one level lower, and using 
 dup() to save the stream to another fd, close() to close the 
 stdout one, and dup2() to restore the saved fd over the 
 stdout one.
Unfortunately D doesn't seem to have dup, dup2.
They are in the C library. Looks like Druntime has D declarations only for Posix: https://github.com/cybershadow/druntime/blob/issue19433/src/core/sys/posix/unistd.d#L51-L52 You can just copy those.
adding int dup(int) trusted; int dup2(int, int) trusted; int close(int) trusted; int open(in char*, int, ...) trusted; results in an unresolved symbol.
May 16 2019
parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Thursday, 16 May 2019 at 17:18:01 UTC, Alex wrote:
 adding

 	int dup(int)  trusted;
 	int dup2(int, int)  trusted;
 	int close(int)  trusted;
 	int open(in char*, int, ...)  trusted;
Be sure to make them extern(C). Sorry, I haven't tried it, I'm guessing that it should work based on: https://github.com/digitalmars/dmc/blob/master/include/io.h#L142-L147
May 16 2019
parent reply Alex <AJ gmail.com> writes:
On Thursday, 16 May 2019 at 17:19:13 UTC, Vladimir Panteleev 
wrote:
 On Thursday, 16 May 2019 at 17:18:01 UTC, Alex wrote:
 adding

 	int dup(int)  trusted;
 	int dup2(int, int)  trusted;
 	int close(int)  trusted;
 	int open(in char*, int, ...)  trusted;
Be sure to make them extern(C). Sorry, I haven't tried it, I'm guessing that it should work based on: https://github.com/digitalmars/dmc/blob/master/include/io.h#L142-L147
Ok, the issue is because I was adding import core.stdc.stdio, core.stdc.stdio; extern (C): system: nothrow: nogc: static int _dup(int); static int dup2(int, int); directly inside the PushFD struct... I marked them static and it still didn't help. I don't know it's adding the class for the lookup: PushFD!(1).PushFD.dup2(int, int)" (_D3mM__T6PushFDVii1ZQm4dup2UNbNiiiZi) Unfortunately the code is crashing because _open or _sopen is returning -1 for /dev/null Works fine nul, NUL, and CONOUT$ but does not block the output. I'm not sure if they are failing to block or if they are blocking what is being opened(and not the original console). That is, do I need to not open and simply close stdout?
May 16 2019
parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Thursday, 16 May 2019 at 17:42:17 UTC, Alex wrote:
 I'm not sure if they are failing to block or if they are 
 blocking what is being opened(and not the original console). 
 That is, do I need to not open and simply close stdout?
Yes, I see. It won't work because the two libraries are using different C standard libraries, so, SDLImage can't see that the FD was dup'd, and the DM C library most likely doesn't also dup/close the Windows handle. I'm not sure how to do this on Windows, then; maybe someone with more experience would know. Windows has DuplicateHandle, but no equivalent for dup2 that I know of, which would be needed to restore stdin using this method.
May 16 2019
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 16 May 2019 at 14:53:14 UTC, Alex wrote:
 I have some code that disables the console because some other 
 code puts junk on it that I don't want to see
soooo stupid question but can't you just edit the other code to not put junk on it? Maybe there is some other approach we can try out.
May 16 2019
parent Alex <AJ gmail.com> writes:
On Thursday, 16 May 2019 at 17:49:24 UTC, Adam D. Ruppe wrote:
 On Thursday, 16 May 2019 at 14:53:14 UTC, Alex wrote:
 I have some code that disables the console because some other 
 code puts junk on it that I don't want to see
soooo stupid question but can't you just edit the other code to not put junk on it?
No, it is in an external lib and I'd have to mod the code, maintain it, and compile it... should be much simpler just to redirect stdout. In fact, it works, I just can figure out how to re-enable it.
May 16 2019