blob: 8cacfb2793ff5b6f573ca79d0b27768c841cf6af [file] [log] [blame]
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001/***********************************************************
Guido van Rossumb6775db1994-08-01 11:34:53 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossume5372401993-03-16 12:15:04 +00003Amsterdam, The Netherlands.
Guido van Rossum6574b3e1991-06-25 21:36:08 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Socket module */
26
27/*
28This module provides an interface to Berkeley socket IPC.
29
30Limitations:
31
Guido van Rossum30a685f1991-06-27 15:51:29 +000032- only AF_INET and AF_UNIX address families are supported
Guido van Rossumb6775db1994-08-01 11:34:53 +000033- no asynchronous I/O (but you can use select() on sockets)
Guido van Rossum81194471991-07-27 21:42:02 +000034- no read/write operations (use send/recv or makefile instead)
Guido van Rossum0e69587d1992-06-05 15:11:30 +000035- setsockopt() and getsockopt() only support integer options
Guido van Rossum6574b3e1991-06-25 21:36:08 +000036
37Interface:
38
Guido van Rossum81194471991-07-27 21:42:02 +000039- socket.gethostname() --> host name (string)
Guido van Rossum30a685f1991-06-27 15:51:29 +000040- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +000041- socket.getservbyname(servername, protocolname) --> port number
42- socket.socket(family, type [, proto]) --> new socket object
Guido van Rossum6574b3e1991-06-25 21:36:08 +000043- family and type constants from <socket.h> are accessed as socket.AF_INET etc.
Guido van Rossum6574b3e1991-06-25 21:36:08 +000044- errors are reported as the exception socket.error
45- an Internet socket address is a pair (hostname, port)
46 where hostname can be anything recognized by gethostbyname()
47 (including the dd.dd.dd.dd notation) and port is in host byte order
48- where a hostname is returned, the dd.dd.dd.dd notation is used
49- a UNIX domain socket is a string specifying the pathname
50
Guido van Rossum30a685f1991-06-27 15:51:29 +000051Socket methods:
Guido van Rossum6574b3e1991-06-25 21:36:08 +000052
Guido van Rossum81194471991-07-27 21:42:02 +000053- s.accept() --> new socket object, sockaddr
Guido van Rossum0e69587d1992-06-05 15:11:30 +000054- s.setsockopt(level, optname, flag) --> None
55- s.getsockopt(level, optname) --> flag
Guido van Rossum30a685f1991-06-27 15:51:29 +000056- s.bind(sockaddr) --> None
57- s.connect(sockaddr) --> None
Guido van Rossumc89705d1992-11-26 08:54:07 +000058- s.getsockname() --> sockaddr
59- s.getpeername() --> sockaddr
Guido van Rossum30a685f1991-06-27 15:51:29 +000060- s.listen(n) --> None
61- s.makefile(mode) --> file object
Guido van Rossumeb6b33a1993-05-25 09:38:27 +000062- s.recv(nbytes [,flags]) --> string
Guido van Rossum18c9a4f1993-05-25 12:16:29 +000063- s.recvfrom(nbytes [,flags]) --> string, sockaddr
Guido van Rossumb6775db1994-08-01 11:34:53 +000064- s.send(string [,flags]) --> nbytes
65- s.sendto(string, [flags,] sockaddr) --> nbytes
Guido van Rossum30a685f1991-06-27 15:51:29 +000066- s.shutdown(how) --> None
67- s.close() --> None
68
Guido van Rossum6574b3e1991-06-25 21:36:08 +000069*/
70
71#include "allobjects.h"
72#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000073#include "ceval.h"
Guido van Rossum6574b3e1991-06-25 21:36:08 +000074
Guido van Rossumb6775db1994-08-01 11:34:53 +000075#include <sys/types.h>
76#include "mytime.h"
Guido van Rossumed233a51992-06-23 09:07:03 +000077
Guido van Rossum81194471991-07-27 21:42:02 +000078#include <signal.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000079#ifndef NT
Guido van Rossumb6775db1994-08-01 11:34:53 +000080#include <netdb.h>
Guido van Rossum6574b3e1991-06-25 21:36:08 +000081#include <sys/socket.h>
82#include <netinet/in.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000083#else
84#include <winsock.h>
85#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000086#ifdef HAVE_SYS_UN_H
Guido van Rossum6574b3e1991-06-25 21:36:08 +000087#include <sys/un.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000088#else
89#undef AF_UNIX
Guido van Rossum9575a441993-04-07 14:06:14 +000090#endif
91
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000092/* Here we have some hacks to choose between K&R or ANSI style function
93 definitions. For NT to build this as an extension module (ie, DLL)
94 it must be compiled by the C++ compiler, as it takes the address of
95 a static data item exported from the main Python DLL.
96*/
97#ifdef NT
98/* seem to be a few differences in the API */
99#define close closesocket
100#define NO_DUP /* I wont trust passing a socket to NT's RTL!! */
101#define FORCE_ANSI_FUNC_DEFS
102#endif
103
104#ifdef FORCE_ANSI_FUNC_DEFS
105#define BUILD_FUNC_DEF_1( fnname, arg1type, arg1name ) \
106fnname( arg1type arg1name )
107
108#define BUILD_FUNC_DEF_2( fnname, arg1type, arg1name, arg2type, arg2name ) \
109fnname( arg1type arg1name, arg2type arg2name )
110
111#define BUILD_FUNC_DEF_3( fnname, arg1type, arg1name, arg2type, arg2name , arg3type, arg3name ) \
112fnname( arg1type arg1name, arg2type arg2name, arg3type arg3name )
113
114#define BUILD_FUNC_DEF_4( fnname, arg1type, arg1name, arg2type, arg2name , arg3type, arg3name, arg4type, arg4name ) \
115fnname( arg1type arg1name, arg2type arg2name, arg3type arg3name, arg4type arg4name )
116
117#else /* !FORCE_ANSI_FN_DEFS */
118#define BUILD_FUNC_DEF_1( fnname, arg1type, arg1name ) \
119fnname( arg1name ) \
120 arg1type arg1name;
121
122#define BUILD_FUNC_DEF_2( fnname, arg1type, arg1name, arg2type, arg2name ) \
123fnname( arg1name, arg2name ) \
124 arg1type arg1name; \
125 arg2type arg2name;
126
127#define BUILD_FUNC_DEF_3( fnname, arg1type, arg1name, arg2type, arg2name, arg3type, arg3name ) \
128fnname( arg1name, arg2name, arg3name ) \
129 arg1type arg1name; \
130 arg2type arg2name; \
131 arg3type arg3name;
132
133#define BUILD_FUNC_DEF_4( fnname, arg1type, arg1name, arg2type, arg2name, arg3type, arg3name, arg4type, arg4name ) \
134fnname( arg1name, arg2name, arg3name, arg4name ) \
135 arg1type arg1name; \
136 arg2type arg2name; \
137 arg3type arg3name; \
138 arg4type arg4name;
139
140#endif /* !FORCE_ANSI_FN_DEFS */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000141
142/* Global variable holding the exception type for errors detected
143 by this module (but not argument type or memory errors, etc.). */
144
145static object *SocketError;
146
147
148/* Convenience function to raise an error according to errno
149 and return a NULL pointer from a function. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000150
151static object *
152socket_error()
153{
154 return err_errno(SocketError);
155}
156
Guido van Rossum30a685f1991-06-27 15:51:29 +0000157
158/* The object holding a socket. It holds some extra information,
159 like the address family, which is used to decode socket address
160 arguments properly. */
161
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000162typedef struct {
163 OB_HEAD
Guido van Rossum30a685f1991-06-27 15:51:29 +0000164 int sock_fd; /* Socket file descriptor */
165 int sock_family; /* Address family, e.g., AF_INET */
166 int sock_type; /* Socket type, e.g., SOCK_STREAM */
167 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000168} sockobject;
169
Guido van Rossum30a685f1991-06-27 15:51:29 +0000170
171/* A forward reference to the Socktype type object.
172 The Socktype variable contains pointers to various functions,
173 some of which call newsocobject(), which uses Socktype, so
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000174 there has to be a circular reference. */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000175
Guido van Rossumb6775db1994-08-01 11:34:53 +0000176staticforward typeobject Socktype;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000177
Guido van Rossum30a685f1991-06-27 15:51:29 +0000178
179/* Create a new socket object.
180 This just creates the object and initializes it.
181 If the creation fails, return NULL and set an exception (implicit
182 in NEWOBJ()). */
183
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000184static sockobject *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185BUILD_FUNC_DEF_4(newsockobject, int, fd, int, family, int, type, int, proto)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000186{
187 sockobject *s;
188 s = NEWOBJ(sockobject, &Socktype);
189 if (s != NULL) {
190 s->sock_fd = fd;
191 s->sock_family = family;
192 s->sock_type = type;
193 s->sock_proto = proto;
194 }
195 return s;
196}
197
Guido van Rossum30a685f1991-06-27 15:51:29 +0000198
199/* Convert a string specifying a host name or one of a few symbolic
200 names to a numeric IP address. This usually calls gethostbyname()
201 to do the work; the names "" and "<broadcast>" are special.
202 Return the length (should always be 4 bytes), or negative if
203 an error occurred; then an exception is raised. */
204
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000205static int
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000206BUILD_FUNC_DEF_2(setipaddr, char*, name, struct sockaddr_in *, addr_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000207{
208 struct hostent *hp;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000209 int d1, d2, d3, d4;
210 char ch;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000211
Guido van Rossum30a685f1991-06-27 15:51:29 +0000212 if (name[0] == '\0') {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000213 addr_ret->sin_addr.s_addr = INADDR_ANY;
214 return 4;
215 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000216 if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000217 addr_ret->sin_addr.s_addr = INADDR_BROADCAST;
218 return 4;
219 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000220 if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
221 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
222 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
223 addr_ret->sin_addr.s_addr = htonl(
224 ((long) d1 << 24) | ((long) d2 << 16) |
225 ((long) d3 << 8) | ((long) d4 << 0));
226 return 4;
227 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000228 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000229 hp = gethostbyname(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000230 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000231 if (hp == NULL) {
232 err_setstr(SocketError, "host not found");
233 return -1;
234 }
235 memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
236 return hp->h_length;
237}
238
Guido van Rossum30a685f1991-06-27 15:51:29 +0000239
Guido van Rossum30a685f1991-06-27 15:51:29 +0000240/* Create a string object representing an IP address.
241 This is always a string of the form 'dd.dd.dd.dd' (with variable
242 size numbers). */
243
244static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000245BUILD_FUNC_DEF_1(makeipaddr, struct sockaddr_in *,addr)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000246{
247 long x = ntohl(addr->sin_addr.s_addr);
248 char buf[100];
249 sprintf(buf, "%d.%d.%d.%d",
250 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
251 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
252 return newstringobject(buf);
253}
254
255
256/* Create an object representing the given socket address,
257 suitable for passing it back to bind(), connect() etc.
258 The family field of the sockaddr structure is inspected
259 to determine what kind of address it really is. */
260
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000261/*ARGSUSED*/
262static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000263BUILD_FUNC_DEF_2(makesockaddr,struct sockaddr *, addr, int, addrlen)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000264{
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000265 if (addrlen == 0) {
266 /* No address -- may be recvfrom() from known socket */
267 INCREF(None);
268 return None;
269 }
270
Guido van Rossum30a685f1991-06-27 15:51:29 +0000271 switch (addr->sa_family) {
272
273 case AF_INET:
274 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000275 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum6f5afc91993-02-05 09:46:15 +0000276 object *addr = makeipaddr(a);
277 object *ret = mkvalue("Oi", addr, ntohs(a->sin_port));
278 XDECREF(addr);
279 return ret;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000280 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000281
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#ifdef AF_UNIX
Guido van Rossum30a685f1991-06-27 15:51:29 +0000283 case AF_UNIX:
284 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000285 struct sockaddr_un *a = (struct sockaddr_un *) addr;
286 return newstringobject(a->sun_path);
287 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288#endif /* AF_UNIX */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000289
290 /* More cases here... */
291
292 default:
293 err_setstr(SocketError, "return unknown socket address type");
294 return NULL;
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000295
Guido van Rossum30a685f1991-06-27 15:51:29 +0000296 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000297}
298
Guido van Rossum30a685f1991-06-27 15:51:29 +0000299
300/* Parse a socket address argument according to the socket object's
301 address family. Return 1 if the address was in the proper format,
302 0 of not. The address is returned through addr_ret, its length
303 through len_ret. */
304
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000305static int
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000306BUILD_FUNC_DEF_4(
307getsockaddrarg,sockobject *,s, object *,args, struct sockaddr **,addr_ret, int *,len_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000308{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000309 switch (s->sock_family) {
310
Guido van Rossumb6775db1994-08-01 11:34:53 +0000311#ifdef AF_UNIX
Guido van Rossum30a685f1991-06-27 15:51:29 +0000312 case AF_UNIX:
313 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000314 static struct sockaddr_un addr;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000315 char *path;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000316 int len;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000317 if (!getargs(args, "s#", &path, &len))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000318 return 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000319 if (len > sizeof addr.sun_path) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000320 err_setstr(SocketError, "AF_UNIX path too long");
321 return 0;
322 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000323 addr.sun_family = AF_UNIX;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000324 memcpy(addr.sun_path, path, len);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000325 *addr_ret = (struct sockaddr *) &addr;
326 *len_ret = len + sizeof addr.sun_family;
327 return 1;
328 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000329#endif /* AF_UNIX */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000330
Guido van Rossum30a685f1991-06-27 15:51:29 +0000331 case AF_INET:
332 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000333 static struct sockaddr_in addr;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000334 char *host;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000335 int port;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000336 if (!getargs(args, "(si)", &host, &port))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000337 return 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000338 if (setipaddr(host, &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000339 return 0;
340 addr.sin_family = AF_INET;
341 addr.sin_port = htons(port);
342 *addr_ret = (struct sockaddr *) &addr;
343 *len_ret = sizeof addr;
344 return 1;
345 }
346
Guido van Rossum30a685f1991-06-27 15:51:29 +0000347 /* More cases here... */
348
349 default:
350 err_setstr(SocketError, "getsockaddrarg: bad family");
351 return 0;
352
353 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000354}
355
Guido van Rossum30a685f1991-06-27 15:51:29 +0000356
Guido van Rossum710e1df1992-06-12 10:39:36 +0000357/* Get the address length according to the socket object's address family.
358 Return 1 if the family is known, 0 otherwise. The length is returned
359 through len_ret. */
360
361static int
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000362BUILD_FUNC_DEF_2(getsockaddrlen,sockobject *,s, int *,len_ret)
Guido van Rossum710e1df1992-06-12 10:39:36 +0000363{
364 switch (s->sock_family) {
365
Guido van Rossumb6775db1994-08-01 11:34:53 +0000366#ifdef AF_UNIX
Guido van Rossum710e1df1992-06-12 10:39:36 +0000367 case AF_UNIX:
368 {
369 *len_ret = sizeof (struct sockaddr_un);
370 return 1;
371 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000372#endif /* AF_UNIX */
Guido van Rossum710e1df1992-06-12 10:39:36 +0000373
374 case AF_INET:
375 {
376 *len_ret = sizeof (struct sockaddr_in);
377 return 1;
378 }
379
380 /* More cases here... */
381
382 default:
383 err_setstr(SocketError, "getsockaddrarg: bad family");
384 return 0;
385
386 }
387}
388
389
Guido van Rossum30a685f1991-06-27 15:51:29 +0000390/* s.accept() method */
391
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000392static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000393BUILD_FUNC_DEF_2(sock_accept,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000394{
395 char addrbuf[256];
396 int addrlen, newfd;
Guido van Rossum6f5afc91993-02-05 09:46:15 +0000397 object *sock, *addr, *res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000398 if (!getnoarg(args))
399 return NULL;
Guido van Rossum710e1df1992-06-12 10:39:36 +0000400 if (!getsockaddrlen(s, &addrlen))
401 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000402 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000403 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000404 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000405 if (newfd < 0)
406 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000407 /* Create the new object with unspecified family,
408 to avoid calls to bind() etc. on it. */
Guido van Rossum6f5afc91993-02-05 09:46:15 +0000409 sock = (object *) newsockobject(newfd,
410 s->sock_family,
411 s->sock_type,
412 s->sock_proto);
413 if (sock == NULL)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000414 close(newfd);
Guido van Rossum6f5afc91993-02-05 09:46:15 +0000415 addr = makesockaddr((struct sockaddr *) addrbuf, addrlen);
416 res = mkvalue("OO", sock, addr);
417 XDECREF(sock);
418 XDECREF(addr);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000419 return res;
420}
421
Guido van Rossum30a685f1991-06-27 15:51:29 +0000422
Guido van Rossumc65a5251994-08-05 13:44:50 +0000423#if 0
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000424/* s.allowbroadcast() method */
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000425/* XXX obsolete -- will disappear in next release */
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000426
427static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000428BUILD_FUNC_DEF_2(sock_allowbroadcast,sockobject *,s, object *,args)
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000429{
430 int flag;
431 int res;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000432 if (!getargs(args, "i", &flag))
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000433 return NULL;
434 res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000435 (ANY *)&flag, sizeof flag);
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000436 if (res < 0)
437 return socket_error();
438 INCREF(None);
439 return None;
440}
Guido van Rossumc65a5251994-08-05 13:44:50 +0000441#endif
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000442
443
Guido van Rossumaee08791992-09-08 09:05:33 +0000444/* s.setsockopt() method.
445 With an integer third argument, sets an integer option.
446 With a string third argument, sets an option from a buffer;
447 use optional built-in module 'struct' to encode the string. */
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000448
449static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000450BUILD_FUNC_DEF_2(sock_setsockopt,sockobject *,s, object *,args)
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000451{
452 int level;
453 int optname;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000454 int res;
Guido van Rossumaee08791992-09-08 09:05:33 +0000455 char *buf;
456 int buflen;
457 int flag;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000458
Guido van Rossumaee08791992-09-08 09:05:33 +0000459 if (getargs(args, "(iii)", &level, &optname, &flag)) {
460 buf = (char *) &flag;
461 buflen = sizeof flag;
462 }
463 else {
464 err_clear();
465 if (!getargs(args, "(iis#)", &level, &optname, &buf, &buflen))
466 return NULL;
467 }
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000468 res = setsockopt(s->sock_fd, level, optname, (ANY *)buf, buflen);
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000469 if (res < 0)
470 return socket_error();
471 INCREF(None);
472 return None;
473}
474
475
Guido van Rossumaee08791992-09-08 09:05:33 +0000476/* s.getsockopt() method.
477 With two arguments, retrieves an integer option.
478 With a third integer argument, retrieves a string buffer of that size;
479 use optional built-in module 'struct' to decode the string. */
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000480
481static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000482BUILD_FUNC_DEF_2(sock_getsockopt,sockobject *,s, object *,args)
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000483{
484 int level;
485 int optname;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000486 int res;
Guido van Rossumaee08791992-09-08 09:05:33 +0000487 object *buf;
488 int buflen;
489 int flag;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000490
Guido van Rossumaee08791992-09-08 09:05:33 +0000491 if (getargs(args, "(ii)", &level, &optname)) {
492 int flag = 0;
493 int flagsize = sizeof flag;
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000494 res = getsockopt(s->sock_fd, level, optname,
495 (ANY *)&flag, &flagsize);
Guido van Rossumaee08791992-09-08 09:05:33 +0000496 if (res < 0)
497 return socket_error();
498 return newintobject(flag);
499 }
500 err_clear();
501 if (!getargs(args, "(iii)", &level, &optname, &buflen))
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000502 return NULL;
Guido van Rossumaee08791992-09-08 09:05:33 +0000503 if (buflen <= 0 || buflen > 1024) {
504 err_setstr(SocketError, "getsockopt buflen out of range");
505 return NULL;
506 }
507 buf = newsizedstringobject((char *)NULL, buflen);
508 if (buf == NULL)
509 return NULL;
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000510 res = getsockopt(s->sock_fd, level, optname,
511 (ANY *)getstringvalue(buf), &buflen);
Guido van Rossumaee08791992-09-08 09:05:33 +0000512 if (res < 0) {
513 DECREF(buf);
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000514 return socket_error();
Guido van Rossumaee08791992-09-08 09:05:33 +0000515 }
516 resizestring(&buf, buflen);
517 return buf;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000518}
519
520
Guido van Rossum30a685f1991-06-27 15:51:29 +0000521/* s.bind(sockaddr) method */
522
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000523static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000524BUILD_FUNC_DEF_2(sock_bind,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000525{
526 struct sockaddr *addr;
527 int addrlen;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000528 int res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000529 if (!getsockaddrarg(s, args, &addr, &addrlen))
530 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000531 BGN_SAVE
532 res = bind(s->sock_fd, addr, addrlen);
533 END_SAVE
534 if (res < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000535 return socket_error();
536 INCREF(None);
537 return None;
538}
539
Guido van Rossum30a685f1991-06-27 15:51:29 +0000540
541/* s.close() method.
542 Set the file descriptor to -1 so operations tried subsequently
543 will surely fail. */
544
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000545static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000546BUILD_FUNC_DEF_2(sock_close,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000547{
548 if (!getnoarg(args))
549 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000550 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000551 (void) close(s->sock_fd);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000552 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000553 s->sock_fd = -1;
554 INCREF(None);
555 return None;
556}
557
Guido van Rossum30a685f1991-06-27 15:51:29 +0000558
559/* s.connect(sockaddr) method */
560
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000561static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000562BUILD_FUNC_DEF_2(sock_connect,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000563{
564 struct sockaddr *addr;
565 int addrlen;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000566 int res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000567 if (!getsockaddrarg(s, args, &addr, &addrlen))
568 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000569 BGN_SAVE
570 res = connect(s->sock_fd, addr, addrlen);
571 END_SAVE
572 if (res < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000573 return socket_error();
574 INCREF(None);
575 return None;
576}
577
Guido van Rossum30a685f1991-06-27 15:51:29 +0000578
Guido van Rossumed233a51992-06-23 09:07:03 +0000579/* s.fileno() method */
580
581static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000582BUILD_FUNC_DEF_2(sock_fileno,sockobject *,s, object *,args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000583{
584 if (!getnoarg(args))
585 return NULL;
586 return newintobject((long) s->sock_fd);
587}
588
589
Guido van Rossumc89705d1992-11-26 08:54:07 +0000590/* s.getsockname() method */
591
592static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000593BUILD_FUNC_DEF_2(sock_getsockname,sockobject *,s, object *,args)
Guido van Rossumc89705d1992-11-26 08:54:07 +0000594{
595 char addrbuf[256];
596 int addrlen, res;
597 if (!getnoarg(args))
598 return NULL;
599 if (!getsockaddrlen(s, &addrlen))
600 return NULL;
601 BGN_SAVE
602 res = getsockname(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
603 END_SAVE
604 if (res < 0)
605 return socket_error();
606 return makesockaddr((struct sockaddr *) addrbuf, addrlen);
607}
608
609
Guido van Rossumb6775db1994-08-01 11:34:53 +0000610#ifdef HAVE_GETPEERNAME /* Cray APP doesn't have this :-( */
Guido van Rossumc89705d1992-11-26 08:54:07 +0000611/* s.getpeername() method */
612
613static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000614BUILD_FUNC_DEF_2(sock_getpeername,sockobject *,s, object *,args)
Guido van Rossumc89705d1992-11-26 08:54:07 +0000615{
616 char addrbuf[256];
617 int addrlen, res;
618 if (!getnoarg(args))
619 return NULL;
620 if (!getsockaddrlen(s, &addrlen))
621 return NULL;
622 BGN_SAVE
623 res = getpeername(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
624 END_SAVE
625 if (res < 0)
626 return socket_error();
627 return makesockaddr((struct sockaddr *) addrbuf, addrlen);
628}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000629#endif /* HAVE_GETPEERNAME */
Guido van Rossumc89705d1992-11-26 08:54:07 +0000630
631
Guido van Rossum30a685f1991-06-27 15:51:29 +0000632/* s.listen(n) method */
633
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000634static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000635BUILD_FUNC_DEF_2(sock_listen,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000636{
637 int backlog;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000638 int res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000639 if (!getintarg(args, &backlog))
640 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000641 BGN_SAVE
Guido van Rossumb6775db1994-08-01 11:34:53 +0000642 if (backlog < 1)
643 backlog = 1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000644 res = listen(s->sock_fd, backlog);
645 END_SAVE
646 if (res < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000647 return socket_error();
648 INCREF(None);
649 return None;
650}
651
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000652#ifndef NO_DUP
Guido van Rossum30a685f1991-06-27 15:51:29 +0000653/* s.makefile(mode) method.
654 Create a new open file object referring to a dupped version of
655 the socket's file descriptor. (The dup() call is necessary so
656 that the open file and socket objects may be closed independent
657 of each other.)
658 The mode argument specifies 'r' or 'w' passed to fdopen(). */
659
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000660static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000661BUILD_FUNC_DEF_2(sock_makefile,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000662{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000663 extern int fclose PROTO((FILE *));
Guido van Rossumff4949e1992-08-05 19:58:53 +0000664 char *mode;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000665 int fd;
666 FILE *fp;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000667 if (!getargs(args, "s", &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000668 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000669 if ((fd = dup(s->sock_fd)) < 0 ||
Guido van Rossumff4949e1992-08-05 19:58:53 +0000670 (fp = fdopen(fd, mode)) == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000671 return socket_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000672 return newopenfileobject(fp, "<socket>", mode, fclose);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000673}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000674#endif /* NO_DUP */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000675
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000676/* s.recv(nbytes [,flags]) method */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000677
678static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000679BUILD_FUNC_DEF_2(sock_recv,sockobject *,s, object *,args)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000680{
681 int len, n, flags;
682 object *buf;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000683 flags = 0;
684 if (!getargs(args, "i", &len)) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000685 err_clear();
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000686 if (!getargs(args, "(ii)", &len, &flags))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000687 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000688 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000689 buf = newsizedstringobject((char *) 0, len);
690 if (buf == NULL)
691 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000692 BGN_SAVE
Guido van Rossum30a685f1991-06-27 15:51:29 +0000693 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000694 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000695 if (n < 0)
696 return socket_error();
697 if (resizestring(&buf, n) < 0)
698 return NULL;
699 return buf;
700}
701
Guido van Rossum30a685f1991-06-27 15:51:29 +0000702
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000703/* s.recvfrom(nbytes [,flags]) method */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000704
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000705static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000706BUILD_FUNC_DEF_2(sock_recvfrom,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000707{
708 char addrbuf[256];
Guido van Rossum6f5afc91993-02-05 09:46:15 +0000709 object *buf, *addr, *ret;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000710 int addrlen, len, n, flags;
711 flags = 0;
712 if (!getargs(args, "i", &len)) {
713 err_clear();
714 if (!getargs(args, "(ii)", &len, &flags))
715 return NULL;
716 }
Guido van Rossum18c9a4f1993-05-25 12:16:29 +0000717 if (!getsockaddrlen(s, &addrlen))
718 return NULL;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000719 buf = newsizedstringobject((char *) 0, len);
Guido van Rossum18c9a4f1993-05-25 12:16:29 +0000720 if (buf == NULL)
721 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000722 BGN_SAVE
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000723 n = recvfrom(s->sock_fd, getstringvalue(buf), len, flags,
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000724#ifndef NT
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000725 (ANY *)addrbuf, &addrlen);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000726#else
727 (struct sockaddr *)addrbuf, &addrlen);
728#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000729 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000730 if (n < 0)
731 return socket_error();
732 if (resizestring(&buf, n) < 0)
733 return NULL;
Guido van Rossum6f5afc91993-02-05 09:46:15 +0000734 addr = makesockaddr((struct sockaddr *)addrbuf, addrlen);
735 ret = mkvalue("OO", buf, addr);
736 XDECREF(addr);
737 XDECREF(buf);
738 return ret;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000739}
740
Guido van Rossum30a685f1991-06-27 15:51:29 +0000741
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000742/* s.send(data [,flags]) method */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000743
744static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000745BUILD_FUNC_DEF_2(sock_send,sockobject *,s, object *,args)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000746{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000747 char *buf;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000748 int len, n, flags;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000749 flags = 0;
Guido van Rossum234f9421993-06-17 12:35:49 +0000750 if (!getargs(args, "s#", &buf, &len)) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000751 err_clear();
Guido van Rossum234f9421993-06-17 12:35:49 +0000752 if (!getargs(args, "(s#i)", &buf, &len, &flags))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000753 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000754 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000755 BGN_SAVE
756 n = send(s->sock_fd, buf, len, flags);
757 END_SAVE
Guido van Rossum30a685f1991-06-27 15:51:29 +0000758 if (n < 0)
759 return socket_error();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000760 return newintobject((long)n);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000761}
762
763
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000764/* s.sendto(data, [flags,] sockaddr) method */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000765
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000766static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000767BUILD_FUNC_DEF_2(sock_sendto,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000768{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000769 object *addro;
770 char *buf;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000771 struct sockaddr *addr;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000772 int addrlen, len, n, flags;
773 flags = 0;
774 if (!getargs(args, "(s#O)", &buf, &len, &addro)) {
775 err_clear();
776 if (!getargs(args, "(s#iO)", &buf, &len, &flags, &addro))
777 return NULL;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000778 }
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000779 if (!getsockaddrarg(s, addro, &addr, &addrlen))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000780 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000781 BGN_SAVE
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000782 n = sendto(s->sock_fd, buf, len, flags, addr, addrlen);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000783 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000784 if (n < 0)
785 return socket_error();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000786 return newintobject((long)n);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000787}
788
Guido van Rossum30a685f1991-06-27 15:51:29 +0000789
790/* s.shutdown(how) method */
791
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000792static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000793BUILD_FUNC_DEF_2(sock_shutdown,sockobject *,s, object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000794{
795 int how;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000796 int res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000797 if (!getintarg(args, &how))
798 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000799 BGN_SAVE
800 res = shutdown(s->sock_fd, how);
801 END_SAVE
802 if (res < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000803 return socket_error();
804 INCREF(None);
805 return None;
806}
807
Guido van Rossum30a685f1991-06-27 15:51:29 +0000808
809/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000810
811static struct methodlist sock_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000812 {"accept", (method)sock_accept},
Guido van Rossumc65a5251994-08-05 13:44:50 +0000813#if 0
Guido van Rossumb6775db1994-08-01 11:34:53 +0000814 {"allowbroadcast", (method)sock_allowbroadcast},
Guido van Rossumc65a5251994-08-05 13:44:50 +0000815#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000816 {"setsockopt", (method)sock_setsockopt},
817 {"getsockopt", (method)sock_getsockopt},
818 {"bind", (method)sock_bind},
819 {"close", (method)sock_close},
820 {"connect", (method)sock_connect},
821 {"fileno", (method)sock_fileno},
822 {"getsockname", (method)sock_getsockname},
823#ifdef HAVE_GETPEERNAME
824 {"getpeername", (method)sock_getpeername},
Guido van Rossum9575a441993-04-07 14:06:14 +0000825#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000826 {"listen", (method)sock_listen},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000827#ifndef NO_DUP
Guido van Rossumb6775db1994-08-01 11:34:53 +0000828 {"makefile", (method)sock_makefile},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000829#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000830 {"recv", (method)sock_recv},
831 {"recvfrom", (method)sock_recvfrom},
832 {"send", (method)sock_send},
833 {"sendto", (method)sock_sendto},
834 {"shutdown", (method)sock_shutdown},
835 {NULL, NULL} /* sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000836};
837
Guido van Rossum30a685f1991-06-27 15:51:29 +0000838
839/* Deallocate a socket object in response to the last DECREF().
840 First close the file description. */
841
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000842static void
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000843BUILD_FUNC_DEF_1(sock_dealloc, sockobject *,s)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000844{
845 (void) close(s->sock_fd);
846 DEL(s);
847}
848
Guido van Rossum30a685f1991-06-27 15:51:29 +0000849
850/* Return a socket object's named attribute. */
851
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000852static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000853BUILD_FUNC_DEF_2(sock_getattr,sockobject *,s, char *,name)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000854{
855 return findmethod(sock_methods, (object *) s, name);
856}
857
Guido van Rossum30a685f1991-06-27 15:51:29 +0000858
Guido van Rossumb6775db1994-08-01 11:34:53 +0000859/* Type object for socket objects. */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000860
Guido van Rossumb6775db1994-08-01 11:34:53 +0000861static typeobject Socktype = {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000862 OB_HEAD_INIT(&Typetype)
863 0,
864 "socket",
865 sizeof(sockobject),
866 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000867 (destructor)sock_dealloc, /*tp_dealloc*/
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000868 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000869 (getattrfunc)sock_getattr, /*tp_getattr*/
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000870 0, /*tp_setattr*/
871 0, /*tp_compare*/
872 0, /*tp_repr*/
873 0, /*tp_as_number*/
874 0, /*tp_as_sequence*/
875 0, /*tp_as_mapping*/
876};
877
Guido van Rossum30a685f1991-06-27 15:51:29 +0000878
Guido van Rossum81194471991-07-27 21:42:02 +0000879/* Python interface to gethostname(). */
880
881/*ARGSUSED*/
882static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000883BUILD_FUNC_DEF_2(socket_gethostname,object *,self, object *,args)
Guido van Rossum81194471991-07-27 21:42:02 +0000884{
885 char buf[1024];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000886 int res;
Guido van Rossum81194471991-07-27 21:42:02 +0000887 if (!getnoarg(args))
888 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000889 BGN_SAVE
890 res = gethostname(buf, (int) sizeof buf - 1);
891 END_SAVE
892 if (res < 0)
Guido van Rossum81194471991-07-27 21:42:02 +0000893 return socket_error();
894 buf[sizeof buf - 1] = '\0';
895 return newstringobject(buf);
896}
Guido van Rossumff4949e1992-08-05 19:58:53 +0000897
898
Guido van Rossum30a685f1991-06-27 15:51:29 +0000899/* Python interface to gethostbyname(name). */
900
901/*ARGSUSED*/
902static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000903BUILD_FUNC_DEF_2(socket_gethostbyname,object *,self, object *,args)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000904{
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000905 char *name;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000906 struct sockaddr_in addrbuf;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000907 if (!getargs(args, "s", &name))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000908 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000909 if (setipaddr(name, &addrbuf) < 0)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000910 return NULL;
911 return makeipaddr(&addrbuf);
912}
913
914
915/* Python interface to getservbyname(name).
916 This only returns the port number, since the other info is already
917 known or not useful (like the list of aliases). */
918
919/*ARGSUSED*/
920static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000921BUILD_FUNC_DEF_2(socket_getservbyname,object *,self, object *,args)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000922{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000923 char *name, *proto;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000924 struct servent *sp;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000925 if (!getargs(args, "(ss)", &name, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000926 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000927 BGN_SAVE
928 sp = getservbyname(name, proto);
929 END_SAVE
Guido van Rossum30a685f1991-06-27 15:51:29 +0000930 if (sp == NULL) {
931 err_setstr(SocketError, "service/proto not found");
932 return NULL;
933 }
934 return newintobject((long) ntohs(sp->s_port));
935}
936
937
938/* Python interface to socket(family, type, proto).
939 The third (protocol) argument is optional.
940 Return a new socket object. */
941
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000942/*ARGSUSED*/
943static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000944BUILD_FUNC_DEF_2(socket_socket,object *,self,object *,args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000945{
946 sockobject *s;
Guido van Rossum2a7178e1992-12-08 13:38:24 +0000947 int fd, family, type, proto;
948 proto = 0;
949 if (!getargs(args, "(ii)", &family, &type)) {
950 err_clear();
951 if (!getargs(args, "(iii)", &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000952 return NULL;
953 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000954 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000955 fd = socket(family, type, proto);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000956 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000957 if (fd < 0)
958 return socket_error();
959 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000960 /* If the object can't be created, don't forget to close the
961 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000962 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000963 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000964 /* From now on, ignore SIGPIPE and let the error checking
965 do the work. */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000966#ifdef SIGPIPE
Guido van Rossum81194471991-07-27 21:42:02 +0000967 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000968#endif
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000969 return (object *) s;
970}
971
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000972#ifndef NO_DUP
Guido van Rossum2a7178e1992-12-08 13:38:24 +0000973/* Create a socket object from a numeric file description.
974 Useful e.g. if stdin is a socket.
975 Additional arguments as for socket(). */
976
977/*ARGSUSED*/
978static object *
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000979BUILD_FUNC_DEF_2(socket_fromfd,object *,self,object *,args)
Guido van Rossum2a7178e1992-12-08 13:38:24 +0000980{
981 sockobject *s;
982 int fd, family, type, proto;
983 proto = 0;
984 if (!getargs(args, "(iii)", &fd, &family, &type)) {
985 err_clear();
986 if (!getargs(args, "(iiii)", &fd, &family, &type, &proto))
987 return NULL;
988 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000989 /* Dup the fd so it and the socket can be closed independently */
990 fd = dup(fd);
991 if (fd < 0)
992 return socket_error();
Guido van Rossum2a7178e1992-12-08 13:38:24 +0000993 s = newsockobject(fd, family, type, proto);
994 /* From now on, ignore SIGPIPE and let the error checking
995 do the work. */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000996#ifdef SIGPIPE
Guido van Rossum2a7178e1992-12-08 13:38:24 +0000997 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000998#endif
Guido van Rossum2a7178e1992-12-08 13:38:24 +0000999 return (object *) s;
1000}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001001#endif /* NO_DUP */
Guido van Rossum2a7178e1992-12-08 13:38:24 +00001002
Guido van Rossum30a685f1991-06-27 15:51:29 +00001003/* List of functions exported by this module. */
1004
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001005static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +00001006 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +00001007 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +00001008 {"getservbyname", socket_getservbyname},
1009 {"socket", socket_socket},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001010#ifndef NO_DUP
Guido van Rossum2a7178e1992-12-08 13:38:24 +00001011 {"fromfd", socket_fromfd},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001012#endif
Guido van Rossum30a685f1991-06-27 15:51:29 +00001013 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001014};
1015
Guido van Rossum30a685f1991-06-27 15:51:29 +00001016
1017/* Convenience routine to export an integer value.
1018 For simplicity, errors (which are unlikely anyway) are ignored. */
1019
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001020static void
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001021BUILD_FUNC_DEF_3(insint,object *,d,char *,name,int,value)
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001022{
1023 object *v = newintobject((long) value);
1024 if (v == NULL) {
1025 /* Don't bother reporting this error */
1026 err_clear();
1027 }
1028 else {
1029 dictinsert(d, name, v);
1030 DECREF(v);
1031 }
1032}
1033
Guido van Rossum30a685f1991-06-27 15:51:29 +00001034
1035/* Initialize this module.
1036 This is called when the first 'import socket' is done,
1037 via a table in config.c, if config.c is compiled with USE_SOCKET
1038 defined. */
1039
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001040void
1041initsocket()
1042{
1043 object *m, *d;
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001044 m = initmodule("socket", socket_methods);
1045 d = getmoduledict(m);
1046 SocketError = newstringobject("socket.error");
1047 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
1048 fatal("can't define socket.error");
1049 insint(d, "AF_INET", AF_INET);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001050#ifdef AF_UNIX
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001051 insint(d, "AF_UNIX", AF_UNIX);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001052#endif /* AF_UNIX */
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001053 insint(d, "SOCK_STREAM", SOCK_STREAM);
1054 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
1055 insint(d, "SOCK_RAW", SOCK_RAW);
1056 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
1057 insint(d, "SOCK_RDM", SOCK_RDM);
1058}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001059
1060#ifdef NT
1061BOOL WINAPI DllMain (HANDLE hInst,
1062 ULONG ul_reason_for_call,
1063 LPVOID lpReserved)
1064{
1065 switch (ul_reason_for_call)
1066 {
1067 case DLL_PROCESS_ATTACH:
1068 WSADATA WSAData;
1069 if (WSAStartup(MAKEWORD(2,0), &WSAData)) {
1070 OutputDebugString("Python can't initialize Windows Sockets DLL!");
1071 return FALSE;
1072 }
1073 break;
1074 case DLL_PROCESS_DETACH:
1075 WSACleanup();
1076 break;
1077
1078 }
1079 return TRUE;
1080}
1081#endif /* NT */