blob: 0410aa7966173884fee19f3588374978c66ba0e3 [file] [log] [blame]
Guido van Rossum80b0fa01996-06-26 19:52:38 +00001"Socket wrapper for Windows, which does not support dup()."
2
Guido van Rossum80b0fa01996-06-26 19:52:38 +00003# (And hence, fromfd() and makefile() are unimplemented in C....)
4
5# XXX Living dangerously here -- close() is implemented by deleting a
6# reference. Thus we rely on the real _socket module to close on
7# deallocation, and also hope that nobody keeps a reference to our _sock
8# member.
9
10
11
12try:
Guido van Rossum1847d061998-03-26 20:22:30 +000013 from _socket import *
Guido van Rossum80b0fa01996-06-26 19:52:38 +000014except ImportError:
Guido van Rossum1847d061998-03-26 20:22:30 +000015 from socket import *
Guido van Rossum80b0fa01996-06-26 19:52:38 +000016
17_realsocketcall = socket
18
19
20def socket(family, type, proto=0):
Guido van Rossum1847d061998-03-26 20:22:30 +000021 return _socketobject(_realsocketcall(family, type, proto))
Guido van Rossum80b0fa01996-06-26 19:52:38 +000022
23
24class _socketobject:
25
Guido van Rossum1847d061998-03-26 20:22:30 +000026 def __init__(self, sock):
27 self._sock = sock
Guido van Rossum80b0fa01996-06-26 19:52:38 +000028
Guido van Rossum1847d061998-03-26 20:22:30 +000029 def close(self):
30 self._sock = 0
Guido van Rossum80b0fa01996-06-26 19:52:38 +000031
Guido van Rossum1847d061998-03-26 20:22:30 +000032 def __del__(self):
33 self.close()
Guido van Rossum80b0fa01996-06-26 19:52:38 +000034
Guido van Rossum1847d061998-03-26 20:22:30 +000035 def accept(self):
36 sock, addr = self._sock.accept()
37 return _socketobject(sock), addr
Guido van Rossum80b0fa01996-06-26 19:52:38 +000038
Guido van Rossum1847d061998-03-26 20:22:30 +000039 def dup(self):
40 return _socketobject(self._sock)
Guido van Rossum80b0fa01996-06-26 19:52:38 +000041
Guido van Rossum1847d061998-03-26 20:22:30 +000042 def makefile(self, mode='r', bufsize=-1):
43 return _fileobject(self._sock, mode, bufsize)
Guido van Rossum80b0fa01996-06-26 19:52:38 +000044
Guido van Rossum1847d061998-03-26 20:22:30 +000045 _s = "def %s(self, *args): return apply(self._sock.%s, args)\n\n"
Guido van Rossum64d036c1998-04-14 01:30:45 +000046 for _m in ('bind', 'connect', 'connect_ex', 'fileno', 'listen',
Guido van Rossum1847d061998-03-26 20:22:30 +000047 'getpeername', 'getsockname',
48 'getsockopt', 'setsockopt',
49 'recv', 'recvfrom', 'send', 'sendto',
50 'setblocking',
51 'shutdown'):
52 exec _s % (_m, _m)
Guido van Rossum80b0fa01996-06-26 19:52:38 +000053
54
55class _fileobject:
56
Guido van Rossum1847d061998-03-26 20:22:30 +000057 def __init__(self, sock, mode, bufsize):
58 self._sock = sock
59 self._mode = mode
60 if bufsize < 0:
61 bufsize = 512
62 self._rbufsize = max(1, bufsize)
63 self._wbufsize = bufsize
64 self._wbuf = self._rbuf = ""
Guido van Rossum80b0fa01996-06-26 19:52:38 +000065
Guido van Rossum1847d061998-03-26 20:22:30 +000066 def close(self):
67 try:
68 if self._sock:
69 self.flush()
70 finally:
71 self._sock = 0
Guido van Rossum80b0fa01996-06-26 19:52:38 +000072
Guido van Rossum1847d061998-03-26 20:22:30 +000073 def __del__(self):
74 self.close()
Guido van Rossum80b0fa01996-06-26 19:52:38 +000075
Guido van Rossum1847d061998-03-26 20:22:30 +000076 def flush(self):
77 if self._wbuf:
78 self._sock.send(self._wbuf)
79 self._wbuf = ""
Guido van Rossum80b0fa01996-06-26 19:52:38 +000080
Guido van Rossum1847d061998-03-26 20:22:30 +000081 def fileno(self):
82 return self._sock.fileno()
Guido van Rossum80b0fa01996-06-26 19:52:38 +000083
Guido van Rossum1847d061998-03-26 20:22:30 +000084 def write(self, data):
85 self._wbuf = self._wbuf + data
86 if self._wbufsize == 1:
87 if '\n' in data:
88 self.flush()
89 else:
90 if len(self._wbuf) >= self._wbufsize:
91 self.flush()
92
93 def writelines(self, list):
94 filter(self._sock.send, list)
Guido van Rossum80b0fa01996-06-26 19:52:38 +000095 self.flush()
96
Guido van Rossum1847d061998-03-26 20:22:30 +000097 def read(self, n=-1):
98 if n >= 0:
Guido van Rossum75a79592000-02-02 16:57:32 +000099 k = len(self._rbuf)
100 if n <= k:
101 data = self._rbuf[:n]
102 self._rbuf = self._rbuf[n:]
103 return data
104 n = n - k
105 l = [self._rbuf]
106 self._rbuf = ""
107 while n > 0:
108 new = self._sock.recv(max(n, self._rbufsize))
Guido van Rossum1847d061998-03-26 20:22:30 +0000109 if not new: break
Guido van Rossum75a79592000-02-02 16:57:32 +0000110 k = len(new)
111 if k > n:
112 l.append(new[:n])
113 self._rbuf = new[n:]
114 break
115 l.append(new)
116 n = n - k
117 return "".join(l)
118 k = max(512, self._rbufsize)
119 l = [self._rbuf]
120 self._rbuf = ""
Guido van Rossum1847d061998-03-26 20:22:30 +0000121 while 1:
Guido van Rossum75a79592000-02-02 16:57:32 +0000122 new = self._sock.recv(k)
Guido van Rossum1847d061998-03-26 20:22:30 +0000123 if not new: break
Guido van Rossum75a79592000-02-02 16:57:32 +0000124 l.append(new)
125 k = min(k*2, 1024**2)
126 return "".join(l)
Guido van Rossum80b0fa01996-06-26 19:52:38 +0000127
Guido van Rossum75a79592000-02-02 16:57:32 +0000128 def readline(self, limit=-1):
Guido van Rossum1847d061998-03-26 20:22:30 +0000129 data = ""
Guido van Rossum75a79592000-02-02 16:57:32 +0000130 i = self._rbuf.find('\n')
131 while i < 0 and not (0 < limit <= len(self._rbuf)):
Guido van Rossum1847d061998-03-26 20:22:30 +0000132 new = self._sock.recv(self._rbufsize)
133 if not new: break
Guido van Rossum75a79592000-02-02 16:57:32 +0000134 i = new.find('\n')
Guido van Rossum1847d061998-03-26 20:22:30 +0000135 if i >= 0: i = i + len(self._rbuf)
136 self._rbuf = self._rbuf + new
137 if i < 0: i = len(self._rbuf)
138 else: i = i+1
Guido van Rossum75a79592000-02-02 16:57:32 +0000139 if 0 <= limit < len(self._rbuf): i = limit
Guido van Rossum1847d061998-03-26 20:22:30 +0000140 data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
141 return data
Guido van Rossum80b0fa01996-06-26 19:52:38 +0000142
Guido van Rossum1847d061998-03-26 20:22:30 +0000143 def readlines(self):
144 list = []
145 while 1:
146 line = self.readline()
147 if not line: break
148 list.append(line)
149 return list
Guido van Rossumd618c911998-05-06 13:48:04 +0000150
151
152# WSA error codes
153errorTab = {}
154errorTab[10004] = "The operation was interrupted."
155errorTab[10009] = "A bad file handle was passed."
156errorTab[10013] = "Permission denied."
157errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
158errorTab[10022] = "An invalid operation was attempted."
159errorTab[10035] = "The socket operation would block"
160errorTab[10036] = "A blocking operation is already in progress."
161errorTab[10048] = "The network address is in use."
162errorTab[10054] = "The connection has been reset."
163errorTab[10058] = "The network has been shut down."
164errorTab[10060] = "The operation timed out."
165errorTab[10061] = "Connection refused."
166errorTab[10063] = "The name is too long."
167errorTab[10064] = "The host is down."
168errorTab[10065] = "The host is unreachable."