blob: 13644fe57bf1a0a0eebd2ef43fab1cde6fd535f4 [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
Guido van Rossum9c16d7f1992-01-27 16:49:54 +000027/* XXX Ought to fix getStr*arg calls to use getargs(args, "s#", ...) */
28
Guido van Rossum6574b3e1991-06-25 21:36:08 +000029/*
30This module provides an interface to Berkeley socket IPC.
31
32Limitations:
33
Guido van Rossum30a685f1991-06-27 15:51:29 +000034- only AF_INET and AF_UNIX address families are supported
Guido van Rossum81194471991-07-27 21:42:02 +000035- no asynchronous I/O (but read polling: avail)
36- no read/write operations (use send/recv or makefile instead)
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +000037- no flags on sendto/recvfrom operations
Guido van Rossume0e5edc1991-10-20 20:22:28 +000038- no general setsockopt() call (but see s.allowbroadcast())
Guido van Rossum6574b3e1991-06-25 21:36:08 +000039
40Interface:
41
Guido van Rossum81194471991-07-27 21:42:02 +000042- socket.gethostname() --> host name (string)
Guido van Rossum30a685f1991-06-27 15:51:29 +000043- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +000044- socket.getservbyname(servername, protocolname) --> port number
45- socket.socket(family, type [, proto]) --> new socket object
Guido van Rossum6574b3e1991-06-25 21:36:08 +000046- family and type constants from <socket.h> are accessed as socket.AF_INET etc.
Guido van Rossum6574b3e1991-06-25 21:36:08 +000047- errors are reported as the exception socket.error
48- an Internet socket address is a pair (hostname, port)
49 where hostname can be anything recognized by gethostbyname()
50 (including the dd.dd.dd.dd notation) and port is in host byte order
51- where a hostname is returned, the dd.dd.dd.dd notation is used
52- a UNIX domain socket is a string specifying the pathname
53
Guido van Rossum30a685f1991-06-27 15:51:29 +000054Socket methods:
Guido van Rossum6574b3e1991-06-25 21:36:08 +000055
Guido van Rossum81194471991-07-27 21:42:02 +000056- s.accept() --> new socket object, sockaddr
57- s.avail() --> boolean
Guido van Rossume0e5edc1991-10-20 20:22:28 +000058- s.allowbroadcast(boolean) --> None
Guido van Rossum30a685f1991-06-27 15:51:29 +000059- s.bind(sockaddr) --> None
60- s.connect(sockaddr) --> None
Guido van Rossum30a685f1991-06-27 15:51:29 +000061- s.listen(n) --> None
62- s.makefile(mode) --> file object
63- s.recv(nbytes) --> string
64- s.recvfrom(nbytes) --> string, sockaddr
65- s.send(string) --> None
66- s.sendto(string, sockaddr) --> None
67- s.shutdown(how) --> None
68- s.close() --> None
69
Guido van Rossum6574b3e1991-06-25 21:36:08 +000070*/
71
72#include "allobjects.h"
73#include "modsupport.h"
74
Guido van Rossum81194471991-07-27 21:42:02 +000075#include <signal.h>
Guido van Rossum6574b3e1991-06-25 21:36:08 +000076#include <sys/types.h>
77#include <sys/socket.h>
Guido van Rossum81194471991-07-27 21:42:02 +000078#include <sys/time.h> /* Needed for struct timeval */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000079#include <netinet/in.h>
80#include <sys/un.h>
81#include <netdb.h>
Guido van Rossum81194471991-07-27 21:42:02 +000082#ifdef _AIX /* I *think* this works */
Guido van Rossum0bb1a511991-11-27 14:55:18 +000083/* AIX defines fd_set in a separate file. Sigh... */
84#include <sys/select.h>
Guido van Rossum81194471991-07-27 21:42:02 +000085#endif
Guido van Rossum6574b3e1991-06-25 21:36:08 +000086
Guido van Rossum30a685f1991-06-27 15:51:29 +000087
88/* Global variable holding the exception type for errors detected
89 by this module (but not argument type or memory errors, etc.). */
90
91static object *SocketError;
92
93
94/* Convenience function to raise an error according to errno
95 and return a NULL pointer from a function. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000096
97static object *
98socket_error()
99{
100 return err_errno(SocketError);
101}
102
Guido van Rossum30a685f1991-06-27 15:51:29 +0000103
104/* The object holding a socket. It holds some extra information,
105 like the address family, which is used to decode socket address
106 arguments properly. */
107
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000108typedef struct {
109 OB_HEAD
Guido van Rossum30a685f1991-06-27 15:51:29 +0000110 int sock_fd; /* Socket file descriptor */
111 int sock_family; /* Address family, e.g., AF_INET */
112 int sock_type; /* Socket type, e.g., SOCK_STREAM */
113 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000114} sockobject;
115
Guido van Rossum30a685f1991-06-27 15:51:29 +0000116
117/* A forward reference to the Socktype type object.
118 The Socktype variable contains pointers to various functions,
119 some of which call newsocobject(), which uses Socktype, so
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000120 there has to be a circular reference. */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000121
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000122extern typeobject Socktype; /* Forward */
123
Guido van Rossum30a685f1991-06-27 15:51:29 +0000124
125/* Create a new socket object.
126 This just creates the object and initializes it.
127 If the creation fails, return NULL and set an exception (implicit
128 in NEWOBJ()). */
129
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000130static sockobject *
131newsockobject(fd, family, type, proto)
132 int fd, family, type, proto;
133{
134 sockobject *s;
135 s = NEWOBJ(sockobject, &Socktype);
136 if (s != NULL) {
137 s->sock_fd = fd;
138 s->sock_family = family;
139 s->sock_type = type;
140 s->sock_proto = proto;
141 }
142 return s;
143}
144
Guido van Rossum30a685f1991-06-27 15:51:29 +0000145
146/* Convert a string specifying a host name or one of a few symbolic
147 names to a numeric IP address. This usually calls gethostbyname()
148 to do the work; the names "" and "<broadcast>" are special.
149 Return the length (should always be 4 bytes), or negative if
150 an error occurred; then an exception is raised. */
151
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000152static int
Guido van Rossum30a685f1991-06-27 15:51:29 +0000153setipaddr(name, addr_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000154 char *name;
155 struct sockaddr_in *addr_ret;
156{
157 struct hostent *hp;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000158 int d1, d2, d3, d4;
159 char ch;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000160
Guido van Rossum30a685f1991-06-27 15:51:29 +0000161 if (name[0] == '\0') {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000162 addr_ret->sin_addr.s_addr = INADDR_ANY;
163 return 4;
164 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000165 if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000166 addr_ret->sin_addr.s_addr = INADDR_BROADCAST;
167 return 4;
168 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000169 if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
170 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
171 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
172 addr_ret->sin_addr.s_addr = htonl(
173 ((long) d1 << 24) | ((long) d2 << 16) |
174 ((long) d3 << 8) | ((long) d4 << 0));
175 return 4;
176 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000177 hp = gethostbyname(name);
178 if (hp == NULL) {
179 err_setstr(SocketError, "host not found");
180 return -1;
181 }
182 memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
183 return hp->h_length;
184}
185
Guido van Rossum30a685f1991-06-27 15:51:29 +0000186
187/* Generally useful convenience function to create a tuple from two
188 objects. This eats references to the objects; if either is NULL
189 it destroys the other and returns NULL without raising an exception
190 (assuming the function that was called to create the argument must
191 have raised an exception and returned NULL). */
192
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000193static object *
194makepair(a, b)
195 object *a, *b;
196{
197 object *pair = NULL;
198 if (a == NULL || b == NULL || (pair = newtupleobject(2)) == NULL) {
199 XDECREF(a);
200 XDECREF(b);
201 return NULL;
202 }
203 settupleitem(pair, 0, a);
204 settupleitem(pair, 1, b);
205 return pair;
206}
207
Guido van Rossum30a685f1991-06-27 15:51:29 +0000208
209/* Create a string object representing an IP address.
210 This is always a string of the form 'dd.dd.dd.dd' (with variable
211 size numbers). */
212
213static object *
214makeipaddr(addr)
215 struct sockaddr_in *addr;
216{
217 long x = ntohl(addr->sin_addr.s_addr);
218 char buf[100];
219 sprintf(buf, "%d.%d.%d.%d",
220 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
221 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
222 return newstringobject(buf);
223}
224
225
226/* Create an object representing the given socket address,
227 suitable for passing it back to bind(), connect() etc.
228 The family field of the sockaddr structure is inspected
229 to determine what kind of address it really is. */
230
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000231/*ARGSUSED*/
232static object *
233makesockaddr(addr, addrlen)
234 struct sockaddr *addr;
235 int addrlen;
236{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000237 switch (addr->sa_family) {
238
239 case AF_INET:
240 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000241 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000242 return makepair(makeipaddr(a),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000243 newintobject((long) ntohs(a->sin_port)));
244 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000245
246 case AF_UNIX:
247 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000248 struct sockaddr_un *a = (struct sockaddr_un *) addr;
249 return newstringobject(a->sun_path);
250 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000251
252 /* More cases here... */
253
254 default:
255 err_setstr(SocketError, "return unknown socket address type");
256 return NULL;
257 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000258}
259
Guido van Rossum30a685f1991-06-27 15:51:29 +0000260
261/* Parse a socket address argument according to the socket object's
262 address family. Return 1 if the address was in the proper format,
263 0 of not. The address is returned through addr_ret, its length
264 through len_ret. */
265
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000266static int
267getsockaddrarg(s, args, addr_ret, len_ret)
268 sockobject *s;
269 object *args;
270 struct sockaddr **addr_ret;
271 int *len_ret;
272{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000273 switch (s->sock_family) {
274
275 case AF_UNIX:
276 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000277 static struct sockaddr_un addr;
278 object *path;
279 int len;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000280 if (!getStrarg(args, &path))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000281 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000282 if ((len = getstringsize(path)) > sizeof addr.sun_path) {
283 err_setstr(SocketError, "AF_UNIX path too long");
284 return 0;
285 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000286 addr.sun_family = AF_UNIX;
287 memcpy(addr.sun_path, getstringvalue(path), len);
288 *addr_ret = (struct sockaddr *) &addr;
289 *len_ret = len + sizeof addr.sun_family;
290 return 1;
291 }
292
Guido van Rossum30a685f1991-06-27 15:51:29 +0000293 case AF_INET:
294 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000295 static struct sockaddr_in addr;
296 object *host;
297 int port;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000298 if (!getStrintarg(args, &host, &port))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000299 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000300 if (setipaddr(getstringvalue(host), &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000301 return 0;
302 addr.sin_family = AF_INET;
303 addr.sin_port = htons(port);
304 *addr_ret = (struct sockaddr *) &addr;
305 *len_ret = sizeof addr;
306 return 1;
307 }
308
Guido van Rossum30a685f1991-06-27 15:51:29 +0000309 /* More cases here... */
310
311 default:
312 err_setstr(SocketError, "getsockaddrarg: bad family");
313 return 0;
314
315 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000316}
317
Guido van Rossum30a685f1991-06-27 15:51:29 +0000318
319/* s.accept() method */
320
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000321static object *
322sock_accept(s, args)
323 sockobject *s;
324 object *args;
325{
326 char addrbuf[256];
327 int addrlen, newfd;
328 object *res;
329 if (!getnoarg(args))
330 return NULL;
331 addrlen = sizeof addrbuf;
332 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
333 if (newfd < 0)
334 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000335 /* Create the new object with unspecified family,
336 to avoid calls to bind() etc. on it. */
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000337 res = makepair((object *) newsockobject(newfd,
338 s->sock_family,
339 s->sock_type,
340 s->sock_proto),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000341 makesockaddr((struct sockaddr *) addrbuf, addrlen));
342 if (res == NULL)
343 close(newfd);
344 return res;
345}
346
Guido van Rossum30a685f1991-06-27 15:51:29 +0000347
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000348/* s.allowbroadcast() method */
349
350static object *
351sock_allowbroadcast(s, args)
352 sockobject *s;
353 object *args;
354{
355 int flag;
356 int res;
357 if (!getintarg(args, &flag))
358 return NULL;
359 res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
360 &flag, sizeof flag);
361 if (res < 0)
362 return socket_error();
363 INCREF(None);
364 return None;
365}
366
367
Guido van Rossum81194471991-07-27 21:42:02 +0000368/* s.avail() method */
369
370static object *
371sock_avail(s, args)
372 sockobject *s;
373 object *args;
374{
375 struct timeval timeout;
376 fd_set readers;
377 int n;
378 timeout.tv_sec = 0;
379 timeout.tv_usec = 0;
380 FD_ZERO(&readers);
381 FD_SET(s->sock_fd, &readers);
382 n = select(s->sock_fd+1, &readers, (fd_set *)0, (fd_set *)0, &timeout);
383 if (n < 0)
384 return socket_error();
385 return newintobject((long) (n != 0));
386}
387
388
Guido van Rossum30a685f1991-06-27 15:51:29 +0000389/* s.bind(sockaddr) method */
390
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000391static object *
392sock_bind(s, args)
393 sockobject *s;
394 object *args;
395{
396 struct sockaddr *addr;
397 int addrlen;
398 if (!getsockaddrarg(s, args, &addr, &addrlen))
399 return NULL;
400 if (bind(s->sock_fd, addr, addrlen) < 0)
401 return socket_error();
402 INCREF(None);
403 return None;
404}
405
Guido van Rossum30a685f1991-06-27 15:51:29 +0000406
407/* s.close() method.
408 Set the file descriptor to -1 so operations tried subsequently
409 will surely fail. */
410
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000411static object *
412sock_close(s, args)
413 sockobject *s;
414 object *args;
415{
416 if (!getnoarg(args))
417 return NULL;
418 (void) close(s->sock_fd);
419 s->sock_fd = -1;
420 INCREF(None);
421 return None;
422}
423
Guido van Rossum30a685f1991-06-27 15:51:29 +0000424
425/* s.connect(sockaddr) method */
426
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000427static object *
428sock_connect(s, args)
429 sockobject *s;
430 object *args;
431{
432 struct sockaddr *addr;
433 int addrlen;
434 if (!getsockaddrarg(s, args, &addr, &addrlen))
435 return NULL;
436 if (connect(s->sock_fd, addr, addrlen) < 0)
437 return socket_error();
438 INCREF(None);
439 return None;
440}
441
Guido van Rossum30a685f1991-06-27 15:51:29 +0000442
443/* s.listen(n) method */
444
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000445static object *
446sock_listen(s, args)
447 sockobject *s;
448 object *args;
449{
450 int backlog;
451 if (!getintarg(args, &backlog))
452 return NULL;
453 if (listen(s->sock_fd, backlog) < 0)
454 return socket_error();
455 INCREF(None);
456 return None;
457}
458
Guido van Rossum30a685f1991-06-27 15:51:29 +0000459
460/* s.makefile(mode) method.
461 Create a new open file object referring to a dupped version of
462 the socket's file descriptor. (The dup() call is necessary so
463 that the open file and socket objects may be closed independent
464 of each other.)
465 The mode argument specifies 'r' or 'w' passed to fdopen(). */
466
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000467static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000468sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000469 sockobject *s;
470 object *args;
471{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000472 extern int fclose PROTO((FILE *));
473 object *mode;
474 int fd;
475 FILE *fp;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000476 if (!getStrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000477 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000478 if ((fd = dup(s->sock_fd)) < 0 ||
479 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
480 return socket_error();
481 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
482}
483
484
485/* s.recv(nbytes) method */
486
487static object *
488sock_recv(s, args)
489 sockobject *s;
490 object *args;
491{
492 int len, n, flags;
493 object *buf;
494 if (!getintintarg(args, &len, &flags)) {
495 err_clear();
496 if (!getintarg(args, &len))
497 return NULL;
498 flags = 0;
499 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000500 buf = newsizedstringobject((char *) 0, len);
501 if (buf == NULL)
502 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000503 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000504 if (n < 0)
505 return socket_error();
506 if (resizestring(&buf, n) < 0)
507 return NULL;
508 return buf;
509}
510
Guido van Rossum30a685f1991-06-27 15:51:29 +0000511
512/* s.recvfrom(nbytes) method */
513
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000514static object *
515sock_recvfrom(s, args)
516 sockobject *s;
517 object *args;
518{
519 char addrbuf[256];
520 object *buf;
521 int addrlen, len, n;
522 if (!getintarg(args, &len))
523 return NULL;
524 buf = newsizedstringobject((char *) 0, len);
525 addrlen = sizeof addrbuf;
526 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
527 addrbuf, &addrlen);
528 if (n < 0)
529 return socket_error();
530 if (resizestring(&buf, n) < 0)
531 return NULL;
532 return makepair(buf, makesockaddr(addrbuf, addrlen));
533}
534
Guido van Rossum30a685f1991-06-27 15:51:29 +0000535
536/* s.send(data) method */
537
538static object *
539sock_send(s, args)
540 sockobject *s;
541 object *args;
542{
543 object *buf;
544 int len, n, flags;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000545 if (!getStrintarg(args, &buf, &flags)) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000546 err_clear();
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000547 if (!getStrarg(args, &buf))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000548 return NULL;
549 flags = 0;
550 }
551 len = getstringsize(buf);
552 n = send(s->sock_fd, getstringvalue(buf), len, flags);
553 if (n < 0)
554 return socket_error();
555 INCREF(None);
556 return None;
557}
558
559
560/* s.sendto(data, sockaddr) method */
561
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000562static object *
563sock_sendto(s, args)
564 sockobject *s;
565 object *args;
566{
567 object *buf;
568 struct sockaddr *addr;
569 int addrlen, len, n;
570 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
571 err_badarg();
572 return NULL;
573 }
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000574 if (!getStrarg(gettupleitem(args, 0), &buf) ||
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000575 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
576 return NULL;
577 len = getstringsize(buf);
578 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
579 addr, addrlen);
580 if (n < 0)
581 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000582 INCREF(None);
583 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000584}
585
Guido van Rossum30a685f1991-06-27 15:51:29 +0000586
587/* s.shutdown(how) method */
588
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000589static object *
590sock_shutdown(s, args)
591 sockobject *s;
592 object *args;
593{
594 int how;
595 if (!getintarg(args, &how))
596 return NULL;
597 if (shutdown(s->sock_fd, how) < 0)
598 return socket_error();
599 INCREF(None);
600 return None;
601}
602
Guido van Rossum30a685f1991-06-27 15:51:29 +0000603
604/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000605
606static struct methodlist sock_methods[] = {
607 {"accept", sock_accept},
Guido van Rossum81194471991-07-27 21:42:02 +0000608 {"avail", sock_avail},
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000609 {"allowbroadcast", sock_allowbroadcast},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000610 {"bind", sock_bind},
611 {"close", sock_close},
612 {"connect", sock_connect},
613 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000614 {"makefile", sock_makefile},
615 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000616 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000617 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000618 {"sendto", sock_sendto},
619 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000620 {NULL, NULL} /* sentinel */
621};
622
Guido van Rossum30a685f1991-06-27 15:51:29 +0000623
624/* Deallocate a socket object in response to the last DECREF().
625 First close the file description. */
626
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000627static void
628sock_dealloc(s)
629 sockobject *s;
630{
631 (void) close(s->sock_fd);
632 DEL(s);
633}
634
Guido van Rossum30a685f1991-06-27 15:51:29 +0000635
636/* Return a socket object's named attribute. */
637
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000638static object *
639sock_getattr(s, name)
640 sockobject *s;
641 char *name;
642{
643 return findmethod(sock_methods, (object *) s, name);
644}
645
Guido van Rossum30a685f1991-06-27 15:51:29 +0000646
647/* Type object for socket objects.
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000648 XXX This should be static, but some compilers don't grok the
649 XXX forward reference to it in that case... */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000650
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000651typeobject Socktype = {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000652 OB_HEAD_INIT(&Typetype)
653 0,
654 "socket",
655 sizeof(sockobject),
656 0,
657 sock_dealloc, /*tp_dealloc*/
658 0, /*tp_print*/
659 sock_getattr, /*tp_getattr*/
660 0, /*tp_setattr*/
661 0, /*tp_compare*/
662 0, /*tp_repr*/
663 0, /*tp_as_number*/
664 0, /*tp_as_sequence*/
665 0, /*tp_as_mapping*/
666};
667
Guido van Rossum30a685f1991-06-27 15:51:29 +0000668
Guido van Rossum81194471991-07-27 21:42:02 +0000669/* Python interface to gethostname(). */
670
671/*ARGSUSED*/
672static object *
673socket_gethostname(self, args)
674 object *self;
675 object *args;
676{
677 char buf[1024];
678 if (!getnoarg(args))
679 return NULL;
680 if (gethostname(buf, sizeof buf - 1) < 0)
681 return socket_error();
682 buf[sizeof buf - 1] = '\0';
683 return newstringobject(buf);
684}
Guido van Rossum30a685f1991-06-27 15:51:29 +0000685/* Python interface to gethostbyname(name). */
686
687/*ARGSUSED*/
688static object *
689socket_gethostbyname(self, args)
690 object *self;
691 object *args;
692{
693 object *name;
694 struct hostent *hp;
695 struct sockaddr_in addrbuf;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000696 if (!getStrarg(args, &name))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000697 return NULL;
698 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
699 return NULL;
700 return makeipaddr(&addrbuf);
701}
702
703
704/* Python interface to getservbyname(name).
705 This only returns the port number, since the other info is already
706 known or not useful (like the list of aliases). */
707
708/*ARGSUSED*/
709static object *
710socket_getservbyname(self, args)
711 object *self;
712 object *args;
713{
714 object *name, *proto;
715 struct servent *sp;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000716 if (!getStrStrarg(args, &name, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000717 return NULL;
718 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
719 if (sp == NULL) {
720 err_setstr(SocketError, "service/proto not found");
721 return NULL;
722 }
723 return newintobject((long) ntohs(sp->s_port));
724}
725
726
727/* Python interface to socket(family, type, proto).
728 The third (protocol) argument is optional.
729 Return a new socket object. */
730
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000731/*ARGSUSED*/
732static object *
733socket_socket(self, args)
734 object *self;
735 object *args;
736{
737 sockobject *s;
738 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000739 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000740 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000741 return NULL;
742 }
743 else {
744 if (!getintintarg(args, &family, &type))
745 return NULL;
746 proto = 0;
747 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000748 fd = socket(family, type, proto);
749 if (fd < 0)
750 return socket_error();
751 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000752 /* If the object can't be created, don't forget to close the
753 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000754 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000755 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000756 /* From now on, ignore SIGPIPE and let the error checking
757 do the work. */
758 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000759 return (object *) s;
760}
761
Guido van Rossum30a685f1991-06-27 15:51:29 +0000762
763/* List of functions exported by this module. */
764
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000765static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000766 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +0000767 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000768 {"getservbyname", socket_getservbyname},
769 {"socket", socket_socket},
770 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000771};
772
Guido van Rossum30a685f1991-06-27 15:51:29 +0000773
774/* Convenience routine to export an integer value.
775 For simplicity, errors (which are unlikely anyway) are ignored. */
776
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000777static void
778insint(d, name, value)
779 object *d;
780 char *name;
781 int value;
782{
783 object *v = newintobject((long) value);
784 if (v == NULL) {
785 /* Don't bother reporting this error */
786 err_clear();
787 }
788 else {
789 dictinsert(d, name, v);
790 DECREF(v);
791 }
792}
793
Guido van Rossum30a685f1991-06-27 15:51:29 +0000794
795/* Initialize this module.
796 This is called when the first 'import socket' is done,
797 via a table in config.c, if config.c is compiled with USE_SOCKET
798 defined. */
799
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000800void
801initsocket()
802{
803 object *m, *d;
804
805 m = initmodule("socket", socket_methods);
806 d = getmoduledict(m);
807 SocketError = newstringobject("socket.error");
808 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
809 fatal("can't define socket.error");
810 insint(d, "AF_INET", AF_INET);
811 insint(d, "AF_UNIX", AF_UNIX);
812 insint(d, "SOCK_STREAM", SOCK_STREAM);
813 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
814 insint(d, "SOCK_RAW", SOCK_RAW);
815 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
816 insint(d, "SOCK_RDM", SOCK_RDM);
817}