The R Project SVN R

Rev

Rev 73630 | Rev 83755 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 73630 Rev 75824
Line 1... Line 1...
1
/*
1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
4
 *  Copyright (C) 1997--2017  The R Core Team
4
 *  Copyright (C) 1997--2018  The R Core Team
5
 *
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
9
 *  (at your option) any later version.
Line 173... Line 173...
173
{
173
{
174
    return 1.0 / 100.0;
174
    return 1.0 / 100.0;
175
}
175
}
176
 
176
 
177
/*
177
/*
-
 
178
 * Stderr, Stdout
-
 
179
 *   =FALSE .. drop output
-
 
180
 *   =TRUE  .. return output
-
 
181
 *   =""    .. print to standard error/output
-
 
182
 *   =fname .. redirect to file of that name
-
 
183
 *
-
 
184
 * Redirection and dropping is supported with all flag values. Printing is
-
 
185
 * supported with all flag values on non-RGui only (and happens via standard
-
 
186
 * handles). For returning output (anywhere) and printing (on RGui),
-
 
187
 * restrictions apply (below).
-
 
188
 * 
178
 * flag =0 don't wait/ignore stdout
189
 * flag =0 don't wait
-
 
190
 *   returning of output not supported
-
 
191
 *   RGui: non-redirected standard error and standard output always dropped
-
 
192
 *         (printing not supported)
-
 
193
 *
-
 
194
 * flag =1 wait
-
 
195
 *   otherwise like flag =0
-
 
196
 *
179
 * flag =1 wait/ignore stdout
197
 * flag =2 wait/printing in RGui
180
 * flag =2 wait/copy stdout to the console
198
 *   returning of output not supported
-
 
199
 *   non-RGui: works like flag =1
-
 
200
 *   RGui: standard error and/or standard output is printed on console;
-
 
201
 *         flag=2 may only be used when at least one of the outputs
-
 
202
 *         is to be printed
-
 
203
 *
181
 * flag =3 wait/return stdout (intern=TRUE)
204
 * flag =3 wait/return output
-
 
205
 *   standard error and/or standard output is returned
-
 
206
 *   flag=3 may only be used when at least one of the outputs is to be returned
-
 
207
 *   RGui: printing is not supported (one cannot return one output and print
-
 
208
 *         the other)
-
 
209
 * 
182
 * Add 10 to minimize application
210
 * Add 10 to flag to minimize application
183
 * Add 20 to make application "invisible"
211
 * Add 20 to flag make application "invisible"
184
*/
212
*/
185
 
213
 
186
#include "run.h"
214
#include "run.h"
187
 
215
 
188
#define INTERN_BUFSIZE 8096
216
#define INTERN_BUFSIZE 8096
Line 191... Line 219...
191
    rpipe *fp;
219
    rpipe *fp;
192
    char  buf[INTERN_BUFSIZE];
220
    char  buf[INTERN_BUFSIZE];
193
    const char *fout = "", *ferr = "";
221
    const char *fout = "", *ferr = "";
194
    int   vis = 0, flag = 2, i = 0, j, ll = 0;
222
    int   vis = 0, flag = 2, i = 0, j, ll = 0;
195
    SEXP  cmd, fin, Stdout, Stderr, tlist = R_NilValue, tchar, rval;
223
    SEXP  cmd, fin, Stdout, Stderr, tlist = R_NilValue, tchar, rval;
-
 
224
    PROTECT_INDEX ti;
196
    int timeout = 0, timedout = 0;
225
    int timeout = 0, timedout = 0;
197
 
226
 
198
    checkArity(op, args);
227
    checkArity(op, args);
199
    cmd = CAR(args);
228
    cmd = CAR(args);
200
    if (!isString(cmd) || LENGTH(cmd) != 1)
229
    if (!isString(cmd) || LENGTH(cmd) != 1)
Line 246... Line 275...
246
		    flag, vis, CHAR(STRING_ELT(fin, 0)), fout, ferr,
275
		    flag, vis, CHAR(STRING_ELT(fin, 0)), fout, ferr,
247
		    timeout, &timedout);
276
		    timeout, &timedout);
248
	if (ll == NOLAUNCH) warning(runerror());
277
	if (ll == NOLAUNCH) warning(runerror());
249
    } else {
278
    } else {
250
	/* read stdout +/- stderr from pipe */
279
	/* read stdout +/- stderr from pipe */
251
	int m = 0;
280
	int m = -1;
252
	if(flag == 2 /* show on console */ || CharacterMode == RGui) m = 3;
281
	if ((TYPEOF(Stderr) == LGLSXP && asLogical(Stderr)) ||
253
	if(TYPEOF(Stderr) == LGLSXP)
282
	   (CharacterMode == RGui && TYPEOF(Stderr) == STRSXP && ferr && !ferr[0]))
254
	    m = asLogical(Stderr) ? 2 : 0;
283
	    /* read stderr from pipe */
-
 
284
	    m = 2;
255
	if(m  && TYPEOF(Stdout) == LGLSXP && asLogical(Stdout)) m = 3;
285
	if ((TYPEOF(Stdout) == LGLSXP && asLogical(Stdout)) ||
-
 
286
	    (CharacterMode == RGui && TYPEOF(Stdout) == STRSXP && fout && !fout[0]))
-
 
287
	    /* read stdout from pipe */
-
 
288
	    m = (m == 2) ? 3 : 0;
-
 
289
	if (m == -1)
-
 
290
	    /* does not happen with system()/system2() */
-
 
291
	    error(_("invalid %s argument"), "flag");
-
 
292
 
256
	fp = rpipeOpen(CHAR(STRING_ELT(cmd, 0)), getCharCE(STRING_ELT(cmd, 0)),
293
	fp = rpipeOpen(CHAR(STRING_ELT(cmd, 0)), getCharCE(STRING_ELT(cmd, 0)),
257
		       vis, CHAR(STRING_ELT(fin, 0)), m, fout, ferr, timeout);
294
		       vis, CHAR(STRING_ELT(fin, 0)), m, fout, ferr, timeout);
258
	if (!fp) {
295
	if (!fp) {
259
	    /* If intern = TRUE generate an error */
296
	    /* If intern = TRUE generate an error */
260
	    if (flag == 3) error(runerror());
297
	    if (flag == 3) error(runerror());
261
	    ll = NOLAUNCH;
298
	    ll = NOLAUNCH;
262
	} else {
299
	} else {
263
	    /* FIXME: use REPROTECT */
-
 
264
	    if (flag == 3) {
300
	    if (flag == 3) { /* intern */
265
		PROTECT(tlist);
301
		PROTECT_WITH_INDEX(tlist, &ti);
266
		/* honour intern = FALSE, ignore.stdout = TRUE */
-
 
267
		if (m > 0 ||
-
 
268
		    (!(TYPEOF(Stdout) == LGLSXP && !asLogical(Stdout))))
-
 
269
		    for (i = 0; rpipeGets(fp, buf, INTERN_BUFSIZE); i++) {
302
		for (i = 0; rpipeGets(fp, buf, INTERN_BUFSIZE); i++) {
270
			ll = strlen(buf) - 1;
303
		    ll = strlen(buf) - 1;
271
			if ((ll >= 0) && (buf[ll] == '\n')) buf[ll] = '\0';
304
		    if ((ll >= 0) && (buf[ll] == '\n')) buf[ll] = '\0';
272
			tchar = mkChar(buf);
305
		    tchar = mkChar(buf);
273
			UNPROTECT(1); /* tlist */
-
 
274
			PROTECT(tlist = CONS(tchar, tlist));
306
		    REPROTECT(tlist = CONS(tchar, tlist), ti);
275
		    }
307
		}
276
 
-
 
277
	    } else {
308
	    } else { /* print on RGui console */
278
		for (i = 0; rpipeGets(fp, buf, INTERN_BUFSIZE); i++)
309
		for (i = 0; rpipeGets(fp, buf, INTERN_BUFSIZE); i++)
279
		    R_WriteConsole(buf, strlen(buf));
310
		    R_WriteConsole(buf, strlen(buf));
280
	    }
311
	    }
281
	    ll = rpipeClose(fp, &timedout);
312
	    ll = rpipeClose(fp, &timedout);
282
	}
313
	}
Line 297... Line 328...
297
	}
328
	}
298
	if(ll) {
329
	if(ll) {
299
	    SEXP lsym = install("status");
330
	    SEXP lsym = install("status");
300
	    setAttrib(rval, lsym, ScalarInteger(ll));
331
	    setAttrib(rval, lsym, ScalarInteger(ll));
301
	}
332
	}
302
	UNPROTECT(2);
333
	UNPROTECT(2); /* tlist, rval */
303
	return rval;
334
	return rval;
304
    } else {
335
    } else {
305
	rval = ScalarInteger(ll);
336
	rval = ScalarInteger(ll);
306
	R_Visible = 0;
337
	R_Visible = 0;
307
	return rval;
338
	return rval;