digitalmars.D.learn - Cannot call system funciton (stdout)
- Joel (7/7) Aug 15 2020 ../../JMiscLib/source/jmisc/base.d(176,2): Error: @safe function
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (18/26) Aug 16 2020 First, what's wrong with using writeln and friends instead of
- Steven Schveighoffer (6/34) Aug 16 2020 Technically, there's nothing unsafe about reading stdout, as long as you...
- Anonymouse (6/18) Aug 16 2020 Just as a drive-by comment, the main stdio thing I came across
- Joel (3/14) Aug 16 2020 Yeah, that's probably the only thing I've used 'stdout' for so
- Kagamin (3/8) Aug 17 2020 Cygwin terminals are not recognized as terminals, you should set
- Anonymouse (2/10) Sep 19 2020 How do I do this?
- Paul Backus (2/13) Sep 19 2020 http://dpldocs.info/experimental-docs/std.stdio.File.setvbuf.1.html
- Anonymouse (10/25) Sep 19 2020 Thanks.
- Adam D. Ruppe (10/12) Sep 19 2020 Part of the problem is the IDE console and cygwin too I believe
- Anonymouse (6/19) Sep 19 2020 Also makes sense, thanks. I already expose the option to force
- Paul Backus (17/30) Sep 19 2020 This isn't a druntime/Phobos thing, it's a libc thing. Phobos
- Anonymouse (5/10) Sep 19 2020 All right, thanks. Yes, currently I'm doing the TERM and uname
../../JMiscLib/source/jmisc/base.d(176,2): Error: safe function jmisc.base.upDateStatus!string.upDateStatus cannot call system function std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal /Library/D/dmd/src/phobos/std/stdio.d(4837,20): std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal is declared here I got around it by avoiding 'stdout'.
Aug 15 2020
On Saturday, 15 August 2020 at 23:59:36 UTC, Joel wrote:../../JMiscLib/source/jmisc/base.d(176,2): Error: safe function jmisc.base.upDateStatus!string.upDateStatus cannot call system function std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal /Library/D/dmd/src/phobos/std/stdio.d(4837,20): std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal is declared here I got around it by avoiding 'stdout'.First, what's wrong with using writeln and friends instead of directly mucking about with stdout? :p stdout is __gshared, so it's available on any thread at any time. That's not safe, so it's system. If you know you're not using stdout from multiple threads, or don't care (it might be perfectly safe even though it's possible to misuse), you can use this code: property File trustedStdout() trusted { return stdout; } That's a trusted wrapper that you can call from safe code. It's not actually safe though, as multiple threads could be using trustedStdout at the same time. In many use cases, this is unlikely to matter, but it's wroth keeping in mind. -- Simen
Aug 16 2020
On 8/16/20 6:07 AM, Simen Kjærås wrote:On Saturday, 15 August 2020 at 23:59:36 UTC, Joel wrote:Technically, there's nothing unsafe about reading stdout, as long as you are not setting it. Otherwise, writeln wouldn't be safe (as all it does is call a private trustedStdout). The whole thing is messy IMO, and should be revisited. -Steve../../JMiscLib/source/jmisc/base.d(176,2): Error: safe function jmisc.base.upDateStatus!string.upDateStatus cannot call system function std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal /Library/D/dmd/src/phobos/std/stdio.d(4837,20): std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal is declared here I got around it by avoiding 'stdout'.First, what's wrong with using writeln and friends instead of directly mucking about with stdout? :p stdout is __gshared, so it's available on any thread at any time. That's not safe, so it's system. If you know you're not using stdout from multiple threads, or don't care (it might be perfectly safe even though it's possible to misuse), you can use this code: property File trustedStdout() trusted { return stdout; } That's a trusted wrapper that you can call from safe code. It's not actually safe though, as multiple threads could be using trustedStdout at the same time. In many use cases, this is unlikely to matter, but it's wroth keeping in mind.
Aug 16 2020
On Sunday, 16 August 2020 at 10:07:02 UTC, Simen Kjærås wrote:On Saturday, 15 August 2020 at 23:59:36 UTC, Joel wrote:Just as a drive-by comment, the main stdio thing I came across that I couldn't do from within safe was stdout.flush(), which I need to call manually for Cygwin terminals and some terminals embedded in editors (vscode). If someone knows why, please tell me.../../JMiscLib/source/jmisc/base.d(176,2): Error: safe function jmisc.base.upDateStatus!string.upDateStatus cannot call system function std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal /Library/D/dmd/src/phobos/std/stdio.d(4837,20): std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal is declared here I got around it by avoiding 'stdout'.First, what's wrong with using writeln and friends instead of directly mucking about with stdout? :p
Aug 16 2020
On Sunday, 16 August 2020 at 18:13:07 UTC, Anonymouse wrote:On Sunday, 16 August 2020 at 10:07:02 UTC, Simen Kjærås wrote:Yeah, that's probably the only thing I've used 'stdout' for so far - flush.On Saturday, 15 August 2020 at 23:59:36 UTC, Joel wrote:Just as a drive-by comment, the main stdio thing I came across that I couldn't do from within safe was stdout.flush(), which I need to call manually for Cygwin terminals and some terminals embedded in editors (vscode). If someone knows why, please tell me.[...]First, what's wrong with using writeln and friends instead of directly mucking about with stdout? :p
Aug 16 2020
On Sunday, 16 August 2020 at 18:13:07 UTC, Anonymouse wrote:Just as a drive-by comment, the main stdio thing I came across that I couldn't do from within safe was stdout.flush(), which I need to call manually for Cygwin terminals and some terminals embedded in editors (vscode). If someone knows why, please tell me.Cygwin terminals are not recognized as terminals, you should set line buffered mode, then it will flush every line.
Aug 17 2020
On Tuesday, 18 August 2020 at 06:25:31 UTC, Kagamin wrote:On Sunday, 16 August 2020 at 18:13:07 UTC, Anonymouse wrote:How do I do this?Just as a drive-by comment, the main stdio thing I came across that I couldn't do from within safe was stdout.flush(), which I need to call manually for Cygwin terminals and some terminals embedded in editors (vscode). If someone knows why, please tell me.Cygwin terminals are not recognized as terminals, you should set line buffered mode, then it will flush every line.
Sep 19 2020
On Saturday, 19 September 2020 at 13:23:29 UTC, Anonymouse wrote:On Tuesday, 18 August 2020 at 06:25:31 UTC, Kagamin wrote:http://dpldocs.info/experimental-docs/std.stdio.File.setvbuf.1.htmlOn Sunday, 16 August 2020 at 18:13:07 UTC, Anonymouse wrote:How do I do this?Just as a drive-by comment, the main stdio thing I came across that I couldn't do from within safe was stdout.flush(), which I need to call manually for Cygwin terminals and some terminals embedded in editors (vscode). If someone knows why, please tell me.Cygwin terminals are not recognized as terminals, you should set line buffered mode, then it will flush every line.
Sep 19 2020
On Saturday, 19 September 2020 at 13:32:07 UTC, Paul Backus wrote:On Saturday, 19 September 2020 at 13:23:29 UTC, Anonymouse wrote:Thanks. I don't have a clone of druntime/Phobos available to me right now, so some follow-up questions. It looks like full buffering _IOFBF is the default setting, but "normal" non-Cygwin stdio certainly seems to do line buffering. Is it getting set to line buffering _IOLBF during initialisation of stdout? (Why then is Cygwin exempt?) Is there a way to detect programmatically if I'm in an environment where I need to manually set line buffering?On Tuesday, 18 August 2020 at 06:25:31 UTC, Kagamin wrote:http://dpldocs.info/experimental-docs/std.stdio.File.setvbuf.1.htmlOn Sunday, 16 August 2020 at 18:13:07 UTC, Anonymouse wrote:How do I do this?Just as a drive-by comment, the main stdio thing I came across that I couldn't do from within safe was stdout.flush(), which I need to call manually for Cygwin terminals and some terminals embedded in editors (vscode). If someone knows why, please tell me.Cygwin terminals are not recognized as terminals, you should set line buffered mode, then it will flush every line.
Sep 19 2020
On Saturday, 19 September 2020 at 13:56:53 UTC, Anonymouse wrote:Is there a way to detect programmatically if I'm in an environment where I need to manually set line buffering?Part of the problem is the IDE console and cygwin too I believe both *look* like a pipe to the program instead of like an interactive terminal, thus why it gets block instead of line buffered. Someone once told me of a trick to detect cygwin specifically but I can't access it right now and I'm not sure it would work reliably anyway.... Just yeah set your expectations low because if it was easy to tell programmatically the libc would already do it right.
Sep 19 2020
On Saturday, 19 September 2020 at 14:08:39 UTC, Adam D. Ruppe wrote:On Saturday, 19 September 2020 at 13:56:53 UTC, Anonymouse wrote:Also makes sense, thanks. I already expose the option to force flushing with a --flush command-line argument, so I guess I'll keep that around (but use setvbuf when the TERM/uname thing detects a whitelisted environment).Is there a way to detect programmatically if I'm in an environment where I need to manually set line buffering?Part of the problem is the IDE console and cygwin too I believe both *look* like a pipe to the program instead of like an interactive terminal, thus why it gets block instead of line buffered. Someone once told me of a trick to detect cygwin specifically but I can't access it right now and I'm not sure it would work reliably anyway.... Just yeah set your expectations low because if it was easy to tell programmatically the libc would already do it right.
Sep 19 2020
That said, full buffering for pipes may be not all that profitable, so it makes sense to always set line buffering for pipes and leave full buffering only for file.
Sep 19 2020
if(GetFileType(GetStdHandle(STD_OUTPUT_HANDLE))==FILE_TYPE_PIPE)setvbuf()
Sep 19 2020
On Saturday, 19 September 2020 at 13:56:53 UTC, Anonymouse wrote:On Saturday, 19 September 2020 at 13:32:07 UTC, Paul Backus wrote:This isn't a druntime/Phobos thing, it's a libc thing. Phobos just provides a wrapper around it. My guess is that libc uses something like `isatty(STDOUT_FILENO)` to determine if it should use line buffering, and that there's a bug in Cygwin that causes isatty() to always return false. If you want to know for sure, you can try looking through the Cygwin source code. [1]http://dpldocs.info/experimental-docs/std.stdio.File.setvbuf.1.htmlThanks. I don't have a clone of druntime/Phobos available to me right now, so some follow-up questions. It looks like full buffering _IOFBF is the default setting, but "normal" non-Cygwin stdio certainly seems to do line buffering. Is it getting set to line buffering _IOLBF during initialisation of stdout? (Why then is Cygwin exempt?)Is there a way to detect programmatically if I'm in an environment where I need to manually set line buffering?You can check the TERM environment variable [2], or you can use the POSIX uname() function [3] to see if you're running under Cygwin specifically. If there are any other environments where you need to manually set line-buffering, you'll probably have to check for those individually as well. [1] https://cygwin.com/git/gitweb.cgi?p=newlib-cygwin.git [2] https://cygwin.com/cygwin-ug-net/setup-env.html [3] https://stackoverflow.com/questions/3466166/how-to-check-if-running-in-cygwin-mac-or-linux
Sep 19 2020
On Saturday, 19 September 2020 at 14:14:46 UTC, Paul Backus wrote:You can check the TERM environment variable [2], or you can use the POSIX uname() function [3] to see if you're running under Cygwin specifically. If there are any other environments where you need to manually set line-buffering, you'll probably have to check for those individually as well.All right, thanks. Yes, currently I'm doing the TERM and uname thing on program start and flushing manually after every writeln if I detected Cygwin or vscode. I think I can work with this.
Sep 19 2020