www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Cannot call system funciton (stdout)

reply Joel <joelcnz gmail.com> writes:
../../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
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
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
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/16/20 6:07 AM, Simen Kjærås wrote:
 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.
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
Aug 16 2020
prev sibling parent reply Anonymouse <zorael gmail.com> writes:
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:
 ../../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
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.
Aug 16 2020
next sibling parent Joel <joelcnz gmail.com> writes:
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:
 On Saturday, 15 August 2020 at 23:59:36 UTC, Joel wrote:
 [...]
First, what's wrong with using writeln and friends instead of directly mucking about with stdout? :p
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.
Yeah, that's probably the only thing I've used 'stdout' for so far - flush.
Aug 16 2020
prev sibling parent reply Kagamin <spam here.lot> writes:
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
parent reply Anonymouse <zorael gmail.com> writes:
On Tuesday, 18 August 2020 at 06:25:31 UTC, Kagamin wrote:
 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.
How do I do this?
Sep 19 2020
parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 19 September 2020 at 13:23:29 UTC, Anonymouse wrote:
 On Tuesday, 18 August 2020 at 06:25:31 UTC, Kagamin wrote:
 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.
How do I do this?
http://dpldocs.info/experimental-docs/std.stdio.File.setvbuf.1.html
Sep 19 2020
parent reply Anonymouse <zorael gmail.com> writes:
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:
 On Tuesday, 18 August 2020 at 06:25:31 UTC, Kagamin wrote:
 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.
How do I do this?
http://dpldocs.info/experimental-docs/std.stdio.File.setvbuf.1.html
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?
Sep 19 2020
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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
parent reply Anonymouse <zorael gmail.com> writes:
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:
 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.
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).
Sep 19 2020
parent reply Kagamin <spam here.lot> writes:
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
parent Kagamin <spam here.lot> writes:
if(GetFileType(GetStdHandle(STD_OUTPUT_HANDLE))==FILE_TYPE_PIPE)setvbuf()
Sep 19 2020
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
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:
 http://dpldocs.info/experimental-docs/std.stdio.File.setvbuf.1.html
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?)
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]
 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
parent Anonymouse <zorael gmail.com> writes:
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