Issue #16962 has been updated by jeremyevans0 (Jeremy Evans).

Backport deleted (2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN)
Subject changed from IO.close behaviour to Make IO.for_fd autoclose option default to false
Tracker changed from Bug to Feature

I looked into this and I think it's because stdin, stdout, and stderr are special cased:

```c
    if (IS_PREP_STDIO(fptr) || fd <= 2) {
        /* need to keep FILE objects of stdin, stdout and stderr */
    }
```

This Ruby program shows the expected behavior:

```ruby
out = STDOUT.dup
IO.for_fd(out.fileno, autoclose: true).close
out.puts "Hello World"
```

output:

```
-:3:in `write': Bad file descriptor @ io_writev - <STDOUT> (Errno::EBADF)
        from -:3:in `puts'
        from -:3:in `<main>'
```

I'm not sure it is worth documenting that `autoclose` does not affect stdin, stdout, or stderr.

I agree that `autoclose: false` is probably a better default.  However, that's a feature request and not a bug fix. Updating subject and switching to feature.

----------------------------------------
Feature #16962: Make IO.for_fd autoclose option default to false
https://bugs.ruby-lang.org/issues/16962#change-91745

* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
----------------------------------------
I discussed this with @eregon and I think the goal here is to try and figure out a way these interfaces can be a bit less confusing. 

## 1. I don't understand this behaviour:

```ruby
STDOUT.close
STDOUT.puts "Hello World"
# => closed stream
```

vs

```ruby
IO.for_fd(STDOUT.fileno, autoclose: true).close
STDOUT.puts "Hello World"
# => Hello World
```

## 2. `IO.for_fd(..., autoclose: true/false)`

The documentation for `autoclose` is:

> If the value is false, the fd will be kept open after this IO instance gets finalized.

But it also seems to affect `#close` - i.e. calling close does not close underlying file descriptor.

Should we fix the documentation or is the implementation wrong? Maybe the name `autoclose:` is very confusing. My initial interpretation was it was just 'automatically close this I/O when it is garbage collected'.

## 3. `IO.for_fd(..., autoclose: false)` default

In most cases, it seems like `autoclose: false` would make more sense as the default, since the file descriptor must come from some other place.




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>