blob: c0c90799347f84b0717916e12328b5aa77147ac9 [file] [log] [blame]
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
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 Rossum6574b3e1991-06-25 21:36:08 +000033- no asynchronous I/O
Guido van Rossum30a685f1991-06-27 15:51:29 +000034- no read/write operations (use send/recv instead)
35- no flags on send/recv operations
36- no setsockopt() call
Guido van Rossum6574b3e1991-06-25 21:36:08 +000037
38Interface:
39
Guido van Rossum30a685f1991-06-27 15:51:29 +000040- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
41- socket.getservbyname(server, type) --> port number
42- socket.socket(family, type) --> 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 Rossum30a685f1991-06-27 15:51:29 +000053- s.bind(sockaddr) --> None
54- s.connect(sockaddr) --> None
55- s.accept() --> new socket object, sockaddr
56- s.listen(n) --> None
57- s.makefile(mode) --> file object
58- s.recv(nbytes) --> string
59- s.recvfrom(nbytes) --> string, sockaddr
60- s.send(string) --> None
61- s.sendto(string, sockaddr) --> None
62- s.shutdown(how) --> None
63- s.close() --> None
64
Guido van Rossum6574b3e1991-06-25 21:36:08 +000065*/
66
67#include "allobjects.h"
68#include "modsupport.h"
69
70#include <sys/types.h>
71#include <sys/socket.h>
72#include <netinet/in.h>
73#include <sys/un.h>
74#include <netdb.h>
75
Guido van Rossum30a685f1991-06-27 15:51:29 +000076
77/* Global variable holding the exception type for errors detected
78 by this module (but not argument type or memory errors, etc.). */
79
80static object *SocketError;
81
82
83/* Convenience function to raise an error according to errno
84 and return a NULL pointer from a function. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000085
86static object *
87socket_error()
88{
89 return err_errno(SocketError);
90}
91
Guido van Rossum30a685f1991-06-27 15:51:29 +000092
93/* The object holding a socket. It holds some extra information,
94 like the address family, which is used to decode socket address
95 arguments properly. */
96
Guido van Rossum6574b3e1991-06-25 21:36:08 +000097typedef struct {
98 OB_HEAD
Guido van Rossum30a685f1991-06-27 15:51:29 +000099 int sock_fd; /* Socket file descriptor */
100 int sock_family; /* Address family, e.g., AF_INET */
101 int sock_type; /* Socket type, e.g., SOCK_STREAM */
102 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000103} sockobject;
104
Guido van Rossum30a685f1991-06-27 15:51:29 +0000105
106/* A forward reference to the Socktype type object.
107 The Socktype variable contains pointers to various functions,
108 some of which call newsocobject(), which uses Socktype, so
109 there has to be a circular reference. If your compiler complains
110 that it is first declared 'extern' and later 'static', remove the
111 'static' keyword from the actual definition. */
112
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000113extern typeobject Socktype; /* Forward */
114
Guido van Rossum30a685f1991-06-27 15:51:29 +0000115
116/* Create a new socket object.
117 This just creates the object and initializes it.
118 If the creation fails, return NULL and set an exception (implicit
119 in NEWOBJ()). */
120
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000121static sockobject *
122newsockobject(fd, family, type, proto)
123 int fd, family, type, proto;
124{
125 sockobject *s;
126 s = NEWOBJ(sockobject, &Socktype);
127 if (s != NULL) {
128 s->sock_fd = fd;
129 s->sock_family = family;
130 s->sock_type = type;
131 s->sock_proto = proto;
132 }
133 return s;
134}
135
Guido van Rossum30a685f1991-06-27 15:51:29 +0000136
137/* Convert a string specifying a host name or one of a few symbolic
138 names to a numeric IP address. This usually calls gethostbyname()
139 to do the work; the names "" and "<broadcast>" are special.
140 Return the length (should always be 4 bytes), or negative if
141 an error occurred; then an exception is raised. */
142
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000143static int
Guido van Rossum30a685f1991-06-27 15:51:29 +0000144setipaddr(name, addr_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000145 char *name;
146 struct sockaddr_in *addr_ret;
147{
148 struct hostent *hp;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000149 int d1, d2, d3, d4;
150 char ch;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000151
Guido van Rossum30a685f1991-06-27 15:51:29 +0000152 if (name[0] == '\0') {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000153 addr_ret->sin_addr.s_addr = INADDR_ANY;
154 return 4;
155 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000156 if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000157 addr_ret->sin_addr.s_addr = INADDR_BROADCAST;
158 return 4;
159 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000160 if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
161 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
162 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
163 addr_ret->sin_addr.s_addr = htonl(
164 ((long) d1 << 24) | ((long) d2 << 16) |
165 ((long) d3 << 8) | ((long) d4 << 0));
166 return 4;
167 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000168 hp = gethostbyname(name);
169 if (hp == NULL) {
170 err_setstr(SocketError, "host not found");
171 return -1;
172 }
173 memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
174 return hp->h_length;
175}
176
Guido van Rossum30a685f1991-06-27 15:51:29 +0000177
178/* Generally useful convenience function to create a tuple from two
179 objects. This eats references to the objects; if either is NULL
180 it destroys the other and returns NULL without raising an exception
181 (assuming the function that was called to create the argument must
182 have raised an exception and returned NULL). */
183
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000184static object *
185makepair(a, b)
186 object *a, *b;
187{
188 object *pair = NULL;
189 if (a == NULL || b == NULL || (pair = newtupleobject(2)) == NULL) {
190 XDECREF(a);
191 XDECREF(b);
192 return NULL;
193 }
194 settupleitem(pair, 0, a);
195 settupleitem(pair, 1, b);
196 return pair;
197}
198
Guido van Rossum30a685f1991-06-27 15:51:29 +0000199
200/* Create a string object representing an IP address.
201 This is always a string of the form 'dd.dd.dd.dd' (with variable
202 size numbers). */
203
204static object *
205makeipaddr(addr)
206 struct sockaddr_in *addr;
207{
208 long x = ntohl(addr->sin_addr.s_addr);
209 char buf[100];
210 sprintf(buf, "%d.%d.%d.%d",
211 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
212 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
213 return newstringobject(buf);
214}
215
216
217/* Create an object representing the given socket address,
218 suitable for passing it back to bind(), connect() etc.
219 The family field of the sockaddr structure is inspected
220 to determine what kind of address it really is. */
221
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000222/*ARGSUSED*/
223static object *
224makesockaddr(addr, addrlen)
225 struct sockaddr *addr;
226 int addrlen;
227{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000228 switch (addr->sa_family) {
229
230 case AF_INET:
231 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000232 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000233 return makepair(makeipaddr(a),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000234 newintobject((long) ntohs(a->sin_port)));
235 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000236
237 case AF_UNIX:
238 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000239 struct sockaddr_un *a = (struct sockaddr_un *) addr;
240 return newstringobject(a->sun_path);
241 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000242
243 /* More cases here... */
244
245 default:
246 err_setstr(SocketError, "return unknown socket address type");
247 return NULL;
248 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000249}
250
Guido van Rossum30a685f1991-06-27 15:51:29 +0000251
252/* Parse a socket address argument according to the socket object's
253 address family. Return 1 if the address was in the proper format,
254 0 of not. The address is returned through addr_ret, its length
255 through len_ret. */
256
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000257static int
258getsockaddrarg(s, args, addr_ret, len_ret)
259 sockobject *s;
260 object *args;
261 struct sockaddr **addr_ret;
262 int *len_ret;
263{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000264 switch (s->sock_family) {
265
266 case AF_UNIX:
267 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000268 static struct sockaddr_un addr;
269 object *path;
270 int len;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000271 if (!getstrarg(args, &path))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000272 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000273 if ((len = getstringsize(path)) > sizeof addr.sun_path) {
274 err_setstr(SocketError, "AF_UNIX path too long");
275 return 0;
276 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000277 addr.sun_family = AF_UNIX;
278 memcpy(addr.sun_path, getstringvalue(path), len);
279 *addr_ret = (struct sockaddr *) &addr;
280 *len_ret = len + sizeof addr.sun_family;
281 return 1;
282 }
283
Guido van Rossum30a685f1991-06-27 15:51:29 +0000284 case AF_INET:
285 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000286 static struct sockaddr_in addr;
287 object *host;
288 int port;
289 if (!getstrintarg(args, &host, &port))
290 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000291 if (setipaddr(getstringvalue(host), &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000292 return 0;
293 addr.sin_family = AF_INET;
294 addr.sin_port = htons(port);
295 *addr_ret = (struct sockaddr *) &addr;
296 *len_ret = sizeof addr;
297 return 1;
298 }
299
Guido van Rossum30a685f1991-06-27 15:51:29 +0000300 /* More cases here... */
301
302 default:
303 err_setstr(SocketError, "getsockaddrarg: bad family");
304 return 0;
305
306 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000307}
308
Guido van Rossum30a685f1991-06-27 15:51:29 +0000309
310/* s.accept() method */
311
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000312static object *
313sock_accept(s, args)
314 sockobject *s;
315 object *args;
316{
317 char addrbuf[256];
318 int addrlen, newfd;
319 object *res;
320 if (!getnoarg(args))
321 return NULL;
322 addrlen = sizeof addrbuf;
323 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
324 if (newfd < 0)
325 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000326 /* Create the new object with unspecified family,
327 to avoid calls to bind() etc. on it. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000328 res = makepair((object *) newsockobject(newfd, AF_UNSPEC, 0, 0),
329 makesockaddr((struct sockaddr *) addrbuf, addrlen));
330 if (res == NULL)
331 close(newfd);
332 return res;
333}
334
Guido van Rossum30a685f1991-06-27 15:51:29 +0000335
336/* s.bind(sockaddr) method */
337
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000338static object *
339sock_bind(s, args)
340 sockobject *s;
341 object *args;
342{
343 struct sockaddr *addr;
344 int addrlen;
345 if (!getsockaddrarg(s, args, &addr, &addrlen))
346 return NULL;
347 if (bind(s->sock_fd, addr, addrlen) < 0)
348 return socket_error();
349 INCREF(None);
350 return None;
351}
352
Guido van Rossum30a685f1991-06-27 15:51:29 +0000353
354/* s.close() method.
355 Set the file descriptor to -1 so operations tried subsequently
356 will surely fail. */
357
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000358static object *
359sock_close(s, args)
360 sockobject *s;
361 object *args;
362{
363 if (!getnoarg(args))
364 return NULL;
365 (void) close(s->sock_fd);
366 s->sock_fd = -1;
367 INCREF(None);
368 return None;
369}
370
Guido van Rossum30a685f1991-06-27 15:51:29 +0000371
372/* s.connect(sockaddr) method */
373
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000374static object *
375sock_connect(s, args)
376 sockobject *s;
377 object *args;
378{
379 struct sockaddr *addr;
380 int addrlen;
381 if (!getsockaddrarg(s, args, &addr, &addrlen))
382 return NULL;
383 if (connect(s->sock_fd, addr, addrlen) < 0)
384 return socket_error();
385 INCREF(None);
386 return None;
387}
388
Guido van Rossum30a685f1991-06-27 15:51:29 +0000389
390/* s.listen(n) method */
391
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000392static object *
393sock_listen(s, args)
394 sockobject *s;
395 object *args;
396{
397 int backlog;
398 if (!getintarg(args, &backlog))
399 return NULL;
400 if (listen(s->sock_fd, backlog) < 0)
401 return socket_error();
402 INCREF(None);
403 return None;
404}
405
Guido van Rossum30a685f1991-06-27 15:51:29 +0000406
407/* s.makefile(mode) method.
408 Create a new open file object referring to a dupped version of
409 the socket's file descriptor. (The dup() call is necessary so
410 that the open file and socket objects may be closed independent
411 of each other.)
412 The mode argument specifies 'r' or 'w' passed to fdopen(). */
413
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000414static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000415sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000416 sockobject *s;
417 object *args;
418{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000419 extern int fclose PROTO((FILE *));
420 object *mode;
421 int fd;
422 FILE *fp;
423 if (!getstrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000424 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000425 if ((fd = dup(s->sock_fd)) < 0 ||
426 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
427 return socket_error();
428 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
429}
430
431
432/* s.recv(nbytes) method */
433
434static object *
435sock_recv(s, args)
436 sockobject *s;
437 object *args;
438{
439 int len, n, flags;
440 object *buf;
441 if (!getintintarg(args, &len, &flags)) {
442 err_clear();
443 if (!getintarg(args, &len))
444 return NULL;
445 flags = 0;
446 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000447 buf = newsizedstringobject((char *) 0, len);
448 if (buf == NULL)
449 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000450 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000451 if (n < 0)
452 return socket_error();
453 if (resizestring(&buf, n) < 0)
454 return NULL;
455 return buf;
456}
457
Guido van Rossum30a685f1991-06-27 15:51:29 +0000458
459/* s.recvfrom(nbytes) method */
460
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000461static object *
462sock_recvfrom(s, args)
463 sockobject *s;
464 object *args;
465{
466 char addrbuf[256];
467 object *buf;
468 int addrlen, len, n;
469 if (!getintarg(args, &len))
470 return NULL;
471 buf = newsizedstringobject((char *) 0, len);
472 addrlen = sizeof addrbuf;
473 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
474 addrbuf, &addrlen);
475 if (n < 0)
476 return socket_error();
477 if (resizestring(&buf, n) < 0)
478 return NULL;
479 return makepair(buf, makesockaddr(addrbuf, addrlen));
480}
481
Guido van Rossum30a685f1991-06-27 15:51:29 +0000482
483/* s.send(data) method */
484
485static object *
486sock_send(s, args)
487 sockobject *s;
488 object *args;
489{
490 object *buf;
491 int len, n, flags;
492 if (!getstrintarg(args, &buf, &flags)) {
493 err_clear();
494 if (!getstrarg(args, &buf))
495 return NULL;
496 flags = 0;
497 }
498 len = getstringsize(buf);
499 n = send(s->sock_fd, getstringvalue(buf), len, flags);
500 if (n < 0)
501 return socket_error();
502 INCREF(None);
503 return None;
504}
505
506
507/* s.sendto(data, sockaddr) method */
508
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000509static object *
510sock_sendto(s, args)
511 sockobject *s;
512 object *args;
513{
514 object *buf;
515 struct sockaddr *addr;
516 int addrlen, len, n;
517 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
518 err_badarg();
519 return NULL;
520 }
521 if (!getstrarg(gettupleitem(args, 0), &buf) ||
522 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
523 return NULL;
524 len = getstringsize(buf);
525 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
526 addr, addrlen);
527 if (n < 0)
528 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000529 INCREF(None);
530 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000531}
532
Guido van Rossum30a685f1991-06-27 15:51:29 +0000533
534/* s.shutdown(how) method */
535
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000536static object *
537sock_shutdown(s, args)
538 sockobject *s;
539 object *args;
540{
541 int how;
542 if (!getintarg(args, &how))
543 return NULL;
544 if (shutdown(s->sock_fd, how) < 0)
545 return socket_error();
546 INCREF(None);
547 return None;
548}
549
Guido van Rossum30a685f1991-06-27 15:51:29 +0000550
551/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000552
553static struct methodlist sock_methods[] = {
554 {"accept", sock_accept},
555 {"bind", sock_bind},
556 {"close", sock_close},
557 {"connect", sock_connect},
558 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000559 {"makefile", sock_makefile},
560 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000561 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000562 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000563 {"sendto", sock_sendto},
564 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000565 {NULL, NULL} /* sentinel */
566};
567
Guido van Rossum30a685f1991-06-27 15:51:29 +0000568
569/* Deallocate a socket object in response to the last DECREF().
570 First close the file description. */
571
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000572static void
573sock_dealloc(s)
574 sockobject *s;
575{
576 (void) close(s->sock_fd);
577 DEL(s);
578}
579
Guido van Rossum30a685f1991-06-27 15:51:29 +0000580
581/* Return a socket object's named attribute. */
582
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000583static object *
584sock_getattr(s, name)
585 sockobject *s;
586 char *name;
587{
588 return findmethod(sock_methods, (object *) s, name);
589}
590
Guido van Rossum30a685f1991-06-27 15:51:29 +0000591
592/* Type object for socket objects.
593 If your compiler complains that it is first declared 'extern'
594 and later 'static', remove the 'static' keyword here. */
595
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000596static typeobject Socktype = {
597 OB_HEAD_INIT(&Typetype)
598 0,
599 "socket",
600 sizeof(sockobject),
601 0,
602 sock_dealloc, /*tp_dealloc*/
603 0, /*tp_print*/
604 sock_getattr, /*tp_getattr*/
605 0, /*tp_setattr*/
606 0, /*tp_compare*/
607 0, /*tp_repr*/
608 0, /*tp_as_number*/
609 0, /*tp_as_sequence*/
610 0, /*tp_as_mapping*/
611};
612
Guido van Rossum30a685f1991-06-27 15:51:29 +0000613
614/* Python interface to gethostbyname(name). */
615
616/*ARGSUSED*/
617static object *
618socket_gethostbyname(self, args)
619 object *self;
620 object *args;
621{
622 object *name;
623 struct hostent *hp;
624 struct sockaddr_in addrbuf;
625 if (!getstrarg(args, &name))
626 return NULL;
627 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
628 return NULL;
629 return makeipaddr(&addrbuf);
630}
631
632
633/* Python interface to getservbyname(name).
634 This only returns the port number, since the other info is already
635 known or not useful (like the list of aliases). */
636
637/*ARGSUSED*/
638static object *
639socket_getservbyname(self, args)
640 object *self;
641 object *args;
642{
643 object *name, *proto;
644 struct servent *sp;
645 if (!getstrstrarg(args, &name, &proto))
646 return NULL;
647 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
648 if (sp == NULL) {
649 err_setstr(SocketError, "service/proto not found");
650 return NULL;
651 }
652 return newintobject((long) ntohs(sp->s_port));
653}
654
655
656/* Python interface to socket(family, type, proto).
657 The third (protocol) argument is optional.
658 Return a new socket object. */
659
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000660/*ARGSUSED*/
661static object *
662socket_socket(self, args)
663 object *self;
664 object *args;
665{
666 sockobject *s;
667 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000668 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
669 if (!getintintarg(args, &family, &type, &proto))
670 return NULL;
671 }
672 else {
673 if (!getintintarg(args, &family, &type))
674 return NULL;
675 proto = 0;
676 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000677 fd = socket(family, type, proto);
678 if (fd < 0)
679 return socket_error();
680 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000681 /* If the object can't be created, don't forget to close the
682 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000683 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000684 (void) close(fd);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000685 return (object *) s;
686}
687
Guido van Rossum30a685f1991-06-27 15:51:29 +0000688
689/* List of functions exported by this module. */
690
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000691static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000692 {"gethostbyname", socket_gethostbyname},
693 {"getservbyname", socket_getservbyname},
694 {"socket", socket_socket},
695 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000696};
697
Guido van Rossum30a685f1991-06-27 15:51:29 +0000698
699/* Convenience routine to export an integer value.
700 For simplicity, errors (which are unlikely anyway) are ignored. */
701
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000702static void
703insint(d, name, value)
704 object *d;
705 char *name;
706 int value;
707{
708 object *v = newintobject((long) value);
709 if (v == NULL) {
710 /* Don't bother reporting this error */
711 err_clear();
712 }
713 else {
714 dictinsert(d, name, v);
715 DECREF(v);
716 }
717}
718
Guido van Rossum30a685f1991-06-27 15:51:29 +0000719
720/* Initialize this module.
721 This is called when the first 'import socket' is done,
722 via a table in config.c, if config.c is compiled with USE_SOCKET
723 defined. */
724
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000725void
726initsocket()
727{
728 object *m, *d;
729
730 m = initmodule("socket", socket_methods);
731 d = getmoduledict(m);
732 SocketError = newstringobject("socket.error");
733 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
734 fatal("can't define socket.error");
735 insint(d, "AF_INET", AF_INET);
736 insint(d, "AF_UNIX", AF_UNIX);
737 insint(d, "SOCK_STREAM", SOCK_STREAM);
738 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
739 insint(d, "SOCK_RAW", SOCK_RAW);
740 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
741 insint(d, "SOCK_RDM", SOCK_RDM);
742}