From murdoch.duncan at gmail.com  Sun May 13 02:17:07 2012
From: murdoch.duncan at gmail.com (Duncan Murdoch)
Date: Sat, 12 May 2012 20:17:07 -0400
Subject: [Rd] Replacements for stdout and stderr guaranteed to be open
 in all versions of R
In-Reply-To: <1336858821.2294.39.camel@mabel>
References: <1336772199.2290.27.camel@mabel> <4FAD9473.8030306@gmail.com>
	<1336858821.2294.39.camel@mabel>
Message-ID: <4FAEFD83.3070400@gmail.com>

On 12-05-12 5:40 PM, David Sterratt wrote:
> On Fri, 2012-05-11 at 18:36 -0400, Duncan Murdoch wrote:
>> On 12-05-11 5:36 PM, David Sterratt wrote:
>>> Looking at
>>> http://svn.r-project.org/R/trunk/src/gnuwin32/system.c
>>> it would appear that R_Consolefile and R_Outputfile only point to open
>>> files when CharacterMode == RTerm, not in GUI mode.
>>>
>>> Therefore my question is, are there any replacements for stdout and
>>> stderr that work across all versions of R?
>>
>> I'm pretty sure the answer is "no".  What you can do is have your
>> initialization code open a new handle (pointing to something that is not
>> stdout, e.g. a file), and then pass that to the Qhull function.
>
> Thanks for your answer Duncan - it's lead me to the following solution,
> which seems to work even with mcapply() in the multicore package, which
> I thought might prove problematic.
>
> In every file that refers to stdout, include (via
>
> PKG_CPPFLAGS = -include myheader.h
>
> in the Makevars file):
>
>          /* myheader.h */
>          FILE * tmpstdout;
>          #undef stdout
>          #define stdout tmpstdout
>
> Then in the file in which the function_requiring_FILE(double arg, FILE *
> fp) is called:
>
>          /* myfile.h */
>          #include<Rembedded.h>           /* For R_tmpnam() */
>          #include<unistd.h>              /* For unlink() */
>
>          void my_function(double arg) {
>            const char *name;
>            name = R_tmpnam("Rf", R_TempDir);
>            tmpstdout = fopen(name, "w");
>            exitcode = function_requiring_FILE(arg, tmpstdout);
>            fclose(tmpstdout);
>            unlink(name);
>            free((char *) name);
>          }
>
> It's not exactly elegant, but it works for Linux, Mac and Windows (Rterm
> and Rgui). I suppose I could use defines to use R_Consolefile for
> platforms with Rinterface.h, but unless the above code is dangerous when
> there are multiple threads, I will stick with it.

I'm afraid I don't know enough about C++ to know if that's safe (or even 
sufficient).

Duncan Murdoch



[Rd] Replacements for stdout and stderr guaranteed to be open in all versions of R
Duncan Murdoch