HenrikBengtsson / Wishlist-for-R

Features and tweaks to R that I and others would love to see - feel free to add yours!
https://github.com/HenrikBengtsson/Wishlist-for-R/issues
GNU Lesser General Public License v3.0
134 stars 4 forks source link

Rscript -e EXPR fails to launch if stdin is closed #140

Closed HenrikBengtsson closed 2 years ago

HenrikBengtsson commented 2 years ago

Issue

Rscript fails to launch if the standard input (stdin) is closed, e.g.

## 0<&- closes the standard input
$ Rscript --vanilla -e 42 0<&-
Fatal error: creating temporary file for '-e' failed

One rationale for having closed standard files (including stdin) is to avoid leaking file descriptors, cf. https://wiki.sei.cmu.edu/confluence/display/c/FIO22-C.+Close+files+before+spawning+processes and https://danwalsh.livejournal.com/53603.html.

Wish(?)

Can Rscript be updated to handle the case when stdin is closed?

Troubleshooting

$ strace Rscript --vanilla -e 42 0<&-
execve("/home/hb/shared/software/CBI/R-4.2.1-gcc9/bin/Rscript", ["Rscript", "--vanilla", "-e", "42"], 0x7fff9f476418 /* 147 vars */) = 0
brk(NULL)                               = 0x5625ca9e6000
arch_prctl(0x3001 /* ARCH_??? */, 0x7fff23b4d260) = -1 EINVAL (Invalid argument)
...
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
write(1, "Fatal error: creating temporary "..., 53Fatal error: creating temporary file for '-e' failed
) = 53
exit_group(2)                           = ?
+++ exited with 2 +++

This happens in src/unix/system.c:

    ifd = mkstemp(ifile);
    if (ifd > 0)
        ifp = fdopen(ifd, "w+");
    if(!ifp) R_Suicide(_("creating temporary file for '-e' failed"));

Rscript script.R works fine when stdin is closed;

$ echo "42" > script.R
$ Rscript --vanilla script.R 0<&-
[1] 42

and so does R;

$ R --quiet --vanilla 0<&-
> 

Background

/ht Gábor Csárdi

HenrikBengtsson commented 2 years ago

Posted to R-devel thread 'Rscript -e EXPR fails to launch if stdin is closed' on 2022-10-09 (https://stat.ethz.ch/pipermail/r-devel/2022-October/082084.html).

HenrikBengtsson commented 2 years ago

Yes, a bug in R;

On Mon, Oct 10, 2022 at 2:07 AM peter dalgaard wrote: ...

Yes, that looks like a blunder.

mkstemp() returns -1 on failure, not 0, so the test on ifd (and I suppose also the one on ifp) is wrong. And of course, once you close file descriptor 0, mkstemp() chooses the 1st available fd, i.e. 0, for its return value.

and a bit later:

It seems to work simply to do "if (ifd >= 0)..." (the ifp test is fine since ifp is FILE* and initialized to NULL). Will commit (to r-devel for now).

Now fixed in R-devel r83051 (https://github.com/wch/r-source/commit/97b3dfb71aeff4a6acb72d400bb1fba8e6b2ed37).

HenrikBengtsson commented 2 years ago

Now also in R-patch (to become R 4.2.2), cf. https://github.com/wch/r-source/commit/ab754c2f6581c81c687ba4115d32e80e0da9fabb