Example #1
0
 def _select(self, for_writing):
     """Returns 0 when reading/writing is possible,
     1 when timing out and -1 on error."""
     timeout = self.timeout
     if timeout <= 0.0 or self.fd == _c.INVALID_SOCKET:
         # blocking I/O or no socket.
         return 0
     tv = rffi.make(_c.timeval)
     rffi.setintfield(tv, 'c_tv_sec', int(timeout))
     rffi.setintfield(tv, 'c_tv_usec', int((timeout-int(timeout))
                                           * 1000000))
     fds = rffi.make(_c.fd_set)
     rffi.setintfield(fds, 'c_fd_count', 1)
     fds.c_fd_array[0] = rffi.cast(_c.socketfd_type, self.fd)
     null = lltype.nullptr(_c.fd_set)
     if for_writing:
         n = _c.select(self.fd + 1, null, fds, null, tv)
     else:
         n = _c.select(self.fd + 1, fds, null, null, tv)
     lltype.free(fds, flavor='raw')
     lltype.free(tv, flavor='raw')
     if n < 0:
         return -1
     if n == 0:
         return 1
     return 0
Example #2
0
 def _select(self, for_writing):
     """Returns 0 when reading/writing is possible,
     1 when timing out and -1 on error."""
     timeout = self.timeout
     if timeout <= 0.0 or self.fd == _c.INVALID_SOCKET:
         # blocking I/O or no socket.
         return 0
     tv = rffi.make(_c.timeval)
     rffi.setintfield(tv, 'c_tv_sec', int(timeout))
     rffi.setintfield(tv, 'c_tv_usec',
                      int((timeout - int(timeout)) * 1000000))
     fds = rffi.make(_c.fd_set)
     rffi.setintfield(fds, 'c_fd_count', 1)
     fds.c_fd_array[0] = rffi.cast(_c.socketfd_type, self.fd)
     null = lltype.nullptr(_c.fd_set)
     if for_writing:
         n = _c.select(self.fd + 1, null, fds, null, tv)
     else:
         n = _c.select(self.fd + 1, fds, null, null, tv)
     lltype.free(fds, flavor='raw')
     lltype.free(tv, flavor='raw')
     if n < 0:
         return -1
     if n == 0:
         return 1
     return 0
Example #3
0
 def _get_allocation_granularity():
     try:
         si = rffi.make(SYSTEM_INFO)
         GetSystemInfo(si)
         return int(si.c_dwAllocationGranularity)
     finally:
         lltype.free(si, flavor="raw")
Example #4
0
File: rmmap.py Project: ieure/pypy
 def _get_allocation_granularity():
     try:
         si = rffi.make(SYSTEM_INFO)
         GetSystemInfo(si)
         return int(si.c_dwAllocationGranularity)
     finally:
         lltype.free(si, flavor="raw")
Example #5
0
 def _get_page_size():
     try:
         si = rffi.make(SYSTEM_INFO)
         GetSystemInfo(si)
         return int(si.c_dwPageSize)
     finally:
         lltype.free(si, flavor="raw")
Example #6
0
 def _get_page_size():
     try:
         si = rffi.make(SYSTEM_INFO)
         GetSystemInfo(si)
         return int(si.c_dwPageSize)
     finally:
         lltype.free(si, flavor="raw")
Example #7
0
def select(inl, outl, excl, timeout=-1.0):
    nfds = 0
    if inl: 
        ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_inl)
        for i in inl:
            _c.FD_SET(i, ll_inl)
            if i > nfds:
                nfds = i
    else:
        ll_inl = lltype.nullptr(_c.fd_set.TO)
    if outl: 
        ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_outl)
        for i in outl:
            _c.FD_SET(i, ll_outl)
            if i > nfds:
                nfds = i
    else:
        ll_outl = lltype.nullptr(_c.fd_set.TO)
    if excl: 
        ll_excl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_excl)
        for i in excl:
            _c.FD_SET(i, ll_excl)
            if i > nfds:
                nfds = i
    else:
        ll_excl = lltype.nullptr(_c.fd_set.TO)
    if timeout != -1.0:
        ll_timeval = rffi.make(_c.timeval)
        rffi.setintfield(ll_timeval, 'c_tv_sec', int(timeout))
        rffi.setintfield(ll_timeval, 'c_tv_usec', int((timeout-int(timeout))
                                                  * 1000000))
    else:
        ll_timeval = lltype.nullptr(_c.timeval)
    try:
        res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
        if res == -1:
            raise SelectError(_c.geterrno())
        if res == 0:
            return ([], [], [])
        else:
            return (
                [i for i in inl if _c.FD_ISSET(i, ll_inl)],
                [i for i in outl if _c.FD_ISSET(i, ll_outl)],
                [i for i in excl if _c.FD_ISSET(i, ll_excl)])
    finally:
        if ll_inl:
            lltype.free(ll_inl, flavor='raw')
        if ll_outl:
            lltype.free(ll_outl, flavor='raw')
        if ll_excl:
            lltype.free(ll_excl, flavor='raw')
        if ll_timeval:
            lltype.free(ll_timeval, flavor='raw')
Example #8
0
File: rpoll.py Project: njues/Sypy
def select(inl, outl, excl, timeout=-1.0):
    nfds = 0
    if inl: 
        ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_inl)
        for i in inl:
            _c.FD_SET(i, ll_inl)
            if i > nfds:
                nfds = i
    else:
        ll_inl = lltype.nullptr(_c.fd_set.TO)
    if outl: 
        ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_outl)
        for i in outl:
            _c.FD_SET(i, ll_outl)
            if i > nfds:
                nfds = i
    else:
        ll_outl = lltype.nullptr(_c.fd_set.TO)
    if excl: 
        ll_excl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_excl)
        for i in excl:
            _c.FD_SET(i, ll_excl)
            if i > nfds:
                nfds = i
    else:
        ll_excl = lltype.nullptr(_c.fd_set.TO)
    if timeout != -1.0:
        ll_timeval = rffi.make(_c.timeval)
        rffi.setintfield(ll_timeval, 'c_tv_sec', int(timeout))
        rffi.setintfield(ll_timeval, 'c_tv_usec', int((timeout-int(timeout))
                                                  * 1000000))
    else:
        ll_timeval = lltype.nullptr(_c.timeval)
    try:
        res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
        if res == -1:
            raise SelectError(_c.geterrno())
        if res == 0:
            return ([], [], [])
        else:
            return (
                [i for i in inl if _c.FD_ISSET(i, ll_inl)],
                [i for i in outl if _c.FD_ISSET(i, ll_outl)],
                [i for i in excl if _c.FD_ISSET(i, ll_excl)])
    finally:
        if ll_inl:
            lltype.free(ll_inl, flavor='raw')
        if ll_outl:
            lltype.free(ll_outl, flavor='raw')
        if ll_excl:
            lltype.free(ll_excl, flavor='raw')
        if ll_timeval:
            lltype.free(ll_timeval, flavor='raw')
Example #9
0
def inet_ntoa(packed):
    "packet 32-bits string -> IPv4 dotted string"
    if len(packed) != sizeof(_c.in_addr):
        raise RSocketError("packed IP wrong length for inet_ntoa")
    buf = rffi.make(_c.in_addr)
    try:
        for i in range(sizeof(_c.in_addr)):
            rffi.cast(rffi.CCHARP, buf)[i] = packed[i]
        return rffi.charp2str(_c.inet_ntoa(buf))
    finally:
        lltype.free(buf, flavor='raw')
Example #10
0
def inet_ntoa(packed):
    "packet 32-bits string -> IPv4 dotted string"
    if len(packed) != sizeof(_c.in_addr):
        raise RSocketError("packed IP wrong length for inet_ntoa")
    buf = rffi.make(_c.in_addr)
    try:
        for i in range(sizeof(_c.in_addr)):
            rffi.cast(rffi.CCHARP, buf)[i] = packed[i]
        return rffi.charp2str(_c.inet_ntoa(buf))
    finally:
        lltype.free(buf, flavor='raw')
Example #11
0
 def test_call_with_struct_argument(self):
     # XXX is there such a function in the standard C headers?
     from pypy.rlib import _rsocket_rffi
     buf = rffi.make(_rsocket_rffi.in_addr)
     rffi.cast(rffi.CCHARP, buf)[0] = '\x01'
     rffi.cast(rffi.CCHARP, buf)[1] = '\x02'
     rffi.cast(rffi.CCHARP, buf)[2] = '\x03'
     rffi.cast(rffi.CCHARP, buf)[3] = '\x04'
     p = _rsocket_rffi.inet_ntoa(buf)
     assert rffi.charp2str(p) == '1.2.3.4'
     lltype.free(buf, flavor='raw')
     assert not ALLOCATED  # detects memory leaks in the test
Example #12
0
 def test_call_with_struct_argument(self):
     # XXX is there such a function in the standard C headers?
     from pypy.rlib import _rsocket_rffi
     buf = rffi.make(_rsocket_rffi.in_addr)
     rffi.cast(rffi.CCHARP, buf)[0] = '\x01'
     rffi.cast(rffi.CCHARP, buf)[1] = '\x02'
     rffi.cast(rffi.CCHARP, buf)[2] = '\x03'
     rffi.cast(rffi.CCHARP, buf)[3] = '\x04'
     p = _rsocket_rffi.inet_ntoa(buf)
     assert rffi.charp2str(p) == '1.2.3.4'
     lltype.free(buf, flavor='raw')
     assert not ALLOCATED     # detects memory leaks in the test
Example #13
0
        def _connect(self, address):
            """Connect the socket to a remote address."""
            addr = address.lock()
            res = _c.socketconnect(self.fd, addr, address.addrlen)
            address.unlock()
            errno = _c.geterrno()
            timeout = self.timeout
            if timeout > 0.0 and res < 0 and errno == _c.EWOULDBLOCK:
                tv = rffi.make(_c.timeval)
                rffi.setintfield(tv, 'c_tv_sec', int(timeout))
                rffi.setintfield(tv, 'c_tv_usec',
                                 int((timeout - int(timeout)) * 1000000))
                fds = lltype.malloc(_c.fd_set.TO, flavor='raw')
                _c.FD_ZERO(fds)
                _c.FD_SET(self.fd, fds)
                fds_exc = lltype.malloc(_c.fd_set.TO, flavor='raw')
                _c.FD_ZERO(fds_exc)
                _c.FD_SET(self.fd, fds_exc)
                null = lltype.nullptr(_c.fd_set.TO)

                try:
                    n = _c.select(self.fd + 1, null, fds, fds_exc, tv)

                    if n > 0:
                        if _c.FD_ISSET(self.fd, fds):
                            # socket writable == connected
                            return (0, False)
                        else:
                            # per MS docs, call getsockopt() to get error
                            assert _c.FD_ISSET(self.fd, fds_exc)
                            return (self.getsockopt_int(
                                _c.SOL_SOCKET, _c.SO_ERROR), False)
                    elif n == 0:
                        return (_c.EWOULDBLOCK, True)
                    else:
                        return (_c.geterrno(), False)

                finally:
                    lltype.free(fds, flavor='raw')
                    lltype.free(fds_exc, flavor='raw')
                    lltype.free(tv, flavor='raw')

            if res == 0:
                errno = 0
            return (errno, False)
Example #14
0
        def _connect(self, address):
            """Connect the socket to a remote address."""
            addr = address.lock()
            res = _c.socketconnect(self.fd, addr, address.addrlen)
            address.unlock()
            errno = _c.geterrno()
            timeout = self.timeout
            if timeout > 0.0 and res < 0 and errno == _c.EWOULDBLOCK:
                tv = rffi.make(_c.timeval)
                rffi.setintfield(tv, 'c_tv_sec', int(timeout))
                rffi.setintfield(tv, 'c_tv_usec',
                                 int((timeout-int(timeout)) * 1000000))
                fds = lltype.malloc(_c.fd_set.TO, flavor='raw')
                _c.FD_ZERO(fds)
                _c.FD_SET(self.fd, fds)
                fds_exc = lltype.malloc(_c.fd_set.TO, flavor='raw')
                _c.FD_ZERO(fds_exc)
                _c.FD_SET(self.fd, fds_exc)
                null = lltype.nullptr(_c.fd_set.TO)

                try:
                    n = _c.select(self.fd + 1, null, fds, fds_exc, tv)

                    if n > 0:
                        if _c.FD_ISSET(self.fd, fds):
                            # socket writable == connected
                            return (0, False)
                        else:
                            # per MS docs, call getsockopt() to get error
                            assert _c.FD_ISSET(self.fd, fds_exc)
                            return (self.getsockopt_int(_c.SOL_SOCKET,
                                                        _c.SO_ERROR), False)
                    elif n == 0:
                        return (_c.EWOULDBLOCK, True)
                    else:
                        return (_c.geterrno(), False)

                finally:
                    lltype.free(fds, flavor='raw')
                    lltype.free(fds_exc, flavor='raw')
                    lltype.free(tv, flavor='raw')

            if res == 0:
                errno = 0
            return (errno, False)
Example #15
0
 def _select(self, for_writing):
     """Returns 0 when reading/writing is possible,
     1 when timing out and -1 on error."""
     if self.timeout <= 0.0 or self.fd == _c.INVALID_SOCKET:
         # blocking I/O or no socket.
         return 0
     pollfd = rffi.make(_c.pollfd)
     try:
         rffi.setintfield(pollfd, 'c_fd', self.fd)
         if for_writing:
             rffi.setintfield(pollfd, 'c_events', _c.POLLOUT)
         else:
             rffi.setintfield(pollfd, 'c_events', _c.POLLIN)
         timeout = int(self.timeout * 1000.0 + 0.5)
         n = _c.poll(rffi.cast(lltype.Ptr(_c.pollfdarray), pollfd),
                     1, timeout)
     finally:
         lltype.free(pollfd, flavor='raw')
     if n < 0:
         return -1
     if n == 0:
         return 1
     return 0
Example #16
0
 def _select(self, for_writing):
     """Returns 0 when reading/writing is possible,
     1 when timing out and -1 on error."""
     if self.timeout <= 0.0 or self.fd == _c.INVALID_SOCKET:
         # blocking I/O or no socket.
         return 0
     pollfd = rffi.make(_c.pollfd)
     try:
         rffi.setintfield(pollfd, 'c_fd', self.fd)
         if for_writing:
             rffi.setintfield(pollfd, 'c_events', _c.POLLOUT)
         else:
             rffi.setintfield(pollfd, 'c_events', _c.POLLIN)
         timeout = int(self.timeout * 1000.0 + 0.5)
         n = _c.poll(rffi.cast(lltype.Ptr(_c.pollfdarray), pollfd), 1,
                     timeout)
     finally:
         lltype.free(pollfd, flavor='raw')
     if n < 0:
         return -1
     if n == 0:
         return 1
     return 0
Example #17
0
def select(space, w_iwtd, w_owtd, w_ewtd, w_timeout=None):
    """Wait until one or more file descriptors are ready for some kind of I/O.
The first three arguments are sequences of file descriptors to be waited for:
rlist -- wait until ready for reading
wlist -- wait until ready for writing
xlist -- wait for an ``exceptional condition''
If only one kind of condition is required, pass [] for the other lists.
A file descriptor is either a socket or file object, or a small integer
gotten from a fileno() method call on one of those.

The optional 4th argument specifies a timeout in seconds; it may be
a floating point number to specify fractions of seconds.  If it is absent
or None, the call will never time out.

The return value is a tuple of three lists corresponding to the first three
arguments; each contains the subset of the corresponding file descriptors
that are ready.

*** IMPORTANT NOTICE ***
On Windows, only sockets are supported; on Unix, all file descriptors.
"""

    iwtd_w = space.listview(w_iwtd)
    owtd_w = space.listview(w_owtd)
    ewtd_w = space.listview(w_ewtd)

    ll_inl  = lltype.nullptr(_c.fd_set.TO)
    ll_outl = lltype.nullptr(_c.fd_set.TO)
    ll_errl = lltype.nullptr(_c.fd_set.TO)
    ll_timeval = lltype.nullptr(_c.timeval)
    
    try:
        fdlistin  = None
        fdlistout = None
        fdlisterr = None
        nfds = -1
        if len(iwtd_w) > 0:
            ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw')
            fdlistin, nfds = _build_fd_set(space, iwtd_w, ll_inl, nfds)
        if len(owtd_w) > 0:
            ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw')
            fdlistout, nfds = _build_fd_set(space, owtd_w, ll_outl, nfds)
        if len(ewtd_w) > 0:
            ll_errl = lltype.malloc(_c.fd_set.TO, flavor='raw')
            fdlisterr, nfds = _build_fd_set(space, ewtd_w, ll_errl, nfds)

        if space.is_w(w_timeout, space.w_None):
            timeout = -1.0
        else:
            timeout = space.float_w(w_timeout)
        if timeout >= 0.0:
            ll_timeval = rffi.make(_c.timeval)
            i = int(timeout)
            rffi.setintfield(ll_timeval, 'c_tv_sec', i)
            rffi.setintfield(ll_timeval, 'c_tv_usec', int((timeout-i)*1000000))

        res = _c.select(nfds + 1, ll_inl, ll_outl, ll_errl, ll_timeval)

        if res < 0:
            errno = _c.geterrno()
            msg = _c.socket_strerror_str(errno)
            w_errortype = space.fromcache(Cache).w_error
            raise OperationError(w_errortype, space.newtuple([
                space.wrap(errno), space.wrap(msg)]))

        resin_w = []
        resout_w = []
        reserr_w = []
        if res > 0:
            if fdlistin is not None:
                _unbuild_fd_set(space, iwtd_w, fdlistin,  ll_inl,  resin_w)
            if fdlistout is not None:
                _unbuild_fd_set(space, owtd_w, fdlistout, ll_outl, resout_w)
            if fdlisterr is not None:
                _unbuild_fd_set(space, ewtd_w, fdlisterr, ll_errl, reserr_w)
    finally:
        if ll_timeval: lltype.free(ll_timeval, flavor='raw')
        if ll_errl:    lltype.free(ll_errl, flavor='raw')
        if ll_outl:    lltype.free(ll_outl, flavor='raw')
        if ll_inl:     lltype.free(ll_inl, flavor='raw')

    return space.newtuple([space.newlist(resin_w),
                           space.newlist(resout_w),
                           space.newlist(reserr_w)])
Example #18
0
def getaddrinfo(hostname, servname,
                family=_c.AF_UNSPEC, socktype=0,
                protocol=0, flags=0,
                address_to_fill=None):

    if not hostname and not servname:
        raise GAIError(EAI_NONAME)

    # error checks for hints
    if flags & ~AI_MASK:
        raise GAIError(EAI_BADFLAGS)
    if family not in (_c.AF_UNSPEC, _c.AF_INET):
        raise GAIError(EAI_FAMILY)

    if socktype == GAI_ANY:
        if protocol == GAI_ANY:
            pass
        elif protocol == _c.IPPROTO_UDP:
            socktype = _c.SOCK_DGRAM
        elif protocol == _c.IPPROTO_TCP:
            socktype = _c.SOCK_STREAM
        else:
            socktype = _c.SOCK_RAW

    elif socktype == _c.SOCK_RAW:
        pass
    elif socktype == _c.SOCK_DGRAM:
        if protocol not in (_c.IPPROTO_UDP, GAI_ANY):
            raise GAIError(EAI_BADHINTS)
        protocol = _c.IPPROTO_UDP
    elif socktype == _c.SOCK_STREAM:
        if protocol not in (_c.IPPROTO_TCP, GAI_ANY):
            raise GAIError(EAI_BADHINTS)
        protocol = _c.IPPROTO_TCP
    else:
        raise GAIError(EAI_SOCKTYPE)

    port = GAI_ANY

    # service port
    if servname:
        if str_isdigit(servname):
            port = _c.htons(int(servname))
            # On windows, python2.3 uses getattrinfo.c,
            # python2.4 uses VC2003 implementation of getaddrinfo().
            # if sys.version < (2, 4)
            #     socktype = _c.SOCK_DGRAM
            #     protocol = _c.IPPROTO_UDP
        else:
            if socktype == _c.SOCK_DGRAM:
                proto = "udp"
            elif socktype == _c.SOCK_STREAM:
                proto = "tcp"
            else:
                proto = None

            sp = _c.getservbyname(servname, proto)
            if not sp:
                raise GAIError(EAI_SERVICE)
            port = sp.c_s_port
            if socktype == GAI_ANY:
                s_proto = rffi.charp2str(sp.c_s_proto)
                if s_proto == "udp":
                    socktype = _c.SOCK_DGRAM
                    protocol = _c.IPPROTO_UDP
                elif s_proto == "tcp":
                    socktype = _c.SOCK_STREAM
                    protocol = _c.IPPROTO_TCP
                else:
                    raise GAIError(EAI_PROTOCOL)

    # hostname == NULL
    # passive socket -> anyaddr (0.0.0.0 or ::)
    # non-passive socket -> localhost (127.0.0.1 or ::1)
    if not hostname:
        result = []
        if family in (_c.AF_UNSPEC, _c.AF_INET):

            sin = rffi.make(_c.sockaddr_in)
            try:
                rffi.setintfield(sin, 'c_sin_family', _c.AF_INET)
                rffi.setintfield(sin, 'c_sin_port', port)
                if flags & _c.AI_PASSIVE:
                    s_addr = 0x0         # addrany
                else:
                    s_addr = 0x0100007f  # loopback
                rffi.setintfield(sin.c_sin_addr, 'c_s_addr', s_addr)

                addr = make_address(rffi.cast(_c.sockaddr_ptr, sin),
                                    rffi.sizeof(_c.sockaddr_in),
                                    address_to_fill)

                result.append((_c.AF_INET, socktype, protocol, "",  # xxx canonname meaningless? "anyaddr"
                               addr))
            finally:
                lltype.free(sin, flavor='raw')

        if not result:
            raise GAIError(EAI_FAMILY)
        return result

    # hostname as numeric name
    if family in (_c.AF_UNSPEC, _c.AF_INET):

        packedaddr = _c.inet_addr(hostname)
        if packedaddr != rffi.cast(rffi.UINT, INADDR_NONE):

            v4a = rffi.cast(lltype.Unsigned, _c.ntohl(packedaddr))
            if (v4a & r_uint(0xf0000000) == r_uint(0xe0000000) or # IN_MULTICAST()
                v4a & r_uint(0xe0000000) == r_uint(0xe0000000)):  # IN_EXPERIMENTAL()
                flags &= ~_c.AI_CANONNAME
            v4a >>= 24 # = IN_CLASSA_NSHIFT
            if v4a == r_uint(0) or v4a == r_uint(127): # = IN_LOOPBACKNET
                flags &= ~_c.AI_CANONNAME

            sin = rffi.make(_c.sockaddr_in)
            try:
                rffi.setintfield(sin, 'c_sin_family', _c.AF_INET)
                rffi.setintfield(sin, 'c_sin_port', port)
                rffi.setintfield(sin.c_sin_addr, 'c_s_addr', packedaddr)
                addr = make_address(rffi.cast(_c.sockaddr_ptr, sin),
                                    rffi.sizeof(_c.sockaddr_in),
                                    address_to_fill)
            finally:
                lltype.free(sin, flavor='raw')

            if not flags & _c.AI_CANONNAME:
                canonname = ""
            else:
                # getaddrinfo() is a name->address translation function,
                # and it looks strange that we do addr->name translation
                # here.
                # This is what python2.3 did on Windows:
                # if sys.version < (2, 4):
                #     canonname = get_name(hostname, sin.sin_addr,
                #                          sizeof(_c.in_addr))
                canonname = hostname
            return [(_c.AF_INET, socktype, protocol, canonname, addr)]

    if flags & _c.AI_NUMERICHOST:
        raise GAIError(EAI_NONAME)

    # hostname as alphabetical name
    result = get_addr(hostname, socktype, protocol, port, address_to_fill)

    if result:
        return result

    raise GAIError(EAI_FAIL)
Example #19
0
def _get_api_ptr():
    api_ptr = rffi.make(api_type)
    for fn_name, fn, fn_ll_type, _, _ in _API_FUNCS_iterable:
        setattr(api_ptr, fn_name, rffi.llhelper(fn_ll_type, fn))
    return api_ptr
Example #20
0
def getaddrinfo(hostname,
                servname,
                family=_c.AF_UNSPEC,
                socktype=0,
                protocol=0,
                flags=0,
                address_to_fill=None):

    if not hostname and not servname:
        raise GAIError(EAI_NONAME)

    # error checks for hints
    if flags & ~AI_MASK:
        raise GAIError(EAI_BADFLAGS)
    if family not in (_c.AF_UNSPEC, _c.AF_INET):
        raise GAIError(EAI_FAMILY)

    if socktype == GAI_ANY:
        if protocol == GAI_ANY:
            pass
        elif protocol == _c.IPPROTO_UDP:
            socktype = _c.SOCK_DGRAM
        elif protocol == _c.IPPROTO_TCP:
            socktype = _c.SOCK_STREAM
        else:
            socktype = _c.SOCK_RAW

    elif socktype == _c.SOCK_RAW:
        pass
    elif socktype == _c.SOCK_DGRAM:
        if protocol not in (_c.IPPROTO_UDP, GAI_ANY):
            raise GAIError(EAI_BADHINTS)
        protocol = _c.IPPROTO_UDP
    elif socktype == _c.SOCK_STREAM:
        if protocol not in (_c.IPPROTO_TCP, GAI_ANY):
            raise GAIError(EAI_BADHINTS)
        protocol = _c.IPPROTO_TCP
    else:
        raise GAIError(EAI_SOCKTYPE)

    port = GAI_ANY

    # service port
    if servname:
        if str_isdigit(servname):
            port = _c.htons(int(servname))
            # On windows, python2.3 uses getattrinfo.c,
            # python2.4 uses VC2003 implementation of getaddrinfo().
            # if sys.version < (2, 4)
            #     socktype = _c.SOCK_DGRAM
            #     protocol = _c.IPPROTO_UDP
        else:
            if socktype == _c.SOCK_DGRAM:
                proto = "udp"
            elif socktype == _c.SOCK_STREAM:
                proto = "tcp"
            else:
                proto = None

            sp = _c.getservbyname(servname, proto)
            if not sp:
                raise GAIError(EAI_SERVICE)
            port = sp.c_s_port
            if socktype == GAI_ANY:
                s_proto = rffi.charp2str(sp.c_s_proto)
                if s_proto == "udp":
                    socktype = _c.SOCK_DGRAM
                    protocol = _c.IPPROTO_UDP
                elif s_proto == "tcp":
                    socktype = _c.SOCK_STREAM
                    protocol = _c.IPPROTO_TCP
                else:
                    raise GAIError(EAI_PROTOCOL)

    # hostname == NULL
    # passive socket -> anyaddr (0.0.0.0 or ::)
    # non-passive socket -> localhost (127.0.0.1 or ::1)
    if not hostname:
        result = []
        if family in (_c.AF_UNSPEC, _c.AF_INET):

            sin = rffi.make(_c.sockaddr_in)
            try:
                rffi.setintfield(sin, 'c_sin_family', _c.AF_INET)
                rffi.setintfield(sin, 'c_sin_port', port)
                if flags & _c.AI_PASSIVE:
                    s_addr = 0x0  # addrany
                else:
                    s_addr = 0x0100007f  # loopback
                rffi.setintfield(sin.c_sin_addr, 'c_s_addr', s_addr)

                addr = make_address(rffi.cast(_c.sockaddr_ptr, sin),
                                    rffi.sizeof(_c.sockaddr_in),
                                    address_to_fill)

                result.append((
                    _c.AF_INET,
                    socktype,
                    protocol,
                    "",  # xxx canonname meaningless? "anyaddr"
                    addr))
            finally:
                lltype.free(sin, flavor='raw')

        if not result:
            raise GAIError(EAI_FAMILY)
        return result

    # hostname as numeric name
    if family in (_c.AF_UNSPEC, _c.AF_INET):

        packedaddr = _c.inet_addr(hostname)
        if packedaddr != rffi.cast(rffi.UINT, INADDR_NONE):

            v4a = rffi.cast(lltype.Unsigned, _c.ntohl(packedaddr))
            if (v4a & r_uint(0xf0000000) == r_uint(0xe0000000)
                    or  # IN_MULTICAST()
                    v4a & r_uint(0xe0000000)
                    == r_uint(0xe0000000)):  # IN_EXPERIMENTAL()
                flags &= ~_c.AI_CANONNAME
            v4a >>= 24  # = IN_CLASSA_NSHIFT
            if v4a == r_uint(0) or v4a == r_uint(127):  # = IN_LOOPBACKNET
                flags &= ~_c.AI_CANONNAME

            sin = rffi.make(_c.sockaddr_in)
            try:
                rffi.setintfield(sin, 'c_sin_family', _c.AF_INET)
                rffi.setintfield(sin, 'c_sin_port', port)
                rffi.setintfield(sin.c_sin_addr, 'c_s_addr', packedaddr)
                addr = make_address(rffi.cast(_c.sockaddr_ptr, sin),
                                    rffi.sizeof(_c.sockaddr_in),
                                    address_to_fill)
            finally:
                lltype.free(sin, flavor='raw')

            if not flags & _c.AI_CANONNAME:
                canonname = ""
            else:
                # getaddrinfo() is a name->address translation function,
                # and it looks strange that we do addr->name translation
                # here.
                # This is what python2.3 did on Windows:
                # if sys.version < (2, 4):
                #     canonname = get_name(hostname, sin.sin_addr,
                #                          sizeof(_c.in_addr))
                canonname = hostname
            return [(_c.AF_INET, socktype, protocol, canonname, addr)]

    if flags & _c.AI_NUMERICHOST:
        raise GAIError(EAI_NONAME)

    # hostname as alphabetical name
    result = get_addr(hostname, socktype, protocol, port, address_to_fill)

    if result:
        return result

    raise GAIError(EAI_FAIL)
Example #21
0
    def poll(fddict, timeout=-1):
        """'fddict' maps file descriptors to interesting events.
        'timeout' is an integer in milliseconds, and NOT a float
        number of seconds, but it's the same in CPython.  Use -1 for infinite.
        Returns a list [(fd, events)].
        """
        numfd = len(fddict)
        numevents = 0
        socketevents = lltype.malloc(_c.WSAEVENT_ARRAY, numfd, flavor='raw')
        try:
            eventdict = {}

            for fd, events in fddict.iteritems():
                # select desired events
                wsaEvents = 0
                if events & _c.POLLIN:
                    wsaEvents |= _c.FD_READ | _c.FD_ACCEPT | _c.FD_CLOSE
                if events & _c.POLLOUT:
                    wsaEvents |= _c.FD_WRITE | _c.FD_CONNECT | _c.FD_CLOSE

                # if no events then ignore socket
                if wsaEvents == 0:
                    continue

                # select socket for desired events
                event = _c.WSACreateEvent()
                if _c.WSAEventSelect(fd, event, wsaEvents) != 0:
                    raise PollError(_c.geterrno())

                eventdict[fd] = event
                socketevents[numevents] = event
                numevents += 1

            assert numevents <= numfd

            # if no sockets then return immediately
            # XXX commented out by arigo - we just want to sleep for
            #     'timeout' milliseconds in this case, which is what
            #     I hope WSAWaitForMultipleEvents will do, no?
            #if numevents == 0:
            #    return []

            # prepare timeout
            if timeout < 0:
                timeout = _c.INFINITE

            ret = _c.WSAWaitForMultipleEvents(numevents, socketevents,
                                              False, timeout, False)

            if ret == _c.WSA_WAIT_TIMEOUT:
                return []

            if ret == r_uint(_c.WSA_WAIT_FAILED):
                raise PollError(_c.geterrno())

            retval = []
            info = rffi.make(_c.WSANETWORKEVENTS)
            for fd, event in eventdict.iteritems():
                if _c.WSAEnumNetworkEvents(fd, event, info) < 0:
                    continue
                revents = 0
                if info.c_lNetworkEvents & _c.FD_READ:
                    revents |= _c.POLLIN
                if info.c_lNetworkEvents & _c.FD_ACCEPT:
                    revents |= _c.POLLIN
                if info.c_lNetworkEvents & _c.FD_WRITE:
                    revents |= _c.POLLOUT
                if info.c_lNetworkEvents & _c.FD_CONNECT:
                    if info.c_iErrorCode[_c.FD_CONNECT_BIT]:
                        revents |= _c.POLLERR
                    else:
                        revents |= _c.POLLOUT
                if info.c_lNetworkEvents & _c.FD_CLOSE:
                    if info.c_iErrorCode[_c.FD_CLOSE_BIT]:
                        revents |= _c.POLLERR
                    else:
                        if fddict[fd] & _c.POLLIN:
                            revents |= _c.POLLIN
                        if fddict[fd] & _c.POLLOUT:
                            revents |= _c.POLLOUT
                if revents:
                    retval.append((fd, revents))

            lltype.free(info, flavor='raw')

        finally:
            for fd, event in eventdict.iteritems():
                _c.WSAEventSelect(fd, event, 0)
                _c.WSACloseEvent(event)
            lltype.free(socketevents, flavor='raw')

        return retval
Example #22
0
    def poll(fddict, timeout=-1):
        """'fddict' maps file descriptors to interesting events.
        'timeout' is an integer in milliseconds, and NOT a float
        number of seconds, but it's the same in CPython.  Use -1 for infinite.
        Returns a list [(fd, events)].
        """
        numfd = len(fddict)
        numevents = 0
        socketevents = lltype.malloc(_c.WSAEVENT_ARRAY, numfd, flavor='raw')
        try:
            eventdict = {}

            for fd, events in fddict.iteritems():
                # select desired events
                wsaEvents = 0
                if events & _c.POLLIN:
                    wsaEvents |= _c.FD_READ | _c.FD_ACCEPT | _c.FD_CLOSE
                if events & _c.POLLOUT:
                    wsaEvents |= _c.FD_WRITE | _c.FD_CONNECT | _c.FD_CLOSE

                # if no events then ignore socket
                if wsaEvents == 0:
                    continue

                # select socket for desired events
                event = _c.WSACreateEvent()
                _c.WSAEventSelect(fd, event, wsaEvents)

                eventdict[fd] = event
                socketevents[numevents] = event
                numevents += 1

            assert numevents <= numfd

            # if no sockets then return immediately
            # XXX commented out by arigo - we just want to sleep for
            #     'timeout' milliseconds in this case, which is what
            #     I hope WSAWaitForMultipleEvents will do, no?
            #if numevents == 0:
            #    return []

            # prepare timeout
            if timeout < 0:
                timeout = _c.INFINITE

            ret = _c.WSAWaitForMultipleEvents(numevents, socketevents, False,
                                              timeout, False)

            if ret == _c.WSA_WAIT_TIMEOUT:
                return []

            if ret == _c.WSA_WAIT_FAILED:
                raise PollError(_c.geterrno())

            retval = []
            info = rffi.make(_c.WSANETWORKEVENTS)
            for fd, event in eventdict.iteritems():
                if _c.WSAEnumNetworkEvents(fd, event, info) < 0:
                    continue
                revents = 0
                if info.c_lNetworkEvents & _c.FD_READ:
                    revents |= _c.POLLIN
                if info.c_lNetworkEvents & _c.FD_ACCEPT:
                    revents |= _c.POLLIN
                if info.c_lNetworkEvents & _c.FD_WRITE:
                    revents |= _c.POLLOUT
                if info.c_lNetworkEvents & _c.FD_CONNECT:
                    if info.c_iErrorCode[_c.FD_CONNECT_BIT]:
                        revents |= _c.POLLERR
                    else:
                        revents |= _c.POLLOUT
                if info.c_lNetworkEvents & _c.FD_CLOSE:
                    if info.c_iErrorCode[_c.FD_CLOSE_BIT]:
                        revents |= _c.POLLERR
                    else:
                        if fddict[fd] & _c.POLLIN:
                            revents |= _c.POLLIN
                        if fddict[fd] & _c.POLLOUT:
                            revents |= _c.POLLOUT
                if revents:
                    retval.append((fd, revents))

            lltype.free(info, flavor='raw')

        finally:
            for i in range(numevents):
                _c.WSACloseEvent(socketevents[i])
            lltype.free(socketevents, flavor='raw')

        return retval
Example #23
0
def _get_api_ptr():
    api_ptr = rffi.make(api_type)
    for fn_name, fn, fn_ll_type, _, _ in _API_FUNCS_iterable:
        setattr(api_ptr, fn_name, rffi.llhelper(fn_ll_type, fn))
    return api_ptr