Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

open(): Is there a simple way to map between numeric open modes and "symbol modes"? (solved)

by isync (Hermit)
on Feb 07, 2013 at 23:27 UTC ( #1017733=perlquestion: print w/ replies, xml ) Need Help??
isync has asked for the wisdom of the Perl Monks concerning the following question:

I've got a problem (with IPC::PerlSSH::IO): somehow numeric mode values doesn't seem to work, while their symbol equivalents work. Now, as I'm doing Fuse work here, I get proper numeric mode values as "open-requests" and have to pass these on to IPC::PerlSSH::IO::open(), an open-implementation that only accepts the symbolized form, as it seems.

Is there any way to convert between numeric<->symbols? (As mocked up in "magig_func" below)?
my $symbols = magic_func(some numeric mode value);        # $symbols set to '<', for "read"
my $symbols = magic_func(another numeric mode value);     # $symbols set to '>', for "write"
my $symbols = magic_func(yet another numeric mode value); # $symbols set to '+<', for "read+"
If anyone can tell me why IPC::PerlSSH::IO::open() only works when I pass it symbols - please do so.

Comment on open(): Is there a simple way to map between numeric open modes and "symbol modes"? (solved)
Re: open(): Is there a simple way to map between numeric open modes and "symbol modes"?
by muba (Priest) on Feb 07, 2013 at 23:48 UTC

    What do you mean by numeric mode values? I don't think I've ever heard of that.

      "Numeric mode value" means the number you'd pass to an open() call, "which is an OR-ing of stuff like O_RDONLY and O_SYNC, constants you can import from POSIX" (for example from FUSE, see).

      Question is: how do I un-OR this stuff and get the matching symbol for what the ORed POSIX flags/constants mean.
Re: open(): Is there a simple way to map between numeric open modes and "symbol modes"?
by BrowserUk (Pope) on Feb 07, 2013 at 23:49 UTC

    See Fmode.pm


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      From Fmode:
      my %modes; @modes{ qw < > >> +< +> +>>  } = ( 1, 2, 2, 128, 128, 128 );
      Are these the official constants? If so, how do I un-OR OR results, against the other flags, to get back to these basic constants?

        As I remember, I "discovered" them by writing a small C program that open files in each of the modes and then queried the numeric value using this code (from Fmode.xs):

        int xs_fmode( FILE *stream ) { return stream->_flag; }

        And I discovered that incantation by finding the struct FILE definition in the C header files.

        NOTE: This was done using MSVC header files; YMMV on other platforms.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        how do I un-OR OR results, against the other flags, to get back to these basic constants?

        (From MSVC header files:

        #define _O_RDONLY 0x0000 /* open for reading only */ #define _O_WRONLY 0x0001 /* open for writing only */ #define _O_RDWR 0x0002 /* open for reading and writing */ #define _O_APPEND 0x0008 /* writes done at eof */ #define _O_CREAT 0x0100 /* create and open file */ #define _O_TRUNC 0x0200 /* open and truncate */ #define _O_EXCL 0x0400 /* open only if file doesn't already e +xist */ #define _O_TEXT 0x4000 /* file mode is text (translated) */ #define _O_BINARY 0x8000 /* file mode is binary (untranslated) +*/ #define _O_WTEXT 0x10000 /* file mode is UTF16 (translated) */ #define _O_U16TEXT 0x20000 /* file mode is UTF16 no BOM (translat +ed) */ #define _O_U8TEXT 0x40000 /* file mode is UTF8 no BOM (translat +ed) */

        So, assuming the variable $mode contains the OR'd values; you can check which bits are set something like:

        if( $mode & 1 ) { ## _O_WRONLY say "File is opend WRITE only }

        But note: not all of the bits that can be set when opening a file are retained in FILE*->_flag.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        See also FileHandle::Fmode and Fcntl

        #!/usr/bin/perl -- use strict; use warnings; use Data::Dump; use Fcntl(); my %mode2symbol = ( #~ Fcntl::F_DUPFD() => '&', Fcntl::O_RDONLY() => '<', Fcntl::O_RDWR() => '+<', Fcntl::O_TRUNC() => '>', Fcntl::O_WRONLY() => '>', Fcntl::O_APPEND() => '>>', Fcntl::O_CREAT() => '>', ); my %name2mode = ( #~ F_DUPFD => Fcntl::F_DUPFD(), O_RDONLY => Fcntl::O_RDONLY(), O_RDWR => Fcntl::O_RDWR(), O_TRUNC => Fcntl::O_TRUNC(), O_WRONLY => Fcntl::O_WRONLY(), O_APPEND => Fcntl::O_APPEND(), O_CREAT => Fcntl::O_CREAT(), ); $mode2symbol{ $name2mode{O_RDWR} | $name2mode{O_APPEND} } = '+>>'; $mode2symbol{ $name2mode{O_RDONLY} | $name2mode{O_APPEND} } = '+>>'; $mode2symbol{ $name2mode{O_WRONLY} | $name2mode{O_APPEND} } = '+>>'; dd \%mode2symbol; dd \%name2mode; __END__ { "0" => "<", "1" => ">", "2" => "+<", "8" => "+>>", "9" => "+>>", "10" => "+>>", "256" => ">", "512" => ">", } { O_APPEND => 8, O_CREAT => 256, O_RDONLY => 0, O_RDWR => 2, O_TRUNC => 512, O_WRONLY => 1, }
Re: open(): Is there a simple way to map between numeric open modes and "symbol modes"?
by Anonymous Monk on Feb 08, 2013 at 04:06 UTC

    somehow numeric mode values doesn't seem to work, while their symbol equivalents work.

    That is the difference between open and sysopen, one takes strings for mode, the other numbers, and IPC::PerlSSH::IO appears to use open

      AHA!!

      So instead of re-translating numeric to symbols in a big if/elsif behemoth, I think, it's easier to simply write a new function that relies on sysopen().

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1017733]
Approved by muba
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (12)
As of 2014-09-02 20:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (29 votes), past polls