blob: 97fea0977f1a83d43bc474a7a168f01f0cadd8b1 [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 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;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000378 if (!getnoarg(args))
379 return NULL;
Guido van Rossum81194471991-07-27 21:42:02 +0000380 timeout.tv_sec = 0;
381 timeout.tv_usec = 0;
382 FD_ZERO(&readers);
383 FD_SET(s->sock_fd, &readers);
384 n = select(s->sock_fd+1, &readers, (fd_set *)0, (fd_set *)0, &timeout);
385 if (n < 0)
386 return socket_error();
387 return newintobject((long) (n != 0));
388}
389
390
Guido van Rossum30a685f1991-06-27 15:51:29 +0000391/* s.bind(sockaddr) method */
392
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000393static object *
394sock_bind(s, args)
395 sockobject *s;
396 object *args;
397{
398 struct sockaddr *addr;
399 int addrlen;
400 if (!getsockaddrarg(s, args, &addr, &addrlen))
401 return NULL;
402 if (bind(s->sock_fd, addr, addrlen) < 0)
403 return socket_error();
404 INCREF(None);
405 return None;
406}
407
Guido van Rossum30a685f1991-06-27 15:51:29 +0000408
409/* s.close() method.
410 Set the file descriptor to -1 so operations tried subsequently
411 will surely fail. */
412
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000413static object *
414sock_close(s, args)
415 sockobject *s;
416 object *args;
417{
418 if (!getnoarg(args))
419 return NULL;
420 (void) close(s->sock_fd);
421 s->sock_fd = -1;
422 INCREF(None);
423 return None;
424}
425
Guido van Rossum30a685f1991-06-27 15:51:29 +0000426
427/* s.connect(sockaddr) method */
428
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000429static object *
430sock_connect(s, args)
431 sockobject *s;
432 object *args;
433{
434 struct sockaddr *addr;
435 int addrlen;
436 if (!getsockaddrarg(s, args, &addr, &addrlen))
437 return NULL;
438 if (connect(s->sock_fd, addr, addrlen) < 0)
439 return socket_error();
440 INCREF(None);
441 return None;
442}
443
Guido van Rossum30a685f1991-06-27 15:51:29 +0000444
445/* s.listen(n) method */
446
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000447static object *
448sock_listen(s, args)
449 sockobject *s;
450 object *args;
451{
452 int backlog;
453 if (!getintarg(args, &backlog))
454 return NULL;
455 if (listen(s->sock_fd, backlog) < 0)
456 return socket_error();
457 INCREF(None);
458 return None;
459}
460
Guido van Rossum30a685f1991-06-27 15:51:29 +0000461
462/* s.makefile(mode) method.
463 Create a new open file object referring to a dupped version of
464 the socket's file descriptor. (The dup() call is necessary so
465 that the open file and socket objects may be closed independent
466 of each other.)
467 The mode argument specifies 'r' or 'w' passed to fdopen(). */
468
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000469static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000470sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000471 sockobject *s;
472 object *args;
473{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000474 extern int fclose PROTO((FILE *));
475 object *mode;
476 int fd;
477 FILE *fp;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000478 if (!getStrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000479 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000480 if ((fd = dup(s->sock_fd)) < 0 ||
481 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
482 return socket_error();
483 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
484}
485
486
487/* s.recv(nbytes) method */
488
489static object *
490sock_recv(s, args)
491 sockobject *s;
492 object *args;
493{
494 int len, n, flags;
495 object *buf;
496 if (!getintintarg(args, &len, &flags)) {
497 err_clear();
498 if (!getintarg(args, &len))
499 return NULL;
500 flags = 0;
501 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000502 buf = newsizedstringobject((char *) 0, len);
503 if (buf == NULL)
504 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000505 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000506 if (n < 0)
507 return socket_error();
508 if (resizestring(&buf, n) < 0)
509 return NULL;
510 return buf;
511}
512
Guido van Rossum30a685f1991-06-27 15:51:29 +0000513
514/* s.recvfrom(nbytes) method */
515
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000516static object *
517sock_recvfrom(s, args)
518 sockobject *s;
519 object *args;
520{
521 char addrbuf[256];
522 object *buf;
523 int addrlen, len, n;
524 if (!getintarg(args, &len))
525 return NULL;
526 buf = newsizedstringobject((char *) 0, len);
527 addrlen = sizeof addrbuf;
528 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
529 addrbuf, &addrlen);
530 if (n < 0)
531 return socket_error();
532 if (resizestring(&buf, n) < 0)
533 return NULL;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000534 return makepair(buf,
535 makesockaddr((struct sockaddr *)addrbuf, addrlen));
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000536}
537
Guido van Rossum30a685f1991-06-27 15:51:29 +0000538
539/* s.send(data) method */
540
541static object *
542sock_send(s, args)
543 sockobject *s;
544 object *args;
545{
546 object *buf;
547 int len, n, flags;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000548 if (!getStrintarg(args, &buf, &flags)) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000549 err_clear();
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000550 if (!getStrarg(args, &buf))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000551 return NULL;
552 flags = 0;
553 }
554 len = getstringsize(buf);
555 n = send(s->sock_fd, getstringvalue(buf), len, flags);
556 if (n < 0)
557 return socket_error();
558 INCREF(None);
559 return None;
560}
561
562
563/* s.sendto(data, sockaddr) method */
564
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000565static object *
566sock_sendto(s, args)
567 sockobject *s;
568 object *args;
569{
570 object *buf;
571 struct sockaddr *addr;
572 int addrlen, len, n;
573 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
574 err_badarg();
575 return NULL;
576 }
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000577 if (!getStrarg(gettupleitem(args, 0), &buf) ||
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000578 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
579 return NULL;
580 len = getstringsize(buf);
581 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
582 addr, addrlen);
583 if (n < 0)
584 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000585 INCREF(None);
586 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000587}
588
Guido van Rossum30a685f1991-06-27 15:51:29 +0000589
590/* s.shutdown(how) method */
591
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000592static object *
593sock_shutdown(s, args)
594 sockobject *s;
595 object *args;
596{
597 int how;
598 if (!getintarg(args, &how))
599 return NULL;
600 if (shutdown(s->sock_fd, how) < 0)
601 return socket_error();
602 INCREF(None);
603 return None;
604}
605
Guido van Rossum30a685f1991-06-27 15:51:29 +0000606
607/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000608
609static struct methodlist sock_methods[] = {
610 {"accept", sock_accept},
Guido van Rossum81194471991-07-27 21:42:02 +0000611 {"avail", sock_avail},
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000612 {"allowbroadcast", sock_allowbroadcast},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000613 {"bind", sock_bind},
614 {"close", sock_close},
615 {"connect", sock_connect},
616 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000617 {"makefile", sock_makefile},
618 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000619 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000620 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000621 {"sendto", sock_sendto},
622 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000623 {NULL, NULL} /* sentinel */
624};
625
Guido van Rossum30a685f1991-06-27 15:51:29 +0000626
627/* Deallocate a socket object in response to the last DECREF().
628 First close the file description. */
629
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000630static void
631sock_dealloc(s)
632 sockobject *s;
633{
634 (void) close(s->sock_fd);
635 DEL(s);
636}
637
Guido van Rossum30a685f1991-06-27 15:51:29 +0000638
639/* Return a socket object's named attribute. */
640
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000641static object *
642sock_getattr(s, name)
643 sockobject *s;
644 char *name;
645{
646 return findmethod(sock_methods, (object *) s, name);
647}
648
Guido van Rossum30a685f1991-06-27 15:51:29 +0000649
650/* Type object for socket objects.
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000651 XXX This should be static, but some compilers don't grok the
652 XXX forward reference to it in that case... */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000653
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000654typeobject Socktype = {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000655 OB_HEAD_INIT(&Typetype)
656 0,
657 "socket",
658 sizeof(sockobject),
659 0,
660 sock_dealloc, /*tp_dealloc*/
661 0, /*tp_print*/
662 sock_getattr, /*tp_getattr*/
663 0, /*tp_setattr*/
664 0, /*tp_compare*/
665 0, /*tp_repr*/
666 0, /*tp_as_number*/
667 0, /*tp_as_sequence*/
668 0, /*tp_as_mapping*/
669};
670
Guido van Rossum30a685f1991-06-27 15:51:29 +0000671
Guido van Rossum81194471991-07-27 21:42:02 +0000672/* Python interface to gethostname(). */
673
674/*ARGSUSED*/
675static object *
676socket_gethostname(self, args)
677 object *self;
678 object *args;
679{
680 char buf[1024];
681 if (!getnoarg(args))
682 return NULL;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000683 if (gethostname(buf, (int) sizeof buf - 1) < 0)
Guido van Rossum81194471991-07-27 21:42:02 +0000684 return socket_error();
685 buf[sizeof buf - 1] = '\0';
686 return newstringobject(buf);
687}
Guido van Rossum30a685f1991-06-27 15:51:29 +0000688/* Python interface to gethostbyname(name). */
689
690/*ARGSUSED*/
691static object *
692socket_gethostbyname(self, args)
693 object *self;
694 object *args;
695{
696 object *name;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000697 struct sockaddr_in addrbuf;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000698 if (!getStrarg(args, &name))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000699 return NULL;
700 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
701 return NULL;
702 return makeipaddr(&addrbuf);
703}
704
705
706/* Python interface to getservbyname(name).
707 This only returns the port number, since the other info is already
708 known or not useful (like the list of aliases). */
709
710/*ARGSUSED*/
711static object *
712socket_getservbyname(self, args)
713 object *self;
714 object *args;
715{
716 object *name, *proto;
717 struct servent *sp;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000718 if (!getStrStrarg(args, &name, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000719 return NULL;
720 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
721 if (sp == NULL) {
722 err_setstr(SocketError, "service/proto not found");
723 return NULL;
724 }
725 return newintobject((long) ntohs(sp->s_port));
726}
727
728
729/* Python interface to socket(family, type, proto).
730 The third (protocol) argument is optional.
731 Return a new socket object. */
732
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000733/*ARGSUSED*/
734static object *
735socket_socket(self, args)
736 object *self;
737 object *args;
738{
739 sockobject *s;
740 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000741 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000742 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000743 return NULL;
744 }
745 else {
746 if (!getintintarg(args, &family, &type))
747 return NULL;
748 proto = 0;
749 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000750 fd = socket(family, type, proto);
751 if (fd < 0)
752 return socket_error();
753 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000754 /* If the object can't be created, don't forget to close the
755 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000756 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000757 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000758 /* From now on, ignore SIGPIPE and let the error checking
759 do the work. */
760 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000761 return (object *) s;
762}
763
Guido van Rossum30a685f1991-06-27 15:51:29 +0000764
765/* List of functions exported by this module. */
766
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000767static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000768 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +0000769 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000770 {"getservbyname", socket_getservbyname},
771 {"socket", socket_socket},
772 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000773};
774
Guido van Rossum30a685f1991-06-27 15:51:29 +0000775
776/* Convenience routine to export an integer value.
777 For simplicity, errors (which are unlikely anyway) are ignored. */
778
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000779static void
780insint(d, name, value)
781 object *d;
782 char *name;
783 int value;
784{
785 object *v = newintobject((long) value);
786 if (v == NULL) {
787 /* Don't bother reporting this error */
788 err_clear();
789 }
790 else {
791 dictinsert(d, name, v);
792 DECREF(v);
793 }
794}
795
Guido van Rossum30a685f1991-06-27 15:51:29 +0000796
797/* Initialize this module.
798 This is called when the first 'import socket' is done,
799 via a table in config.c, if config.c is compiled with USE_SOCKET
800 defined. */
801
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000802void
803initsocket()
804{
805 object *m, *d;
806
807 m = initmodule("socket", socket_methods);
808 d = getmoduledict(m);
809 SocketError = newstringobject("socket.error");
810 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
811 fatal("can't define socket.error");
812 insint(d, "AF_INET", AF_INET);
813 insint(d, "AF_UNIX", AF_UNIX);
814 insint(d, "SOCK_STREAM", SOCK_STREAM);
815 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
816 insint(d, "SOCK_RAW", SOCK_RAW);
817 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
818 insint(d, "SOCK_RDM", SOCK_RDM);
819}