blob: c5f6fe7ba9ff5d05221231cf4ba449bbc7247b03 [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)
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +000035- no flags on sendto/recvfrom operations
Guido van Rossum30a685f1991-06-27 15:51:29 +000036- 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')
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 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 Rossum4dd2a7e1991-07-01 18:51:33 +0000328 res = makepair((object *) newsockobject(newfd,
329 s->sock_family,
330 s->sock_type,
331 s->sock_proto),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000332 makesockaddr((struct sockaddr *) addrbuf, addrlen));
333 if (res == NULL)
334 close(newfd);
335 return res;
336}
337
Guido van Rossum30a685f1991-06-27 15:51:29 +0000338
339/* s.bind(sockaddr) method */
340
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000341static object *
342sock_bind(s, args)
343 sockobject *s;
344 object *args;
345{
346 struct sockaddr *addr;
347 int addrlen;
348 if (!getsockaddrarg(s, args, &addr, &addrlen))
349 return NULL;
350 if (bind(s->sock_fd, addr, addrlen) < 0)
351 return socket_error();
352 INCREF(None);
353 return None;
354}
355
Guido van Rossum30a685f1991-06-27 15:51:29 +0000356
357/* s.close() method.
358 Set the file descriptor to -1 so operations tried subsequently
359 will surely fail. */
360
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000361static object *
362sock_close(s, args)
363 sockobject *s;
364 object *args;
365{
366 if (!getnoarg(args))
367 return NULL;
368 (void) close(s->sock_fd);
369 s->sock_fd = -1;
370 INCREF(None);
371 return None;
372}
373
Guido van Rossum30a685f1991-06-27 15:51:29 +0000374
375/* s.connect(sockaddr) method */
376
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000377static object *
378sock_connect(s, args)
379 sockobject *s;
380 object *args;
381{
382 struct sockaddr *addr;
383 int addrlen;
384 if (!getsockaddrarg(s, args, &addr, &addrlen))
385 return NULL;
386 if (connect(s->sock_fd, addr, addrlen) < 0)
387 return socket_error();
388 INCREF(None);
389 return None;
390}
391
Guido van Rossum30a685f1991-06-27 15:51:29 +0000392
393/* s.listen(n) method */
394
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000395static object *
396sock_listen(s, args)
397 sockobject *s;
398 object *args;
399{
400 int backlog;
401 if (!getintarg(args, &backlog))
402 return NULL;
403 if (listen(s->sock_fd, backlog) < 0)
404 return socket_error();
405 INCREF(None);
406 return None;
407}
408
Guido van Rossum30a685f1991-06-27 15:51:29 +0000409
410/* s.makefile(mode) method.
411 Create a new open file object referring to a dupped version of
412 the socket's file descriptor. (The dup() call is necessary so
413 that the open file and socket objects may be closed independent
414 of each other.)
415 The mode argument specifies 'r' or 'w' passed to fdopen(). */
416
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000417static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000418sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000419 sockobject *s;
420 object *args;
421{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000422 extern int fclose PROTO((FILE *));
423 object *mode;
424 int fd;
425 FILE *fp;
426 if (!getstrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000427 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000428 if ((fd = dup(s->sock_fd)) < 0 ||
429 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
430 return socket_error();
431 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
432}
433
434
435/* s.recv(nbytes) method */
436
437static object *
438sock_recv(s, args)
439 sockobject *s;
440 object *args;
441{
442 int len, n, flags;
443 object *buf;
444 if (!getintintarg(args, &len, &flags)) {
445 err_clear();
446 if (!getintarg(args, &len))
447 return NULL;
448 flags = 0;
449 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000450 buf = newsizedstringobject((char *) 0, len);
451 if (buf == NULL)
452 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000453 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000454 if (n < 0)
455 return socket_error();
456 if (resizestring(&buf, n) < 0)
457 return NULL;
458 return buf;
459}
460
Guido van Rossum30a685f1991-06-27 15:51:29 +0000461
462/* s.recvfrom(nbytes) method */
463
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000464static object *
465sock_recvfrom(s, args)
466 sockobject *s;
467 object *args;
468{
469 char addrbuf[256];
470 object *buf;
471 int addrlen, len, n;
472 if (!getintarg(args, &len))
473 return NULL;
474 buf = newsizedstringobject((char *) 0, len);
475 addrlen = sizeof addrbuf;
476 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
477 addrbuf, &addrlen);
478 if (n < 0)
479 return socket_error();
480 if (resizestring(&buf, n) < 0)
481 return NULL;
482 return makepair(buf, makesockaddr(addrbuf, addrlen));
483}
484
Guido van Rossum30a685f1991-06-27 15:51:29 +0000485
486/* s.send(data) method */
487
488static object *
489sock_send(s, args)
490 sockobject *s;
491 object *args;
492{
493 object *buf;
494 int len, n, flags;
495 if (!getstrintarg(args, &buf, &flags)) {
496 err_clear();
497 if (!getstrarg(args, &buf))
498 return NULL;
499 flags = 0;
500 }
501 len = getstringsize(buf);
502 n = send(s->sock_fd, getstringvalue(buf), len, flags);
503 if (n < 0)
504 return socket_error();
505 INCREF(None);
506 return None;
507}
508
509
510/* s.sendto(data, sockaddr) method */
511
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000512static object *
513sock_sendto(s, args)
514 sockobject *s;
515 object *args;
516{
517 object *buf;
518 struct sockaddr *addr;
519 int addrlen, len, n;
520 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
521 err_badarg();
522 return NULL;
523 }
524 if (!getstrarg(gettupleitem(args, 0), &buf) ||
525 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
526 return NULL;
527 len = getstringsize(buf);
528 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
529 addr, addrlen);
530 if (n < 0)
531 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000532 INCREF(None);
533 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000534}
535
Guido van Rossum30a685f1991-06-27 15:51:29 +0000536
537/* s.shutdown(how) method */
538
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000539static object *
540sock_shutdown(s, args)
541 sockobject *s;
542 object *args;
543{
544 int how;
545 if (!getintarg(args, &how))
546 return NULL;
547 if (shutdown(s->sock_fd, how) < 0)
548 return socket_error();
549 INCREF(None);
550 return None;
551}
552
Guido van Rossum30a685f1991-06-27 15:51:29 +0000553
554/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000555
556static struct methodlist sock_methods[] = {
557 {"accept", sock_accept},
558 {"bind", sock_bind},
559 {"close", sock_close},
560 {"connect", sock_connect},
561 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000562 {"makefile", sock_makefile},
563 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000564 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000565 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000566 {"sendto", sock_sendto},
567 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000568 {NULL, NULL} /* sentinel */
569};
570
Guido van Rossum30a685f1991-06-27 15:51:29 +0000571
572/* Deallocate a socket object in response to the last DECREF().
573 First close the file description. */
574
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000575static void
576sock_dealloc(s)
577 sockobject *s;
578{
579 (void) close(s->sock_fd);
580 DEL(s);
581}
582
Guido van Rossum30a685f1991-06-27 15:51:29 +0000583
584/* Return a socket object's named attribute. */
585
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000586static object *
587sock_getattr(s, name)
588 sockobject *s;
589 char *name;
590{
591 return findmethod(sock_methods, (object *) s, name);
592}
593
Guido van Rossum30a685f1991-06-27 15:51:29 +0000594
595/* Type object for socket objects.
596 If your compiler complains that it is first declared 'extern'
597 and later 'static', remove the 'static' keyword here. */
598
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000599static typeobject Socktype = {
600 OB_HEAD_INIT(&Typetype)
601 0,
602 "socket",
603 sizeof(sockobject),
604 0,
605 sock_dealloc, /*tp_dealloc*/
606 0, /*tp_print*/
607 sock_getattr, /*tp_getattr*/
608 0, /*tp_setattr*/
609 0, /*tp_compare*/
610 0, /*tp_repr*/
611 0, /*tp_as_number*/
612 0, /*tp_as_sequence*/
613 0, /*tp_as_mapping*/
614};
615
Guido van Rossum30a685f1991-06-27 15:51:29 +0000616
617/* Python interface to gethostbyname(name). */
618
619/*ARGSUSED*/
620static object *
621socket_gethostbyname(self, args)
622 object *self;
623 object *args;
624{
625 object *name;
626 struct hostent *hp;
627 struct sockaddr_in addrbuf;
628 if (!getstrarg(args, &name))
629 return NULL;
630 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
631 return NULL;
632 return makeipaddr(&addrbuf);
633}
634
635
636/* Python interface to getservbyname(name).
637 This only returns the port number, since the other info is already
638 known or not useful (like the list of aliases). */
639
640/*ARGSUSED*/
641static object *
642socket_getservbyname(self, args)
643 object *self;
644 object *args;
645{
646 object *name, *proto;
647 struct servent *sp;
648 if (!getstrstrarg(args, &name, &proto))
649 return NULL;
650 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
651 if (sp == NULL) {
652 err_setstr(SocketError, "service/proto not found");
653 return NULL;
654 }
655 return newintobject((long) ntohs(sp->s_port));
656}
657
658
659/* Python interface to socket(family, type, proto).
660 The third (protocol) argument is optional.
661 Return a new socket object. */
662
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000663/*ARGSUSED*/
664static object *
665socket_socket(self, args)
666 object *self;
667 object *args;
668{
669 sockobject *s;
670 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000671 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000672 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000673 return NULL;
674 }
675 else {
676 if (!getintintarg(args, &family, &type))
677 return NULL;
678 proto = 0;
679 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000680 fd = socket(family, type, proto);
681 if (fd < 0)
682 return socket_error();
683 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000684 /* If the object can't be created, don't forget to close the
685 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000686 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000687 (void) close(fd);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000688 return (object *) s;
689}
690
Guido van Rossum30a685f1991-06-27 15:51:29 +0000691
692/* List of functions exported by this module. */
693
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000694static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000695 {"gethostbyname", socket_gethostbyname},
696 {"getservbyname", socket_getservbyname},
697 {"socket", socket_socket},
698 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000699};
700
Guido van Rossum30a685f1991-06-27 15:51:29 +0000701
702/* Convenience routine to export an integer value.
703 For simplicity, errors (which are unlikely anyway) are ignored. */
704
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000705static void
706insint(d, name, value)
707 object *d;
708 char *name;
709 int value;
710{
711 object *v = newintobject((long) value);
712 if (v == NULL) {
713 /* Don't bother reporting this error */
714 err_clear();
715 }
716 else {
717 dictinsert(d, name, v);
718 DECREF(v);
719 }
720}
721
Guido van Rossum30a685f1991-06-27 15:51:29 +0000722
723/* Initialize this module.
724 This is called when the first 'import socket' is done,
725 via a table in config.c, if config.c is compiled with USE_SOCKET
726 defined. */
727
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000728void
729initsocket()
730{
731 object *m, *d;
732
733 m = initmodule("socket", socket_methods);
734 d = getmoduledict(m);
735 SocketError = newstringobject("socket.error");
736 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
737 fatal("can't define socket.error");
738 insint(d, "AF_INET", AF_INET);
739 insint(d, "AF_UNIX", AF_UNIX);
740 insint(d, "SOCK_STREAM", SOCK_STREAM);
741 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
742 insint(d, "SOCK_RAW", SOCK_RAW);
743 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
744 insint(d, "SOCK_RDM", SOCK_RDM);
745}