On Mon, Dec 06, 2004 at 04:08:29PM +0900, Tanaka Akira wrote:
> In article <20041204195115.GA83981 / lizzy.catnook.com>,
>   Jos Backus <jos / catnook.com> writes:
> 
> > Another question... How do I access the File open mode ("w" in this case) on a
> > File object?  Example:
> 
> % ruby -rfcntl -e '
> open("/dev/null") {|f| p f.fcntl(Fcntl::F_GETFL) & Fcntl::O_ACCMODE }
> open("/dev/null", "w") {|f| p f.fcntl(Fcntl::F_GETFL) & Fcntl::O_ACCMODE }
> open("/dev/null", "r+") {|f| p f.fcntl(Fcntl::F_GETFL) & Fcntl::O_ACCMODE }
> '
> 0
> 1
> 2
> 
> 0 means O_RDONLY.  1 means O_WRONLY.  2 means O_RDWR.
> 
> I don't know this is portable enough.
 
This is good enough for my purposes (it only needs to run on Linux), thanks.

Otoh, how about creating an IO.mode instance method that returns the opposite
of what rb_io_mode_flags() produces? rb_io_mode_flags() turns a mode string
into a flags value which OR's some FMODE_* constants. What if we would have a
method which would take fptr->mode and return this as a String?  It would be
as portable as Ruby's idea of the file's mode. If there's interest, I can whip
up a patch which should be pretty small.

> Note that this doesn't work for duplex pipe.
> 
> % ruby -rfcntl -e '
> open("|echo", "r+") {|f| p f.fcntl(Fcntl::F_GETFL) & Fcntl::O_ACCMODE }
> '
> 0

Okay. I also notice this asymmetry:

irb(main):001:0> require 'fcntl'
=> true
irb(main):002:0> open("|echo", "r") {|f| p f.fcntl(Fcntl::F_GETFL) & Fcntl::O_ACCMODE }
2
=> nil
irb(main):003:0> open("|echo", "w") {|f| p f.fcntl(Fcntl::F_GETFL) & Fcntl::O_ACCMODE }
2

=> nil
irb(main):004:0> open("echo|", "r") {|f| p f.fcntl(Fcntl::F_GETFL) & Fcntl::O_ACCMODE }
0
=> nil
irb(main):005:0> open("echo|", "w") {|f| p f.fcntl(Fcntl::F_GETFL) & Fcntl::O_ACCMODE }
1
=> nil
irb(main):006:0> 

Thanks!

-- 
Jos Backus                       _/  _/_/_/      Sunnyvale, CA
                                _/  _/   _/
                               _/  _/_/_/
                          _/  _/  _/    _/
jos at catnook.com        _/_/   _/_/_/          require 'std/disclaimer'