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