blob: 200310e61fc34ef6a5bdb8c311d2858dc770332c [file] [log] [blame]
Guido van Rossum6574b3e1991-06-25 21:36:08 +00001/***********************************************************
Guido van Rossumbab9d031992-04-05 14:26:55 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossum6574b3e1991-06-25 21:36:08 +00003Netherlands.
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 Rossum0e69587d1992-06-05 15:11:30 +000038- setsockopt() and getsockopt() only support integer options
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 Rossum0e69587d1992-06-05 15:11:30 +000058- s.setsockopt(level, optname, flag) --> None
59- s.getsockopt(level, optname) --> flag
Guido van Rossum30a685f1991-06-27 15:51:29 +000060- s.bind(sockaddr) --> None
61- s.connect(sockaddr) --> None
Guido van Rossum30a685f1991-06-27 15:51:29 +000062- s.listen(n) --> None
63- s.makefile(mode) --> file object
64- s.recv(nbytes) --> string
65- s.recvfrom(nbytes) --> string, sockaddr
66- s.send(string) --> None
67- s.sendto(string, sockaddr) --> None
68- s.shutdown(how) --> None
69- s.close() --> None
70
Guido van Rossum6574b3e1991-06-25 21:36:08 +000071*/
72
73#include "allobjects.h"
74#include "modsupport.h"
75
Guido van Rossum81194471991-07-27 21:42:02 +000076#include <signal.h>
Guido van Rossum6574b3e1991-06-25 21:36:08 +000077#include <sys/types.h>
78#include <sys/socket.h>
Guido van Rossum81194471991-07-27 21:42:02 +000079#include <sys/time.h> /* Needed for struct timeval */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000080#include <netinet/in.h>
81#include <sys/un.h>
82#include <netdb.h>
Guido van Rossum81194471991-07-27 21:42:02 +000083#ifdef _AIX /* I *think* this works */
Guido van Rossum0bb1a511991-11-27 14:55:18 +000084/* AIX defines fd_set in a separate file. Sigh... */
85#include <sys/select.h>
Guido van Rossum81194471991-07-27 21:42:02 +000086#endif
Guido van Rossum6574b3e1991-06-25 21:36:08 +000087
Guido van Rossum30a685f1991-06-27 15:51:29 +000088
89/* Global variable holding the exception type for errors detected
90 by this module (but not argument type or memory errors, etc.). */
91
92static object *SocketError;
93
94
95/* Convenience function to raise an error according to errno
96 and return a NULL pointer from a function. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000097
98static object *
99socket_error()
100{
101 return err_errno(SocketError);
102}
103
Guido van Rossum30a685f1991-06-27 15:51:29 +0000104
105/* The object holding a socket. It holds some extra information,
106 like the address family, which is used to decode socket address
107 arguments properly. */
108
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000109typedef struct {
110 OB_HEAD
Guido van Rossum30a685f1991-06-27 15:51:29 +0000111 int sock_fd; /* Socket file descriptor */
112 int sock_family; /* Address family, e.g., AF_INET */
113 int sock_type; /* Socket type, e.g., SOCK_STREAM */
114 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000115} sockobject;
116
Guido van Rossum30a685f1991-06-27 15:51:29 +0000117
118/* A forward reference to the Socktype type object.
119 The Socktype variable contains pointers to various functions,
120 some of which call newsocobject(), which uses Socktype, so
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000121 there has to be a circular reference. */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000122
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000123extern typeobject Socktype; /* Forward */
124
Guido van Rossum30a685f1991-06-27 15:51:29 +0000125
126/* Create a new socket object.
127 This just creates the object and initializes it.
128 If the creation fails, return NULL and set an exception (implicit
129 in NEWOBJ()). */
130
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000131static sockobject *
132newsockobject(fd, family, type, proto)
133 int fd, family, type, proto;
134{
135 sockobject *s;
136 s = NEWOBJ(sockobject, &Socktype);
137 if (s != NULL) {
138 s->sock_fd = fd;
139 s->sock_family = family;
140 s->sock_type = type;
141 s->sock_proto = proto;
142 }
143 return s;
144}
145
Guido van Rossum30a685f1991-06-27 15:51:29 +0000146
147/* Convert a string specifying a host name or one of a few symbolic
148 names to a numeric IP address. This usually calls gethostbyname()
149 to do the work; the names "" and "<broadcast>" are special.
150 Return the length (should always be 4 bytes), or negative if
151 an error occurred; then an exception is raised. */
152
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000153static int
Guido van Rossum30a685f1991-06-27 15:51:29 +0000154setipaddr(name, addr_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000155 char *name;
156 struct sockaddr_in *addr_ret;
157{
158 struct hostent *hp;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000159 int d1, d2, d3, d4;
160 char ch;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000161
Guido van Rossum30a685f1991-06-27 15:51:29 +0000162 if (name[0] == '\0') {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000163 addr_ret->sin_addr.s_addr = INADDR_ANY;
164 return 4;
165 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000166 if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000167 addr_ret->sin_addr.s_addr = INADDR_BROADCAST;
168 return 4;
169 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000170 if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
171 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
172 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
173 addr_ret->sin_addr.s_addr = htonl(
174 ((long) d1 << 24) | ((long) d2 << 16) |
175 ((long) d3 << 8) | ((long) d4 << 0));
176 return 4;
177 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000178 hp = gethostbyname(name);
179 if (hp == NULL) {
180 err_setstr(SocketError, "host not found");
181 return -1;
182 }
183 memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
184 return hp->h_length;
185}
186
Guido van Rossum30a685f1991-06-27 15:51:29 +0000187
188/* Generally useful convenience function to create a tuple from two
189 objects. This eats references to the objects; if either is NULL
190 it destroys the other and returns NULL without raising an exception
191 (assuming the function that was called to create the argument must
192 have raised an exception and returned NULL). */
193
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000194static object *
195makepair(a, b)
196 object *a, *b;
197{
198 object *pair = NULL;
199 if (a == NULL || b == NULL || (pair = newtupleobject(2)) == NULL) {
200 XDECREF(a);
201 XDECREF(b);
202 return NULL;
203 }
204 settupleitem(pair, 0, a);
205 settupleitem(pair, 1, b);
206 return pair;
207}
208
Guido van Rossum30a685f1991-06-27 15:51:29 +0000209
210/* Create a string object representing an IP address.
211 This is always a string of the form 'dd.dd.dd.dd' (with variable
212 size numbers). */
213
214static object *
215makeipaddr(addr)
216 struct sockaddr_in *addr;
217{
218 long x = ntohl(addr->sin_addr.s_addr);
219 char buf[100];
220 sprintf(buf, "%d.%d.%d.%d",
221 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
222 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
223 return newstringobject(buf);
224}
225
226
227/* Create an object representing the given socket address,
228 suitable for passing it back to bind(), connect() etc.
229 The family field of the sockaddr structure is inspected
230 to determine what kind of address it really is. */
231
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000232/*ARGSUSED*/
233static object *
234makesockaddr(addr, addrlen)
235 struct sockaddr *addr;
236 int addrlen;
237{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000238 switch (addr->sa_family) {
239
240 case AF_INET:
241 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000242 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000243 return makepair(makeipaddr(a),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000244 newintobject((long) ntohs(a->sin_port)));
245 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000246
247 case AF_UNIX:
248 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000249 struct sockaddr_un *a = (struct sockaddr_un *) addr;
250 return newstringobject(a->sun_path);
251 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000252
253 /* More cases here... */
254
255 default:
256 err_setstr(SocketError, "return unknown socket address type");
257 return NULL;
258 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000259}
260
Guido van Rossum30a685f1991-06-27 15:51:29 +0000261
262/* Parse a socket address argument according to the socket object's
263 address family. Return 1 if the address was in the proper format,
264 0 of not. The address is returned through addr_ret, its length
265 through len_ret. */
266
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000267static int
268getsockaddrarg(s, args, addr_ret, len_ret)
269 sockobject *s;
270 object *args;
271 struct sockaddr **addr_ret;
272 int *len_ret;
273{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000274 switch (s->sock_family) {
275
276 case AF_UNIX:
277 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000278 static struct sockaddr_un addr;
279 object *path;
280 int len;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000281 if (!getStrarg(args, &path))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000282 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000283 if ((len = getstringsize(path)) > sizeof addr.sun_path) {
284 err_setstr(SocketError, "AF_UNIX path too long");
285 return 0;
286 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000287 addr.sun_family = AF_UNIX;
288 memcpy(addr.sun_path, getstringvalue(path), len);
289 *addr_ret = (struct sockaddr *) &addr;
290 *len_ret = len + sizeof addr.sun_family;
291 return 1;
292 }
293
Guido van Rossum30a685f1991-06-27 15:51:29 +0000294 case AF_INET:
295 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000296 static struct sockaddr_in addr;
297 object *host;
298 int port;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000299 if (!getStrintarg(args, &host, &port))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000300 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000301 if (setipaddr(getstringvalue(host), &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000302 return 0;
303 addr.sin_family = AF_INET;
304 addr.sin_port = htons(port);
305 *addr_ret = (struct sockaddr *) &addr;
306 *len_ret = sizeof addr;
307 return 1;
308 }
309
Guido van Rossum30a685f1991-06-27 15:51:29 +0000310 /* More cases here... */
311
312 default:
313 err_setstr(SocketError, "getsockaddrarg: bad family");
314 return 0;
315
316 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000317}
318
Guido van Rossum30a685f1991-06-27 15:51:29 +0000319
320/* s.accept() method */
321
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000322static object *
323sock_accept(s, args)
324 sockobject *s;
325 object *args;
326{
327 char addrbuf[256];
328 int addrlen, newfd;
329 object *res;
330 if (!getnoarg(args))
331 return NULL;
332 addrlen = sizeof addrbuf;
333 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
334 if (newfd < 0)
335 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000336 /* Create the new object with unspecified family,
337 to avoid calls to bind() etc. on it. */
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000338 res = makepair((object *) newsockobject(newfd,
339 s->sock_family,
340 s->sock_type,
341 s->sock_proto),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000342 makesockaddr((struct sockaddr *) addrbuf, addrlen));
343 if (res == NULL)
344 close(newfd);
345 return res;
346}
347
Guido van Rossum30a685f1991-06-27 15:51:29 +0000348
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000349/* s.allowbroadcast() method */
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000350/* XXX obsolete -- will disappear in next release */
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000351
352static object *
353sock_allowbroadcast(s, args)
354 sockobject *s;
355 object *args;
356{
357 int flag;
358 int res;
359 if (!getintarg(args, &flag))
360 return NULL;
361 res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
362 &flag, sizeof flag);
363 if (res < 0)
364 return socket_error();
365 INCREF(None);
366 return None;
367}
368
369
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000370/* s.setsockopt() method */
371/* XXX this works for integer flags only */
372
373static object *
374sock_setsockopt(s, args)
375 sockobject *s;
376 object *args;
377{
378 int level;
379 int optname;
380 int flag;
381 int res;
382
383 if (!getargs(args, "(iii)", &level, &optname, &flag))
384 return NULL;
385 res = setsockopt(s->sock_fd, level, optname, &flag, sizeof flag);
386 if (res < 0)
387 return socket_error();
388 INCREF(None);
389 return None;
390}
391
392
393/* s.getsockopt() method */
394/* XXX this works for integer flags only */
395
396static object *
397sock_getsockopt(s, args)
398 sockobject *s;
399 object *args;
400{
401 int level;
402 int optname;
403 int flag;
404 int flagsize;
405 int res;
406
407 if (!getargs(args, "(ii)", &level, &optname))
408 return NULL;
409 flagsize = sizeof flag;
410 flag = 0;
411 res = getsockopt(s->sock_fd, level, optname, &flag, &flagsize);
412 if (res < 0)
413 return socket_error();
414 return newintobject(flag);
415}
416
417
Guido van Rossum81194471991-07-27 21:42:02 +0000418/* s.avail() method */
419
420static object *
421sock_avail(s, args)
422 sockobject *s;
423 object *args;
424{
425 struct timeval timeout;
426 fd_set readers;
427 int n;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000428 if (!getnoarg(args))
429 return NULL;
Guido van Rossum81194471991-07-27 21:42:02 +0000430 timeout.tv_sec = 0;
431 timeout.tv_usec = 0;
432 FD_ZERO(&readers);
433 FD_SET(s->sock_fd, &readers);
434 n = select(s->sock_fd+1, &readers, (fd_set *)0, (fd_set *)0, &timeout);
435 if (n < 0)
436 return socket_error();
437 return newintobject((long) (n != 0));
438}
439
440
Guido van Rossum30a685f1991-06-27 15:51:29 +0000441/* s.bind(sockaddr) method */
442
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000443static object *
444sock_bind(s, args)
445 sockobject *s;
446 object *args;
447{
448 struct sockaddr *addr;
449 int addrlen;
450 if (!getsockaddrarg(s, args, &addr, &addrlen))
451 return NULL;
452 if (bind(s->sock_fd, addr, addrlen) < 0)
453 return socket_error();
454 INCREF(None);
455 return None;
456}
457
Guido van Rossum30a685f1991-06-27 15:51:29 +0000458
459/* s.close() method.
460 Set the file descriptor to -1 so operations tried subsequently
461 will surely fail. */
462
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000463static object *
464sock_close(s, args)
465 sockobject *s;
466 object *args;
467{
468 if (!getnoarg(args))
469 return NULL;
470 (void) close(s->sock_fd);
471 s->sock_fd = -1;
472 INCREF(None);
473 return None;
474}
475
Guido van Rossum30a685f1991-06-27 15:51:29 +0000476
477/* s.connect(sockaddr) method */
478
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000479static object *
480sock_connect(s, args)
481 sockobject *s;
482 object *args;
483{
484 struct sockaddr *addr;
485 int addrlen;
486 if (!getsockaddrarg(s, args, &addr, &addrlen))
487 return NULL;
488 if (connect(s->sock_fd, addr, addrlen) < 0)
489 return socket_error();
490 INCREF(None);
491 return None;
492}
493
Guido van Rossum30a685f1991-06-27 15:51:29 +0000494
495/* s.listen(n) method */
496
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000497static object *
498sock_listen(s, args)
499 sockobject *s;
500 object *args;
501{
502 int backlog;
503 if (!getintarg(args, &backlog))
504 return NULL;
505 if (listen(s->sock_fd, backlog) < 0)
506 return socket_error();
507 INCREF(None);
508 return None;
509}
510
Guido van Rossum30a685f1991-06-27 15:51:29 +0000511
512/* s.makefile(mode) method.
513 Create a new open file object referring to a dupped version of
514 the socket's file descriptor. (The dup() call is necessary so
515 that the open file and socket objects may be closed independent
516 of each other.)
517 The mode argument specifies 'r' or 'w' passed to fdopen(). */
518
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000519static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000520sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000521 sockobject *s;
522 object *args;
523{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000524 extern int fclose PROTO((FILE *));
525 object *mode;
526 int fd;
527 FILE *fp;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000528 if (!getStrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000529 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000530 if ((fd = dup(s->sock_fd)) < 0 ||
531 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
532 return socket_error();
533 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
534}
535
536
537/* s.recv(nbytes) method */
538
539static object *
540sock_recv(s, args)
541 sockobject *s;
542 object *args;
543{
544 int len, n, flags;
545 object *buf;
546 if (!getintintarg(args, &len, &flags)) {
547 err_clear();
548 if (!getintarg(args, &len))
549 return NULL;
550 flags = 0;
551 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000552 buf = newsizedstringobject((char *) 0, len);
553 if (buf == NULL)
554 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000555 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000556 if (n < 0)
557 return socket_error();
558 if (resizestring(&buf, n) < 0)
559 return NULL;
560 return buf;
561}
562
Guido van Rossum30a685f1991-06-27 15:51:29 +0000563
564/* s.recvfrom(nbytes) method */
565
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000566static object *
567sock_recvfrom(s, args)
568 sockobject *s;
569 object *args;
570{
571 char addrbuf[256];
572 object *buf;
573 int addrlen, len, n;
574 if (!getintarg(args, &len))
575 return NULL;
576 buf = newsizedstringobject((char *) 0, len);
577 addrlen = sizeof addrbuf;
578 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
579 addrbuf, &addrlen);
580 if (n < 0)
581 return socket_error();
582 if (resizestring(&buf, n) < 0)
583 return NULL;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000584 return makepair(buf,
585 makesockaddr((struct sockaddr *)addrbuf, addrlen));
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000586}
587
Guido van Rossum30a685f1991-06-27 15:51:29 +0000588
589/* s.send(data) method */
590
591static object *
592sock_send(s, args)
593 sockobject *s;
594 object *args;
595{
596 object *buf;
597 int len, n, flags;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000598 if (!getStrintarg(args, &buf, &flags)) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000599 err_clear();
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000600 if (!getStrarg(args, &buf))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000601 return NULL;
602 flags = 0;
603 }
604 len = getstringsize(buf);
605 n = send(s->sock_fd, getstringvalue(buf), len, flags);
606 if (n < 0)
607 return socket_error();
608 INCREF(None);
609 return None;
610}
611
612
613/* s.sendto(data, sockaddr) method */
614
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000615static object *
616sock_sendto(s, args)
617 sockobject *s;
618 object *args;
619{
620 object *buf;
621 struct sockaddr *addr;
622 int addrlen, len, n;
623 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
624 err_badarg();
625 return NULL;
626 }
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000627 if (!getStrarg(gettupleitem(args, 0), &buf) ||
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000628 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
629 return NULL;
630 len = getstringsize(buf);
631 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
632 addr, addrlen);
633 if (n < 0)
634 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000635 INCREF(None);
636 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000637}
638
Guido van Rossum30a685f1991-06-27 15:51:29 +0000639
640/* s.shutdown(how) method */
641
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000642static object *
643sock_shutdown(s, args)
644 sockobject *s;
645 object *args;
646{
647 int how;
648 if (!getintarg(args, &how))
649 return NULL;
650 if (shutdown(s->sock_fd, how) < 0)
651 return socket_error();
652 INCREF(None);
653 return None;
654}
655
Guido van Rossum30a685f1991-06-27 15:51:29 +0000656
657/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000658
659static struct methodlist sock_methods[] = {
660 {"accept", sock_accept},
Guido van Rossum81194471991-07-27 21:42:02 +0000661 {"avail", sock_avail},
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000662 {"allowbroadcast", sock_allowbroadcast},
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000663 {"setsockopt", sock_setsockopt},
664 {"getsockopt", sock_getsockopt},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000665 {"bind", sock_bind},
666 {"close", sock_close},
667 {"connect", sock_connect},
668 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000669 {"makefile", sock_makefile},
670 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000671 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000672 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000673 {"sendto", sock_sendto},
674 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000675 {NULL, NULL} /* sentinel */
676};
677
Guido van Rossum30a685f1991-06-27 15:51:29 +0000678
679/* Deallocate a socket object in response to the last DECREF().
680 First close the file description. */
681
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000682static void
683sock_dealloc(s)
684 sockobject *s;
685{
686 (void) close(s->sock_fd);
687 DEL(s);
688}
689
Guido van Rossum30a685f1991-06-27 15:51:29 +0000690
691/* Return a socket object's named attribute. */
692
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000693static object *
694sock_getattr(s, name)
695 sockobject *s;
696 char *name;
697{
698 return findmethod(sock_methods, (object *) s, name);
699}
700
Guido van Rossum30a685f1991-06-27 15:51:29 +0000701
702/* Type object for socket objects.
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000703 XXX This should be static, but some compilers don't grok the
704 XXX forward reference to it in that case... */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000705
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000706typeobject Socktype = {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000707 OB_HEAD_INIT(&Typetype)
708 0,
709 "socket",
710 sizeof(sockobject),
711 0,
712 sock_dealloc, /*tp_dealloc*/
713 0, /*tp_print*/
714 sock_getattr, /*tp_getattr*/
715 0, /*tp_setattr*/
716 0, /*tp_compare*/
717 0, /*tp_repr*/
718 0, /*tp_as_number*/
719 0, /*tp_as_sequence*/
720 0, /*tp_as_mapping*/
721};
722
Guido van Rossum30a685f1991-06-27 15:51:29 +0000723
Guido van Rossum81194471991-07-27 21:42:02 +0000724/* Python interface to gethostname(). */
725
726/*ARGSUSED*/
727static object *
728socket_gethostname(self, args)
729 object *self;
730 object *args;
731{
732 char buf[1024];
733 if (!getnoarg(args))
734 return NULL;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000735 if (gethostname(buf, (int) sizeof buf - 1) < 0)
Guido van Rossum81194471991-07-27 21:42:02 +0000736 return socket_error();
737 buf[sizeof buf - 1] = '\0';
738 return newstringobject(buf);
739}
Guido van Rossum30a685f1991-06-27 15:51:29 +0000740/* Python interface to gethostbyname(name). */
741
742/*ARGSUSED*/
743static object *
744socket_gethostbyname(self, args)
745 object *self;
746 object *args;
747{
748 object *name;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000749 struct sockaddr_in addrbuf;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000750 if (!getStrarg(args, &name))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000751 return NULL;
752 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
753 return NULL;
754 return makeipaddr(&addrbuf);
755}
756
757
758/* Python interface to getservbyname(name).
759 This only returns the port number, since the other info is already
760 known or not useful (like the list of aliases). */
761
762/*ARGSUSED*/
763static object *
764socket_getservbyname(self, args)
765 object *self;
766 object *args;
767{
768 object *name, *proto;
769 struct servent *sp;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000770 if (!getStrStrarg(args, &name, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000771 return NULL;
772 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
773 if (sp == NULL) {
774 err_setstr(SocketError, "service/proto not found");
775 return NULL;
776 }
777 return newintobject((long) ntohs(sp->s_port));
778}
779
780
781/* Python interface to socket(family, type, proto).
782 The third (protocol) argument is optional.
783 Return a new socket object. */
784
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000785/*ARGSUSED*/
786static object *
787socket_socket(self, args)
788 object *self;
789 object *args;
790{
791 sockobject *s;
792 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000793 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000794 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000795 return NULL;
796 }
797 else {
798 if (!getintintarg(args, &family, &type))
799 return NULL;
800 proto = 0;
801 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000802 fd = socket(family, type, proto);
803 if (fd < 0)
804 return socket_error();
805 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000806 /* If the object can't be created, don't forget to close the
807 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000808 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000809 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000810 /* From now on, ignore SIGPIPE and let the error checking
811 do the work. */
812 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000813 return (object *) s;
814}
815
Guido van Rossum30a685f1991-06-27 15:51:29 +0000816
817/* List of functions exported by this module. */
818
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000819static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000820 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +0000821 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000822 {"getservbyname", socket_getservbyname},
823 {"socket", socket_socket},
824 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000825};
826
Guido van Rossum30a685f1991-06-27 15:51:29 +0000827
828/* Convenience routine to export an integer value.
829 For simplicity, errors (which are unlikely anyway) are ignored. */
830
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000831static void
832insint(d, name, value)
833 object *d;
834 char *name;
835 int value;
836{
837 object *v = newintobject((long) value);
838 if (v == NULL) {
839 /* Don't bother reporting this error */
840 err_clear();
841 }
842 else {
843 dictinsert(d, name, v);
844 DECREF(v);
845 }
846}
847
Guido van Rossum30a685f1991-06-27 15:51:29 +0000848
849/* Initialize this module.
850 This is called when the first 'import socket' is done,
851 via a table in config.c, if config.c is compiled with USE_SOCKET
852 defined. */
853
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000854void
855initsocket()
856{
857 object *m, *d;
858
859 m = initmodule("socket", socket_methods);
860 d = getmoduledict(m);
861 SocketError = newstringobject("socket.error");
862 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
863 fatal("can't define socket.error");
864 insint(d, "AF_INET", AF_INET);
865 insint(d, "AF_UNIX", AF_UNIX);
866 insint(d, "SOCK_STREAM", SOCK_STREAM);
867 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
868 insint(d, "SOCK_RAW", SOCK_RAW);
869 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
870 insint(d, "SOCK_RDM", SOCK_RDM);
871}