/lib/ffi/libc/libc.rb
https://github.com/postmodern/ffi-libc · Ruby · 220 lines · 142 code · 36 blank · 42 comment · 5 complexity · 2f735d5524f170f65ac77a36d9d88d8a MD5 · raw file
- require 'ffi/libc/types'
- require 'ffi/libc/timeval'
- require 'ffi/libc/timezone'
- require 'ffi/libc/ifaddrs'
- require 'ffi/libc/rusage'
- require 'ffi'
- module FFI
- module LibC
- extend FFI::Library
- ffi_lib FFI::Library::LIBC
- # The NULL constant
- NULL = nil
- # errno.h
- begin
- attach_variable :sys_errlist, :pointer
- attach_variable :sys_nerr, :int
- rescue FFI::NotFoundError
- end
- attach_variable :errno, :int
- def self.raise_error(error=self.errno)
- raise(strerror(error))
- end
- # unistd.h
- attach_function :brk, [:pointer], :int
- attach_function :sbrk, [:pointer], :pointer
- attach_function :getpid, [], :pid_t
- attach_function :getppid, [], :pid_t
- attach_function :getuid, [], :uid_t
- attach_function :geteuid, [], :uid_t
- attach_function :getgid, [], :gid_t
- attach_function :getegid, [], :gid_t
- attach_function :alarm, [:uint], :uint
- # stdlib.h
- attach_function :calloc, [:size_t, :size_t], :pointer
- attach_function :malloc, [:size_t], :pointer
- attach_function :free, [:pointer], :void
- attach_function :realloc, [:pointer, :size_t], :pointer
- attach_function :getenv, [:string], :string
- attach_function :putenv, [:string], :int
- attach_function :unsetenv, [:string], :int
- begin
- attach_function :clearenv, [], :int
- rescue FFI::NotFoundError
- # clearenv is not available on OSX
- end
- # time.h
- attach_function :clock, [], :clock_t
- attach_function :time, [:pointer], :time_t
- # sys/time.h
- attach_function :gettimeofday, [:pointer, :pointer], :int
- attach_function :settimeofday, [:pointer, :pointer], :int
- # sys/mman.h
- attach_function :mmap, [:pointer, :size_t, :int, :int, :int, :off_t], :pointer
- attach_function :munmap, [:pointer, :size_t], :int
- # string.h
- attach_function :bzero, [:pointer, :size_t], :void
- attach_function :memset, [:pointer, :int, :size_t], :pointer
- attach_function :memcpy, [:buffer_out, :buffer_in, :size_t], :pointer
- attach_function :memcmp, [:buffer_in, :buffer_in, :size_t], :int
- attach_function :memchr, [:buffer_in, :int, :size_t], :pointer
- begin
- attach_function :memrchr, [:buffer_in, :int, :size_t], :pointer
- rescue FFI::NotFoundError
- # memrchr is not available on OSX
- end
- attach_function :strcpy, [:buffer_out, :string], :pointer
- attach_function :strncpy, [:buffer_out, :string, :size_t], :pointer
- attach_function :strcmp, [:buffer_in, :buffer_in], :int
- attach_function :strncmp, [:buffer_in, :buffer_in, :size_t], :int
- attach_function :strlen, [:buffer_in], :size_t
- attach_function :index, [:buffer_in, :int], :pointer
- attach_function :rindex, [:buffer_in, :int], :pointer
- attach_function :strchr, [:buffer_in, :int], :pointer
- attach_function :strrchr, [:buffer_in, :int], :pointer
- attach_function :strstr, [:buffer_in, :string], :pointer
- attach_function :strerror, [:int], :string
- begin
- attach_variable :stdin, :pointer
- attach_variable :stdout, :pointer
- attach_variable :stderr, :pointer
- rescue FFI::NotFoundError
- # stdin, stdout, stderr are not available on OSX
- end
- attach_function :fopen, [:string, :string], :FILE
- attach_function :fdopen, [:int, :string], :FILE
- attach_function :freopen, [:string, :string, :FILE], :FILE
- attach_function :fseek, [:FILE, :long, :int], :int
- attach_function :ftell, [:FILE], :long
- attach_function :rewind, [:FILE], :void
- attach_function :fread, [:buffer_out, :size_t, :size_t, :FILE], :size_t
- attach_function :fwrite, [:buffer_in, :size_t, :size_t, :FILE], :size_t
- attach_function :fgetc, [:FILE], :int
- attach_function :fgets, [:buffer_out, :int, :FILE], :pointer
- attach_function :fputc, [:int, :FILE], :int
- attach_function :fputs, [:buffer_in, :FILE], :int
- attach_function :fflush, [:FILE], :int
- attach_function :fclose, [:FILE], :int
- attach_function :clearerr, [:FILE], :void
- attach_function :feof, [:FILE], :int
- attach_function :ferror, [:FILE], :int
- attach_function :fileno, [:FILE], :int
- attach_function :perror, [:string], :void
- attach_function :getc, [:FILE], :int
- attach_function :getchar, [], :int
- attach_function :gets, [:buffer_out], :int
- attach_function :ungetc, [:int, :pointer], :int
- attach_function :putc, [:int, :FILE], :int
- attach_function :putchar, [:int], :int
- attach_function :puts, [:string], :int
- # netdb.h
- attach_function :getnameinfo, [
- :pointer,
- :socklen_t, :pointer,
- :socklen_t, :pointer,
- :socklen_t, :int
- ], :int
- NI_MAXHOST = 1024
- NI_MAXSERV = 32
- NI_NUMERICHOST = 1 # Don't try to look up hostname.
- NI_NUMERICSERV = 2 # Don't convert port number to name.
- NI_NOFQDN = 4 # Only return nodename portion.
- NI_NAMEREQD = 8 # Don't return numeric addresses.
- NI_DGRAM = 16 # Look up UDP service rather than TCP.
- # ifaddrs.h
- attach_function :getifaddrs, [:pointer], :int
- attach_function :freeifaddrs, [:pointer], :void
- #
- # Enumerates over the Interface Addresses.
- #
- # @yield [ifaddr]
- # The given block will be passed each Interface Address.
- #
- # @yieldparam [Ifaddrs] ifaddr
- # An Interface Address.
- #
- # @return [Enumerator]
- # If no block is given, an enumerator will be returned.
- #
- # @since 0.1.0
- #
- def self.each_ifaddr
- return enum_for(__method__) unless block_given?
- ptr = MemoryPointer.new(:pointer)
- if getifaddrs(ptr) == -1
- raise_error
- end
- if (ifaddrs = ptr.get_pointer(0)).null?
- return
- end
- ifaddr = Ifaddrs.new(ifaddrs)
- while ifaddr
- yield ifaddr
- ifaddr = ifaddr.next
- end
- freeifaddrs(ifaddrs)
- end
- # bits/resource.h (Linux) / sys/resource.h (Darwin)
- RUSAGE_SELF = 0
- RUSAGE_CHILDREN = -1
- RUSAGE_THREAD = 1 # Linux/glibc only
- attach_function :getrusage, [:int, :pointer], :int
- #
- # Gets the RUsage for the user.
- #
- # @param [RUSAGE_SELF, RUSAGE_CHILDREN, RUSAGE_THREAD] who
- # Whome to get RUsage statistics for.
- #
- # @return [RUsage]
- # The RUsage statistics.
- #
- # @raise [RuntimeError]
- # An error has occurred.
- #
- # @since 0.1.0
- #
- def self.rusage(who=RUSAGE_SELF)
- rusage = RUsage.new
- unless (ret = getrusage(who,rusage)) == 0
- raise_error(ret)
- end
- return rusage
- end
- end
- end