# class IO

    IO/StringIO/File alterations
    Fill in missing constants according to platform.
    ### win32 stuff

006 define F_SETFL 1 007 define F_SETFD 2 008 define F_GETFL 3 009 010 define _O_RDONLY 0x0000 open for reading only

011 define _O_WRONLY 0x0001 open for writing only

012 define _O_RDWR 0x0002 /* open for reading and writing */ 013 014 define _O_NONBLOCK 0x0004 015 016 define _O_APPEND 0x0008 /* writes done at eof */ 017 define _O_CREAT 0x0100 /* create and open file */ 018 define _O_TRUNC 0x0200 /* open and truncate */ 019 define _O_EXCL 0x0400 /* open only if file doesn't already exist */ 020 define _O_TEXT 0x4000 /* file mode is text (translated) */ 021 define _O_BINARY 0x8000 /* file mode is binary (untranslated) */ 022 define _O_ACCMODE 0x10000 023 024 define _O_NOINHERIT 0 025 define O_NOINHERIT _O_NOINHERIT 026 027 define O_RDONLY _O_RDONLY 028 define O_WRONLY _O_WRONLY 029 define O_RDWR _O_RDWR 030 031 define O_NONBLOCK _O_NONBLOCK 032 033 define O_APPEND _O_APPEND 034 define O_CREAT _O_CREAT 035 define O_TRUNC _O_TRUNC 036 define O_EXCL _O_EXCL 037 define O_TEXT _O_TEXT 038 define O_BINARY _O_BINARY 039 define O_ACCMODE _O_ACCMODE

    ### end win32 stuff
         @@valid_modes[:flags][:io][:tty] = 0x00000010
         @@valid_modes[:flags][:io][:noctty] = ::IO::NOCTTY
         @@valid_modes[:flags][:io][:duplex] = 0x00000020
         @@valid_modes[:flags][:io][:append] = ::IO::APPEND
         @@valid_modes[:flags][:io][:create] = ::IO::CREAT
         @@valid_modes[:flags][:io][:exclusive] = ::IO::EXCL
         @@valid_modes[:flags][:io][:wsplit] = 0x00000200
         @@valid_modes[:flags][:io][:wsplit_initialized] = 0x00000400
         @@valid_modes[:flags][:io][:trunc] = ::IO::TRUNC
         @@valid_modes[:flags][:io][:text] = ::IO::TEXT
         @@valid_modes[:flags][:io][:setenc_by_bom] = 0x00100000
    See : http://boop.ankhcraft.com/library/ruby-api/dc/dac/io_8h.html
    Also : http://boop.ankhcraft.com/library/ruby-api/d2/d4d/file_8h.html
    also : http://boop.ankhcraft.com/library/ruby-api/d6/d13/file_8c.html

### Constants

DSYNC

  Note: need to verify this int value before using:

DUPLEX

  Note: need to verify this int value before using:

NOATIME

  Note: need to verify this int value before using:

NOFOLLOW

  Note: need to verify this int value before using:

RSYNC

  Note: need to verify this int value before using:

SETENC_BY_BOM

      Note: need to verify this int value before using:

  `SETENC_BY_BOM` = 0x00100000

TEXT

  What is the flag value under Win32?

TTY

  Note: need to verify this int value before using:

WSPLIT

  Note: need to verify this int value before using:

WSPLIT_INITIALIZED

  Note: need to verify this int value before using:

### Public Instance Methods

flags() click to toggle source

    # File lib/gxg/gxg_augmented.rb, line 275
    def flags()
      result = []
      current = self.fcntl(::Fcntl::F_GETFL)
      flags = {}
      if self.binmode?()
        result << :binary
        if self.external_encoding == ::Encoding::ASCII_8BIT
          result << :setenc_by_bom
        end
      else
        result << :text
        result << :wsplit
      end
      if self.tty?
        result << :tty
      end
      #
      #flag[:read] = 0x00000001
      #flag[:write] = 0x00000002
      #flag[:readwrite] = (flag[:read] | flag[:write])
      #flag[:binmode] = 0x00000004
      #flag[:readwrite] = (flag[:read] | flag[:write])
      flags[:read] = ::Fcntl::O_RDONLY
      flags[:write] = ::Fcntl::O_WRONLY
      flags[:readwrite] = ::Fcntl::O_RDWR
      #flags[:binary] = 0x00000004
      flags[:sync] = ::File::SYNC # no internal buffering -- The file will be opened for synchronous I/O. No write operation will complete until the data has been physically written to disk.
      flags[:dsync] = ::File::DSYNC # only normal data be synchronized after each write operation, not metadata.
      flags[:rsync] = ::File::RSYNC # the synchronization of read requests as well as write requests. It must be used with one of IO::SYNC or IO::DSYNC
      #flags[:tty] = 0x00000010
      flags[:notcontrol_tty] = ::Fcntl::O_NOCTTY
      flags[:duplex] = 0x00000020
      flags[:append] = ::Fcntl::O_APPEND
      flags[:create] = ::Fcntl::O_CREAT
      flags[:exclusive] = ::Fcntl::O_EXCL
      # flags[:wsplit] = 0x00000200
      flags[:wsplit_initialized] = 0x00000400
      flags[:trunc] = ::Fcntl::O_TRUNC
      #flags[:text] = 0x00001000
      #flags[:setenc_by_bom] = 0x00100000
      flags[:seek_set] = ::File::SEEK_SET
      flags[:seek_current] = ::File::SEEK_CUR
      flags[:seek_end] = ::File::SEEK_END
      # ### file region locking:
      flags[:shared_lock] = ::File::LOCK_SH # for reading
      flags[:exclusive_lock] = ::File::LOCK_EX # for writing (implies blocking)
      flags[:nonblock_lock] = ::File::LOCK_NB # combine with exclusive_lock for immediate non-blocking lock for writing.
      flags[:unlock] = ::File::LOCK_UN
      #
      flags[:nonblocking] = ::Fcntl::O_NONBLOCK
      flags[:ndelay] = ::Fcntl::O_NDELAY
      flags[:nofollow] = ::File::NOFOLLOW # Do not follow symlinks.
      flags[:noaccesstime] = ::File::NOATIME # Do not update the access time (atime) of the file.
      flags[:match_noescape] = ::File::FNM_NOESCAPE #
      flags[:match_pathname] = ::File::FNM_PATHNAME #
      flags[:match_dotmatch] = ::File::FNM_DOTMATCH #
      flags[:match_casefold] = ::File::FNM_CASEFOLD #
      flags[:match_systemcase] = ::File::FNM_SYSCASE #
      #
      flags.keys.to_enum.each do |the_flag_key|
        if (current & flags[(the_flag_key)]) == flags[(the_flag_key)]
          case the_flag_key
          when :readwrite
            if result.index(:write)
              result << :read
            else
              if result.index(:read)
                result << :write
              end
            end
          when :wsplit_initialized
            if result.index(:wsplit)
              result[(result.index(:wsplit))] = :wsplit_initialized
            else
              result << :wsplit_initialized
            end
          else
            result << the_flag_key
          end
        end
      end
      #
      result
    end

latency_reading(old_reading=nil,&block) click to toggle source

    # File lib/gxg/gxg_augmented.rb, line 246
    def latency_reading(old_reading=nil,&block)
      unless old_reading.is_a?(::Hash)
        old_reading = {:low => nil, :last => nil, :high => nil}
      end
      new_reading = {:low => nil, :last => nil, :high => nil}
      reading = millisecond_latency(&block)
      if old_reading[:low]
        if reading[:milliseconds] < old_reading[:low]
          new_reading[:low] = reading[:milliseconds].dup
        else
          new_reading[:low] = old_reading[:low]
        end
      else
        new_reading[:low] = reading[:milliseconds].dup
      end
      new_reading[:last] = reading[:milliseconds].dup
      if old_reading[:high]
        if reading[:milliseconds] > old_reading[:high]
          new_reading[:high] = reading[:milliseconds].dup
        else
          new_reading[:high] = old_reading[:high]
        end
      else
        new_reading[:high] = reading[:milliseconds].dup
      end
      #
      {:result => reading[:result], :reading => new_reading}
    end

profile(params={:follow_symlinks => true}) click to toggle source

    # File lib/gxg/gxg_augmented.rb, line 360
    def profile(params={:follow_symlinks => true})
      platform_details = GxG::SYSTEM.platform()
      result = {}
      #
      if params[:follow_symlinks]
        raw_stat = self.to_io.stat
      else
        raw_stat = self.to_io.lstat
      end
      raw_mode = raw_stat.mode.to_s(base=8)
      if raw_mode.size < 7
        raw_mode = ("0" << raw_mode)
      end
      set_user_id = false
      set_group_id = false
      set_sticky_bit = false
      if (raw_mode[3].to_i & 4) == 4
        set_user_id = true
      end
      if (raw_mode[3].to_i & 2) == 2
        set_group_id = true
      end
      if (raw_mode[3].to_i & 1) ==  1
        set_sticky_bit = true
      end
      #
      #
      raw_permission = { :execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false }
      #
      file_handle = nil
      GxG::Engine::file_descriptors.to_enum.each do |the_handle|
        if self.fileno == the_handle.fileno
          file_handle = the_handle
          break
        end
      end
      # LATER: GxG::IO::IO.profile : patch into file/stream type recognition engine.
      case raw_stat.ftype.to_s.downcase.to_sym
      when :link
        # are .lnk files handled properly on win32 for this?
        result[:type] =  :symlink
      when :file
        if file_handle
          if self.tty?
            result[:type] =  :tty
          else
            the_extension = ::File::basename(file_handle.to_path).split(".")[-1].to_s.downcase
            if the_extension == "lnk"
              result[:type] =  :symlink
            else
              if ["so","la","a","dylib","dll","class"].include?(the_extension)
                result[:type] =  :library
              else
                if (["out","exe","misc","java","jar", "sh", "rb", "py", "pyc"].include?(the_extension) || raw_stat.executable_real?)
                  result[:type] =  :application
                else
                  result[:type] = :file
                end
              end
            end
          end
        end
      when :fifo
        result[:type] =  :fifo
      when :characterspecial
        result[:type] =  :character_device
      when :blockspecial
        result[:type] =  :block_device
      when :socket
        result[:type] =  :socket
      when :directory
        result[:type] =  :directory
      when :unknown
        result[:type] =  :unknown
        if raw_stat.pipe?
          result[:type] =  :pipe
        end
      else
        if raw_stat.pipe?
          result[:type] =  :pipe
        end
      end
      result[:owner_type] = result[:type]
      result[:on_device] = raw_stat.dev.to_s(base=10).to_i
      if result[:on_device]
        result[:on_device_major] = raw_stat.dev_major
        result[:on_device_minor] = raw_stat.dev_minor
      end
      result[:is_device] = raw_stat.rdev
      if result[:is_device]
        result[:is_device_major] = raw_stat.rdev_major
        result[:is_device_minor] = raw_stat.rdev_minor
      end
      result[:inode] = raw_stat.ino.to_i
      #
      result[:flags] = self.flags()
      #
      if file_handle
        # man fstat : mode decoder-ring table:
        #
        #           S_IFMT     0170000   bit mask for the file type bit fields
        #           S_IFSOCK   0140000   socket
        #           S_IFLNK    0120000   symbolic link
        #           S_IFREG    0100000   regular file
        #           S_IFBLK    0060000   block device
        #           S_IFDIR    0040000   directory
        #           S_IFCHR    0020000   character device
        #           S_IFIFO    0010000   FIFO
        #
        #           S_ISUID    0004000   set UID bit
        #           S_ISGID    0002000   set-group-ID bit (see below)
        #           S_ISVTX    0001000   sticky bit (see below)
        #
        #           S_IRWXU    00700     mask for file owner permissions
        #           S_IRUSR    00400     owner has read permission
        #           S_IWUSR    00200     owner has write permission
        #           S_IXUSR    00100     owner has execute permission
        #
        #           S_IRWXG    00070     mask for group permissions
        #           S_IRGRP    00040     group has read permission
        #           S_IWGRP    00020     group has write permission
        #           S_IXGRP    00010     group has execute permission
        #
        #           S_IRWXO    00007     mask for permissions for others (not in group)
        #           S_IROTH    00004     others have read permission
        #           S_IWOTH    00002     others have write permission
        #           S_IXOTH    00001     others have execute permission
        #
        # <file>.stat table: (mode example : 0100664)
        #      0700       rwx mask for owner
        #      0400       r for owner
        #      0200       w for owner
        #      0100       x for owner
        #      0070       rwx mask for group
        #      0040       r for group
        #      0020       w for group
        #      0010       x for group
        #      0007       rwx mask for other
        #      0004       r for other
        #      0002       w for other
        #      0001       x for other
        #      4000       Set user ID on execution
        #      2000       Set group ID on execution
        #      1000       Save swapped text, even after use
        result[:hardlinks_to] = raw_stat.nlink.to_i
        result[:user_id] = raw_stat.uid.to_i
        result[:group_id] = raw_stat.gid.to_i
        result[:size] = raw_stat.size
        result[:block_size] = raw_stat.blksize
        result[:blocks] = raw_stat.blocks
        result[:accessed] = DateTime::parse(raw_stat.atime.to_s)
        result[:modified] = DateTime::parse(raw_stat.mtime.to_s)
        result[:status_modified] = DateTime::parse(raw_stat.ctime.to_s)
        # File permissions work in an ACL style, even if based only upon Unix-style permissions.
        #
        result[:permissions] = {:effective => raw_permission.clone, :owner => raw_permission.clone, :group => raw_permission.clone, :other => raw_permission.clone}
        if set_user_id
          result[:flags] << :user_id_on_execute
        end
        if set_group_id
          result[:flags] << :group_id_on_execute
        end
        if set_sticky_bit
          result[:flags] << :sticky_bit
        end
        # owner permissions
        if (raw_mode[4].to_i & 4) == 4
          result[:permissions][:owner][:read] = true
        end
        if (raw_mode[4].to_i & 2) == 2
          result[:permissions][:owner][:write] = true
          if platform_details[:platform] == :windows
            # :windows way of reading :rename, :move, and :destroy permission for file/directory.
          else
            result[:permissions][:owner][:rename] = true
            result[:permissions][:owner][:move] = true
            result[:permissions][:owner][:destroy] = true
            result[:permissions][:owner][:create] = true
          end
        end
        if (raw_mode[4].to_i & 1) == 1
          result[:permissions][:owner][:execute] = true
        end
        # group permissions
        if (raw_mode[5].to_i & 4) == 4
          result[:permissions][:owner][:read] = true
        end
        if (raw_mode[5].to_i & 2) == 2
          result[:permissions][:group][:write] = true
          if platform_details[:platform] == :windows
            # :windows way of reading :rename, :move, and :destroy permission for file/directory.
          else
            result[:permissions][:group][:rename] = true
            result[:permissions][:group][:move] = true
            result[:permissions][:group][:destroy] = true
            result[:permissions][:group][:create] = true
          end
        end
        if (raw_mode[5].to_i & 1) == 1
          result[:permissions][:group][:execute] = true
        end
        # other permissions
        if (raw_mode[6].to_i & 4) == 4
          result[:permissions][:other][:read] = true
        end
        if (raw_mode[6].to_i & 2) == 2
          result[:permissions][:other][:write] = true
          if platform_details[:platform] == :windows
            # :windows way of reading :rename, :move, and :destroy permission for file/directory.
          else
            result[:permissions][:other][:rename] = true
            result[:permissions][:other][:move] = true
            result[:permissions][:other][:destroy] = true
            result[:permissions][:other][:create] = true
          end
        end
        if (raw_mode[6].to_i & 1) == 1
          result[:permissions][:other][:execute] = true
        end
        # effective (this user) permissions (while opened, supercedes normal effective file system permissions)
        if result[:flags].index(:read)
          result[:permissions][:effective][:read] = true
          #
        end
        if result[:flags].index(:write)
          result[:permissions][:effective][:write] = true
          if platform_details[:platform] == :windows
            # :windows way of reading :rename, :move, and :destroy permission for file/directory.
          else
            result[:permissions][:effective][:rename] = true
            result[:permissions][:effective][:move] = true
            result[:permissions][:effective][:destroy] = true
            result[:permissions][:effective][:create] = true
          end
        end
        if raw_stat.executable?
          result[:permissions][:effective][:execute] = true
        end
        #
      else
        # in-memory object - no fs involvement
        # ok ... why? Well, I want objects to be able to pass through my unwritten system stuff : experimental, w/o special handling.
        result[:permissions] = {:effective => raw_permission.clone, :owner => raw_permission.clone, :group => raw_permission.clone, :other => raw_permission.clone}
        #
        if result[:flags].index(:read)
          result[:permissions][:effective][:read] = true
          result[:permissions][:owner][:read] = true
          result[:permissions][:group][:read] = true
          result[:permissions][:other][:read] = true
          #
        end
        #
        if result[:flags].index(:write)
          result[:permissions][:effective][:write] = true
          result[:permissions][:owner][:write] = true
          result[:permissions][:group][:write] = true
          result[:permissions][:other][:write] = true
        end
        #
      end
      #
      result[:mode] = {}
      #
      result
    end

read_latency() click to toggle source

    # File lib/gxg/gxg_augmented.rb, line 239
    def read_latency()
      unless self.instance_variable_defined?(:@read_latency)
        @read_latency= {:low => nil, :last => nil, :high => nil}
      end
      @read_latency.clone
    end

write_latency() click to toggle source

    # File lib/gxg/gxg_augmented.rb, line 232
    def write_latency()
      unless self.instance_variable_defined?(:@write_latency)
        @write_latency= {:low => nil, :last => nil, :high => nil}
      end
      @write_latency.clone
    end