blob: 8ad9adae4371af7e0ec533bf4303aff86b557566 [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 Rossum81194471991-07-27 21:42:02 +000033- no asynchronous I/O (but read polling: avail)
34- no read/write operations (use send/recv or makefile 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 Rossum81194471991-07-27 21:42:02 +000040- socket.gethostname() --> host name (string)
Guido van Rossum30a685f1991-06-27 15:51:29 +000041- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +000042- socket.getservbyname(servername, protocolname) --> port number
43- socket.socket(family, type [, proto]) --> new socket object
Guido van Rossum6574b3e1991-06-25 21:36:08 +000044- family and type constants from <socket.h> are accessed as socket.AF_INET etc.
Guido van Rossum6574b3e1991-06-25 21:36:08 +000045- errors are reported as the exception socket.error
46- an Internet socket address is a pair (hostname, port)
47 where hostname can be anything recognized by gethostbyname()
48 (including the dd.dd.dd.dd notation) and port is in host byte order
49- where a hostname is returned, the dd.dd.dd.dd notation is used
50- a UNIX domain socket is a string specifying the pathname
51
Guido van Rossum30a685f1991-06-27 15:51:29 +000052Socket methods:
Guido van Rossum6574b3e1991-06-25 21:36:08 +000053
Guido van Rossum81194471991-07-27 21:42:02 +000054- s.accept() --> new socket object, sockaddr
55- s.avail() --> boolean
Guido van Rossum30a685f1991-06-27 15:51:29 +000056- s.bind(sockaddr) --> None
57- s.connect(sockaddr) --> None
Guido van Rossum30a685f1991-06-27 15:51:29 +000058- s.listen(n) --> None
59- s.makefile(mode) --> file object
60- s.recv(nbytes) --> string
61- s.recvfrom(nbytes) --> string, sockaddr
62- s.send(string) --> None
63- s.sendto(string, sockaddr) --> None
64- s.shutdown(how) --> None
65- s.close() --> None
66
Guido van Rossum6574b3e1991-06-25 21:36:08 +000067*/
68
69#include "allobjects.h"
70#include "modsupport.h"
71
Guido van Rossum81194471991-07-27 21:42:02 +000072#include <signal.h>
Guido van Rossum6574b3e1991-06-25 21:36:08 +000073#include <sys/types.h>
74#include <sys/socket.h>
Guido van Rossum81194471991-07-27 21:42:02 +000075#include <sys/time.h> /* Needed for struct timeval */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000076#include <netinet/in.h>
77#include <sys/un.h>
78#include <netdb.h>
Guido van Rossum81194471991-07-27 21:42:02 +000079#ifdef _AIX /* I *think* this works */
80#include <select.h> /* Needed for fd_set */
81#endif
Guido van Rossum6574b3e1991-06-25 21:36:08 +000082
Guido van Rossum30a685f1991-06-27 15:51:29 +000083
84/* Global variable holding the exception type for errors detected
85 by this module (but not argument type or memory errors, etc.). */
86
87static object *SocketError;
88
89
90/* Convenience function to raise an error according to errno
91 and return a NULL pointer from a function. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000092
93static object *
94socket_error()
95{
96 return err_errno(SocketError);
97}
98
Guido van Rossum30a685f1991-06-27 15:51:29 +000099
100/* The object holding a socket. It holds some extra information,
101 like the address family, which is used to decode socket address
102 arguments properly. */
103
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000104typedef struct {
105 OB_HEAD
Guido van Rossum30a685f1991-06-27 15:51:29 +0000106 int sock_fd; /* Socket file descriptor */
107 int sock_family; /* Address family, e.g., AF_INET */
108 int sock_type; /* Socket type, e.g., SOCK_STREAM */
109 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000110} sockobject;
111
Guido van Rossum30a685f1991-06-27 15:51:29 +0000112
113/* A forward reference to the Socktype type object.
114 The Socktype variable contains pointers to various functions,
115 some of which call newsocobject(), which uses Socktype, so
116 there has to be a circular reference. If your compiler complains
117 that it is first declared 'extern' and later 'static', remove the
118 'static' keyword from the actual definition. */
119
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000120extern typeobject Socktype; /* Forward */
121
Guido van Rossum30a685f1991-06-27 15:51:29 +0000122
123/* Create a new socket object.
124 This just creates the object and initializes it.
125 If the creation fails, return NULL and set an exception (implicit
126 in NEWOBJ()). */
127
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000128static sockobject *
129newsockobject(fd, family, type, proto)
130 int fd, family, type, proto;
131{
132 sockobject *s;
133 s = NEWOBJ(sockobject, &Socktype);
134 if (s != NULL) {
135 s->sock_fd = fd;
136 s->sock_family = family;
137 s->sock_type = type;
138 s->sock_proto = proto;
139 }
140 return s;
141}
142
Guido van Rossum30a685f1991-06-27 15:51:29 +0000143
144/* Convert a string specifying a host name or one of a few symbolic
145 names to a numeric IP address. This usually calls gethostbyname()
146 to do the work; the names "" and "<broadcast>" are special.
147 Return the length (should always be 4 bytes), or negative if
148 an error occurred; then an exception is raised. */
149
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000150static int
Guido van Rossum30a685f1991-06-27 15:51:29 +0000151setipaddr(name, addr_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000152 char *name;
153 struct sockaddr_in *addr_ret;
154{
155 struct hostent *hp;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000156 int d1, d2, d3, d4;
157 char ch;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000158
Guido van Rossum30a685f1991-06-27 15:51:29 +0000159 if (name[0] == '\0') {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000160 addr_ret->sin_addr.s_addr = INADDR_ANY;
161 return 4;
162 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000163 if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000164 addr_ret->sin_addr.s_addr = INADDR_BROADCAST;
165 return 4;
166 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000167 if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
168 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
169 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
170 addr_ret->sin_addr.s_addr = htonl(
171 ((long) d1 << 24) | ((long) d2 << 16) |
172 ((long) d3 << 8) | ((long) d4 << 0));
173 return 4;
174 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000175 hp = gethostbyname(name);
176 if (hp == NULL) {
177 err_setstr(SocketError, "host not found");
178 return -1;
179 }
180 memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
181 return hp->h_length;
182}
183
Guido van Rossum30a685f1991-06-27 15:51:29 +0000184
185/* Generally useful convenience function to create a tuple from two
186 objects. This eats references to the objects; if either is NULL
187 it destroys the other and returns NULL without raising an exception
188 (assuming the function that was called to create the argument must
189 have raised an exception and returned NULL). */
190
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000191static object *
192makepair(a, b)
193 object *a, *b;
194{
195 object *pair = NULL;
196 if (a == NULL || b == NULL || (pair = newtupleobject(2)) == NULL) {
197 XDECREF(a);
198 XDECREF(b);
199 return NULL;
200 }
201 settupleitem(pair, 0, a);
202 settupleitem(pair, 1, b);
203 return pair;
204}
205
Guido van Rossum30a685f1991-06-27 15:51:29 +0000206
207/* Create a string object representing an IP address.
208 This is always a string of the form 'dd.dd.dd.dd' (with variable
209 size numbers). */
210
211static object *
212makeipaddr(addr)
213 struct sockaddr_in *addr;
214{
215 long x = ntohl(addr->sin_addr.s_addr);
216 char buf[100];
217 sprintf(buf, "%d.%d.%d.%d",
218 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
219 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
220 return newstringobject(buf);
221}
222
223
224/* Create an object representing the given socket address,
225 suitable for passing it back to bind(), connect() etc.
226 The family field of the sockaddr structure is inspected
227 to determine what kind of address it really is. */
228
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000229/*ARGSUSED*/
230static object *
231makesockaddr(addr, addrlen)
232 struct sockaddr *addr;
233 int addrlen;
234{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000235 switch (addr->sa_family) {
236
237 case AF_INET:
238 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000239 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000240 return makepair(makeipaddr(a),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000241 newintobject((long) ntohs(a->sin_port)));
242 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000243
244 case AF_UNIX:
245 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000246 struct sockaddr_un *a = (struct sockaddr_un *) addr;
247 return newstringobject(a->sun_path);
248 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000249
250 /* More cases here... */
251
252 default:
253 err_setstr(SocketError, "return unknown socket address type");
254 return NULL;
255 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000256}
257
Guido van Rossum30a685f1991-06-27 15:51:29 +0000258
259/* Parse a socket address argument according to the socket object's
260 address family. Return 1 if the address was in the proper format,
261 0 of not. The address is returned through addr_ret, its length
262 through len_ret. */
263
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000264static int
265getsockaddrarg(s, args, addr_ret, len_ret)
266 sockobject *s;
267 object *args;
268 struct sockaddr **addr_ret;
269 int *len_ret;
270{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000271 switch (s->sock_family) {
272
273 case AF_UNIX:
274 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000275 static struct sockaddr_un addr;
276 object *path;
277 int len;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000278 if (!getstrarg(args, &path))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000279 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000280 if ((len = getstringsize(path)) > sizeof addr.sun_path) {
281 err_setstr(SocketError, "AF_UNIX path too long");
282 return 0;
283 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000284 addr.sun_family = AF_UNIX;
285 memcpy(addr.sun_path, getstringvalue(path), len);
286 *addr_ret = (struct sockaddr *) &addr;
287 *len_ret = len + sizeof addr.sun_family;
288 return 1;
289 }
290
Guido van Rossum30a685f1991-06-27 15:51:29 +0000291 case AF_INET:
292 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000293 static struct sockaddr_in addr;
294 object *host;
295 int port;
296 if (!getstrintarg(args, &host, &port))
297 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000298 if (setipaddr(getstringvalue(host), &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000299 return 0;
300 addr.sin_family = AF_INET;
301 addr.sin_port = htons(port);
302 *addr_ret = (struct sockaddr *) &addr;
303 *len_ret = sizeof addr;
304 return 1;
305 }
306
Guido van Rossum30a685f1991-06-27 15:51:29 +0000307 /* More cases here... */
308
309 default:
310 err_setstr(SocketError, "getsockaddrarg: bad family");
311 return 0;
312
313 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000314}
315
Guido van Rossum30a685f1991-06-27 15:51:29 +0000316
317/* s.accept() method */
318
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000319static object *
320sock_accept(s, args)
321 sockobject *s;
322 object *args;
323{
324 char addrbuf[256];
325 int addrlen, newfd;
326 object *res;
327 if (!getnoarg(args))
328 return NULL;
329 addrlen = sizeof addrbuf;
330 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
331 if (newfd < 0)
332 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000333 /* Create the new object with unspecified family,
334 to avoid calls to bind() etc. on it. */
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000335 res = makepair((object *) newsockobject(newfd,
336 s->sock_family,
337 s->sock_type,
338 s->sock_proto),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000339 makesockaddr((struct sockaddr *) addrbuf, addrlen));
340 if (res == NULL)
341 close(newfd);
342 return res;
343}
344
Guido van Rossum30a685f1991-06-27 15:51:29 +0000345
Guido van Rossum81194471991-07-27 21:42:02 +0000346/* s.avail() method */
347
348static object *
349sock_avail(s, args)
350 sockobject *s;
351 object *args;
352{
353 struct timeval timeout;
354 fd_set readers;
355 int n;
356 timeout.tv_sec = 0;
357 timeout.tv_usec = 0;
358 FD_ZERO(&readers);
359 FD_SET(s->sock_fd, &readers);
360 n = select(s->sock_fd+1, &readers, (fd_set *)0, (fd_set *)0, &timeout);
361 if (n < 0)
362 return socket_error();
363 return newintobject((long) (n != 0));
364}
365
366
Guido van Rossum30a685f1991-06-27 15:51:29 +0000367/* s.bind(sockaddr) method */
368
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000369static object *
370sock_bind(s, args)
371 sockobject *s;
372 object *args;
373{
374 struct sockaddr *addr;
375 int addrlen;
376 if (!getsockaddrarg(s, args, &addr, &addrlen))
377 return NULL;
378 if (bind(s->sock_fd, addr, addrlen) < 0)
379 return socket_error();
380 INCREF(None);
381 return None;
382}
383
Guido van Rossum30a685f1991-06-27 15:51:29 +0000384
385/* s.close() method.
386 Set the file descriptor to -1 so operations tried subsequently
387 will surely fail. */
388
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000389static object *
390sock_close(s, args)
391 sockobject *s;
392 object *args;
393{
394 if (!getnoarg(args))
395 return NULL;
396 (void) close(s->sock_fd);
397 s->sock_fd = -1;
398 INCREF(None);
399 return None;
400}
401
Guido van Rossum30a685f1991-06-27 15:51:29 +0000402
403/* s.connect(sockaddr) method */
404
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000405static object *
406sock_connect(s, args)
407 sockobject *s;
408 object *args;
409{
410 struct sockaddr *addr;
411 int addrlen;
412 if (!getsockaddrarg(s, args, &addr, &addrlen))
413 return NULL;
414 if (connect(s->sock_fd, addr, addrlen) < 0)
415 return socket_error();
416 INCREF(None);
417 return None;
418}
419
Guido van Rossum30a685f1991-06-27 15:51:29 +0000420
421/* s.listen(n) method */
422
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000423static object *
424sock_listen(s, args)
425 sockobject *s;
426 object *args;
427{
428 int backlog;
429 if (!getintarg(args, &backlog))
430 return NULL;
431 if (listen(s->sock_fd, backlog) < 0)
432 return socket_error();
433 INCREF(None);
434 return None;
435}
436
Guido van Rossum30a685f1991-06-27 15:51:29 +0000437
438/* s.makefile(mode) method.
439 Create a new open file object referring to a dupped version of
440 the socket's file descriptor. (The dup() call is necessary so
441 that the open file and socket objects may be closed independent
442 of each other.)
443 The mode argument specifies 'r' or 'w' passed to fdopen(). */
444
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000445static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000446sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000447 sockobject *s;
448 object *args;
449{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000450 extern int fclose PROTO((FILE *));
451 object *mode;
452 int fd;
453 FILE *fp;
454 if (!getstrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000455 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000456 if ((fd = dup(s->sock_fd)) < 0 ||
457 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
458 return socket_error();
459 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
460}
461
462
463/* s.recv(nbytes) method */
464
465static object *
466sock_recv(s, args)
467 sockobject *s;
468 object *args;
469{
470 int len, n, flags;
471 object *buf;
472 if (!getintintarg(args, &len, &flags)) {
473 err_clear();
474 if (!getintarg(args, &len))
475 return NULL;
476 flags = 0;
477 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000478 buf = newsizedstringobject((char *) 0, len);
479 if (buf == NULL)
480 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000481 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000482 if (n < 0)
483 return socket_error();
484 if (resizestring(&buf, n) < 0)
485 return NULL;
486 return buf;
487}
488
Guido van Rossum30a685f1991-06-27 15:51:29 +0000489
490/* s.recvfrom(nbytes) method */
491
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000492static object *
493sock_recvfrom(s, args)
494 sockobject *s;
495 object *args;
496{
497 char addrbuf[256];
498 object *buf;
499 int addrlen, len, n;
500 if (!getintarg(args, &len))
501 return NULL;
502 buf = newsizedstringobject((char *) 0, len);
503 addrlen = sizeof addrbuf;
504 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
505 addrbuf, &addrlen);
506 if (n < 0)
507 return socket_error();
508 if (resizestring(&buf, n) < 0)
509 return NULL;
510 return makepair(buf, makesockaddr(addrbuf, addrlen));
511}
512
Guido van Rossum30a685f1991-06-27 15:51:29 +0000513
514/* s.send(data) method */
515
516static object *
517sock_send(s, args)
518 sockobject *s;
519 object *args;
520{
521 object *buf;
522 int len, n, flags;
523 if (!getstrintarg(args, &buf, &flags)) {
524 err_clear();
525 if (!getstrarg(args, &buf))
526 return NULL;
527 flags = 0;
528 }
529 len = getstringsize(buf);
530 n = send(s->sock_fd, getstringvalue(buf), len, flags);
531 if (n < 0)
532 return socket_error();
533 INCREF(None);
534 return None;
535}
536
537
538/* s.sendto(data, sockaddr) method */
539
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000540static object *
541sock_sendto(s, args)
542 sockobject *s;
543 object *args;
544{
545 object *buf;
546 struct sockaddr *addr;
547 int addrlen, len, n;
548 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
549 err_badarg();
550 return NULL;
551 }
552 if (!getstrarg(gettupleitem(args, 0), &buf) ||
553 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
554 return NULL;
555 len = getstringsize(buf);
556 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
557 addr, addrlen);
558 if (n < 0)
559 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000560 INCREF(None);
561 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000562}
563
Guido van Rossum30a685f1991-06-27 15:51:29 +0000564
565/* s.shutdown(how) method */
566
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000567static object *
568sock_shutdown(s, args)
569 sockobject *s;
570 object *args;
571{
572 int how;
573 if (!getintarg(args, &how))
574 return NULL;
575 if (shutdown(s->sock_fd, how) < 0)
576 return socket_error();
577 INCREF(None);
578 return None;
579}
580
Guido van Rossum30a685f1991-06-27 15:51:29 +0000581
582/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000583
584static struct methodlist sock_methods[] = {
585 {"accept", sock_accept},
Guido van Rossum81194471991-07-27 21:42:02 +0000586 {"avail", sock_avail},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000587 {"bind", sock_bind},
588 {"close", sock_close},
589 {"connect", sock_connect},
590 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000591 {"makefile", sock_makefile},
592 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000593 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000594 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000595 {"sendto", sock_sendto},
596 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000597 {NULL, NULL} /* sentinel */
598};
599
Guido van Rossum30a685f1991-06-27 15:51:29 +0000600
601/* Deallocate a socket object in response to the last DECREF().
602 First close the file description. */
603
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000604static void
605sock_dealloc(s)
606 sockobject *s;
607{
608 (void) close(s->sock_fd);
609 DEL(s);
610}
611
Guido van Rossum30a685f1991-06-27 15:51:29 +0000612
613/* Return a socket object's named attribute. */
614
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000615static object *
616sock_getattr(s, name)
617 sockobject *s;
618 char *name;
619{
620 return findmethod(sock_methods, (object *) s, name);
621}
622
Guido van Rossum30a685f1991-06-27 15:51:29 +0000623
624/* Type object for socket objects.
625 If your compiler complains that it is first declared 'extern'
626 and later 'static', remove the 'static' keyword here. */
627
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000628static typeobject Socktype = {
629 OB_HEAD_INIT(&Typetype)
630 0,
631 "socket",
632 sizeof(sockobject),
633 0,
634 sock_dealloc, /*tp_dealloc*/
635 0, /*tp_print*/
636 sock_getattr, /*tp_getattr*/
637 0, /*tp_setattr*/
638 0, /*tp_compare*/
639 0, /*tp_repr*/
640 0, /*tp_as_number*/
641 0, /*tp_as_sequence*/
642 0, /*tp_as_mapping*/
643};
644
Guido van Rossum30a685f1991-06-27 15:51:29 +0000645
Guido van Rossum81194471991-07-27 21:42:02 +0000646/* Python interface to gethostname(). */
647
648/*ARGSUSED*/
649static object *
650socket_gethostname(self, args)
651 object *self;
652 object *args;
653{
654 char buf[1024];
655 if (!getnoarg(args))
656 return NULL;
657 if (gethostname(buf, sizeof buf - 1) < 0)
658 return socket_error();
659 buf[sizeof buf - 1] = '\0';
660 return newstringobject(buf);
661}
Guido van Rossum30a685f1991-06-27 15:51:29 +0000662/* Python interface to gethostbyname(name). */
663
664/*ARGSUSED*/
665static object *
666socket_gethostbyname(self, args)
667 object *self;
668 object *args;
669{
670 object *name;
671 struct hostent *hp;
672 struct sockaddr_in addrbuf;
673 if (!getstrarg(args, &name))
674 return NULL;
675 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
676 return NULL;
677 return makeipaddr(&addrbuf);
678}
679
680
681/* Python interface to getservbyname(name).
682 This only returns the port number, since the other info is already
683 known or not useful (like the list of aliases). */
684
685/*ARGSUSED*/
686static object *
687socket_getservbyname(self, args)
688 object *self;
689 object *args;
690{
691 object *name, *proto;
692 struct servent *sp;
693 if (!getstrstrarg(args, &name, &proto))
694 return NULL;
695 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
696 if (sp == NULL) {
697 err_setstr(SocketError, "service/proto not found");
698 return NULL;
699 }
700 return newintobject((long) ntohs(sp->s_port));
701}
702
703
704/* Python interface to socket(family, type, proto).
705 The third (protocol) argument is optional.
706 Return a new socket object. */
707
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000708/*ARGSUSED*/
709static object *
710socket_socket(self, args)
711 object *self;
712 object *args;
713{
714 sockobject *s;
715 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000716 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000717 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000718 return NULL;
719 }
720 else {
721 if (!getintintarg(args, &family, &type))
722 return NULL;
723 proto = 0;
724 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000725 fd = socket(family, type, proto);
726 if (fd < 0)
727 return socket_error();
728 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000729 /* If the object can't be created, don't forget to close the
730 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000731 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000732 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000733 /* From now on, ignore SIGPIPE and let the error checking
734 do the work. */
735 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000736 return (object *) s;
737}
738
Guido van Rossum30a685f1991-06-27 15:51:29 +0000739
740/* List of functions exported by this module. */
741
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000742static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000743 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +0000744 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000745 {"getservbyname", socket_getservbyname},
746 {"socket", socket_socket},
747 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000748};
749
Guido van Rossum30a685f1991-06-27 15:51:29 +0000750
751/* Convenience routine to export an integer value.
752 For simplicity, errors (which are unlikely anyway) are ignored. */
753
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000754static void
755insint(d, name, value)
756 object *d;
757 char *name;
758 int value;
759{
760 object *v = newintobject((long) value);
761 if (v == NULL) {
762 /* Don't bother reporting this error */
763 err_clear();
764 }
765 else {
766 dictinsert(d, name, v);
767 DECREF(v);
768 }
769}
770
Guido van Rossum30a685f1991-06-27 15:51:29 +0000771
772/* Initialize this module.
773 This is called when the first 'import socket' is done,
774 via a table in config.c, if config.c is compiled with USE_SOCKET
775 defined. */
776
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000777void
778initsocket()
779{
780 object *m, *d;
781
782 m = initmodule("socket", socket_methods);
783 d = getmoduledict(m);
784 SocketError = newstringobject("socket.error");
785 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
786 fatal("can't define socket.error");
787 insint(d, "AF_INET", AF_INET);
788 insint(d, "AF_UNIX", AF_UNIX);
789 insint(d, "SOCK_STREAM", SOCK_STREAM);
790 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
791 insint(d, "SOCK_RAW", SOCK_RAW);
792 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
793 insint(d, "SOCK_RDM", SOCK_RDM);
794}