1cdef class PseudoSocket:
2    cdef:
3        int _family
4        int _type
5        int _proto
6        int _fd
7        object _peername
8        object _sockname
9
10    def __init__(self, int family, int type, int proto, int fd):
11        self._family = family
12        self._type = type
13        self._proto = proto
14        self._fd = fd
15        self._peername = None
16        self._sockname = None
17
18    cdef _na(self, what):
19        raise TypeError('transport sockets do not support {}'.format(what))
20
21    cdef _make_sock(self):
22        return socket_socket(self._family, self._type, self._proto, self._fd)
23
24    property family:
25        def __get__(self):
26            try:
27                return socket_AddressFamily(self._family)
28            except ValueError:
29                return self._family
30
31    property type:
32        def __get__(self):
33            try:
34                return socket_SocketKind(self._type)
35            except ValueError:
36                return self._type
37
38    property proto:
39        def __get__(self):
40            return self._proto
41
42    def __repr__(self):
43        s = ("<uvloop.PseudoSocket fd={}, family={!s}, "
44             "type={!s}, proto={}").format(self.fileno(), self.family,
45                                           self.type, self.proto)
46
47        if self._fd != -1:
48            try:
49                laddr = self.getsockname()
50                if laddr:
51                    s += ", laddr=%s" % str(laddr)
52            except socket_error:
53                pass
54            try:
55                raddr = self.getpeername()
56                if raddr:
57                    s += ", raddr=%s" % str(raddr)
58            except socket_error:
59                pass
60        s += '>'
61        return s
62
63    def __getstate__(self):
64        raise TypeError("Cannot serialize socket object")
65
66    def fileno(self):
67        return self._fd
68
69    def dup(self):
70        fd = os_dup(self._fd)
71        sock = socket_socket(self._family, self._type, self._proto, fileno=fd)
72        sock.settimeout(0)
73        return sock
74
75    def get_inheritable(self):
76        return os_get_inheritable(self._fd)
77
78    def set_inheritable(self):
79        os_set_inheritable(self._fd)
80
81    def ioctl(self, *args, **kwargs):
82        pass
83
84    def getsockopt(self, *args, **kwargs):
85        sock = self._make_sock()
86        try:
87            return sock.getsockopt(*args, **kwargs)
88        finally:
89            sock.detach()
90
91    def setsockopt(self, *args, **kwargs):
92        sock = self._make_sock()
93        try:
94            return sock.setsockopt(*args, **kwargs)
95        finally:
96            sock.detach()
97
98    def getpeername(self):
99        if self._peername is not None:
100            return self._peername
101
102        sock = self._make_sock()
103        try:
104            self._peername = sock.getpeername()
105            return self._peername
106        finally:
107            sock.detach()
108
109    def getsockname(self):
110        if self._sockname is not None:
111            return self._sockname
112
113        sock = self._make_sock()
114        try:
115            self._sockname = sock.getsockname()
116            return self._sockname
117        finally:
118            sock.detach()
119
120    def share(self, process_id):
121        sock = self._make_sock()
122        try:
123            return sock.share(process_id)
124        finally:
125            sock.detach()
126
127    def accept(self):
128        self._na('accept() method')
129
130    def connect(self, *args):
131        self._na('connect() method')
132
133    def connect_ex(self, *args):
134        self._na('connect_ex() method')
135
136    def bind(self, *args):
137        self._na('bind() method')
138
139    def listen(self, *args, **kwargs):
140        self._na('listen() method')
141
142    def makefile(self):
143        self._na('makefile() method')
144
145    def sendfile(self, *args, **kwargs):
146        self._na('sendfile() method')
147
148    def close(self):
149        self._na('close() method')
150
151    def detach(self):
152        self._na('detach() method')
153
154    def shutdown(self, *args):
155        self._na('shutdown() method')
156
157    def sendmsg_afalg(self, *args, **kwargs):
158        self._na('sendmsg_afalg() method')
159
160    def sendmsg(self):
161        self._na('sendmsg() method')
162
163    def sendto(self, *args, **kwargs):
164        self._na('sendto() method')
165
166    def send(self, *args, **kwargs):
167        self._na('send() method')
168
169    def sendall(self, *args, **kwargs):
170        self._na('sendall() method')
171
172    def recv_into(self, *args, **kwargs):
173        self._na('recv_into() method')
174
175    def recvfrom_into(self, *args, **kwargs):
176        self._na('recvfrom_into() method')
177
178    def recvmsg_into(self, *args, **kwargs):
179        self._na('recvmsg_into() method')
180
181    def recvmsg(self, *args, **kwargs):
182        self._na('recvmsg() method')
183
184    def recvfrom(self, *args, **kwargs):
185        self._na('recvfrom() method')
186
187    def recv(self, *args, **kwargs):
188        self._na('recv() method')
189
190    def settimeout(self, value):
191        if value == 0:
192            return
193        raise ValueError(
194            'settimeout(): only 0 timeout is allowed on transport sockets')
195
196    def gettimeout(self):
197        return 0
198
199    def setblocking(self, flag):
200        if not flag:
201            return
202        raise ValueError(
203            'setblocking(): transport sockets cannot be blocking')
204
205    def __enter__(self):
206        self._na('context manager protocol')
207
208    def __exit__(self, *err):
209        self._na('context manager protocol')
210