blob: 849eec41f60c8c90bc7dfe46435abee6102d5bb1 [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 Rossume0e5edc1991-10-20 20:22:28 +000036- no general setsockopt() call (but see s.allowbroadcast())
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 Rossume0e5edc1991-10-20 20:22:28 +000056- s.allowbroadcast(boolean) --> None
Guido van Rossum30a685f1991-06-27 15:51:29 +000057- s.bind(sockaddr) --> None
58- s.connect(sockaddr) --> None
Guido van Rossum30a685f1991-06-27 15:51:29 +000059- s.listen(n) --> None
60- s.makefile(mode) --> file object
61- s.recv(nbytes) --> string
62- s.recvfrom(nbytes) --> string, sockaddr
63- s.send(string) --> None
64- s.sendto(string, sockaddr) --> None
65- s.shutdown(how) --> None
66- s.close() --> None
67
Guido van Rossum6574b3e1991-06-25 21:36:08 +000068*/
69
70#include "allobjects.h"
71#include "modsupport.h"
72
Guido van Rossum81194471991-07-27 21:42:02 +000073#include <signal.h>
Guido van Rossum6574b3e1991-06-25 21:36:08 +000074#include <sys/types.h>
75#include <sys/socket.h>
Guido van Rossum81194471991-07-27 21:42:02 +000076#include <sys/time.h> /* Needed for struct timeval */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000077#include <netinet/in.h>
78#include <sys/un.h>
79#include <netdb.h>
Guido van Rossum81194471991-07-27 21:42:02 +000080#ifdef _AIX /* I *think* this works */
81#include <select.h> /* Needed for fd_set */
82#endif
Guido van Rossum6574b3e1991-06-25 21:36:08 +000083
Guido van Rossum30a685f1991-06-27 15:51:29 +000084
85/* Global variable holding the exception type for errors detected
86 by this module (but not argument type or memory errors, etc.). */
87
88static object *SocketError;
89
90
91/* Convenience function to raise an error according to errno
92 and return a NULL pointer from a function. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000093
94static object *
95socket_error()
96{
97 return err_errno(SocketError);
98}
99
Guido van Rossum30a685f1991-06-27 15:51:29 +0000100
101/* The object holding a socket. It holds some extra information,
102 like the address family, which is used to decode socket address
103 arguments properly. */
104
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000105typedef struct {
106 OB_HEAD
Guido van Rossum30a685f1991-06-27 15:51:29 +0000107 int sock_fd; /* Socket file descriptor */
108 int sock_family; /* Address family, e.g., AF_INET */
109 int sock_type; /* Socket type, e.g., SOCK_STREAM */
110 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000111} sockobject;
112
Guido van Rossum30a685f1991-06-27 15:51:29 +0000113
114/* A forward reference to the Socktype type object.
115 The Socktype variable contains pointers to various functions,
116 some of which call newsocobject(), which uses Socktype, so
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000117 there has to be a circular reference. */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000118
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000119extern typeobject Socktype; /* Forward */
120
Guido van Rossum30a685f1991-06-27 15:51:29 +0000121
122/* Create a new socket object.
123 This just creates the object and initializes it.
124 If the creation fails, return NULL and set an exception (implicit
125 in NEWOBJ()). */
126
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000127static sockobject *
128newsockobject(fd, family, type, proto)
129 int fd, family, type, proto;
130{
131 sockobject *s;
132 s = NEWOBJ(sockobject, &Socktype);
133 if (s != NULL) {
134 s->sock_fd = fd;
135 s->sock_family = family;
136 s->sock_type = type;
137 s->sock_proto = proto;
138 }
139 return s;
140}
141
Guido van Rossum30a685f1991-06-27 15:51:29 +0000142
143/* Convert a string specifying a host name or one of a few symbolic
144 names to a numeric IP address. This usually calls gethostbyname()
145 to do the work; the names "" and "<broadcast>" are special.
146 Return the length (should always be 4 bytes), or negative if
147 an error occurred; then an exception is raised. */
148
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000149static int
Guido van Rossum30a685f1991-06-27 15:51:29 +0000150setipaddr(name, addr_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000151 char *name;
152 struct sockaddr_in *addr_ret;
153{
154 struct hostent *hp;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000155 int d1, d2, d3, d4;
156 char ch;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000157
Guido van Rossum30a685f1991-06-27 15:51:29 +0000158 if (name[0] == '\0') {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000159 addr_ret->sin_addr.s_addr = INADDR_ANY;
160 return 4;
161 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000162 if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000163 addr_ret->sin_addr.s_addr = INADDR_BROADCAST;
164 return 4;
165 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000166 if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
167 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
168 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
169 addr_ret->sin_addr.s_addr = htonl(
170 ((long) d1 << 24) | ((long) d2 << 16) |
171 ((long) d3 << 8) | ((long) d4 << 0));
172 return 4;
173 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000174 hp = gethostbyname(name);
175 if (hp == NULL) {
176 err_setstr(SocketError, "host not found");
177 return -1;
178 }
179 memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
180 return hp->h_length;
181}
182
Guido van Rossum30a685f1991-06-27 15:51:29 +0000183
184/* Generally useful convenience function to create a tuple from two
185 objects. This eats references to the objects; if either is NULL
186 it destroys the other and returns NULL without raising an exception
187 (assuming the function that was called to create the argument must
188 have raised an exception and returned NULL). */
189
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000190static object *
191makepair(a, b)
192 object *a, *b;
193{
194 object *pair = NULL;
195 if (a == NULL || b == NULL || (pair = newtupleobject(2)) == NULL) {
196 XDECREF(a);
197 XDECREF(b);
198 return NULL;
199 }
200 settupleitem(pair, 0, a);
201 settupleitem(pair, 1, b);
202 return pair;
203}
204
Guido van Rossum30a685f1991-06-27 15:51:29 +0000205
206/* Create a string object representing an IP address.
207 This is always a string of the form 'dd.dd.dd.dd' (with variable
208 size numbers). */
209
210static object *
211makeipaddr(addr)
212 struct sockaddr_in *addr;
213{
214 long x = ntohl(addr->sin_addr.s_addr);
215 char buf[100];
216 sprintf(buf, "%d.%d.%d.%d",
217 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
218 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
219 return newstringobject(buf);
220}
221
222
223/* Create an object representing the given socket address,
224 suitable for passing it back to bind(), connect() etc.
225 The family field of the sockaddr structure is inspected
226 to determine what kind of address it really is. */
227
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000228/*ARGSUSED*/
229static object *
230makesockaddr(addr, addrlen)
231 struct sockaddr *addr;
232 int addrlen;
233{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000234 switch (addr->sa_family) {
235
236 case AF_INET:
237 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000238 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000239 return makepair(makeipaddr(a),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000240 newintobject((long) ntohs(a->sin_port)));
241 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000242
243 case AF_UNIX:
244 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000245 struct sockaddr_un *a = (struct sockaddr_un *) addr;
246 return newstringobject(a->sun_path);
247 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000248
249 /* More cases here... */
250
251 default:
252 err_setstr(SocketError, "return unknown socket address type");
253 return NULL;
254 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000255}
256
Guido van Rossum30a685f1991-06-27 15:51:29 +0000257
258/* Parse a socket address argument according to the socket object's
259 address family. Return 1 if the address was in the proper format,
260 0 of not. The address is returned through addr_ret, its length
261 through len_ret. */
262
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000263static int
264getsockaddrarg(s, args, addr_ret, len_ret)
265 sockobject *s;
266 object *args;
267 struct sockaddr **addr_ret;
268 int *len_ret;
269{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000270 switch (s->sock_family) {
271
272 case AF_UNIX:
273 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000274 static struct sockaddr_un addr;
275 object *path;
276 int len;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000277 if (!getstrarg(args, &path))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000278 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000279 if ((len = getstringsize(path)) > sizeof addr.sun_path) {
280 err_setstr(SocketError, "AF_UNIX path too long");
281 return 0;
282 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000283 addr.sun_family = AF_UNIX;
284 memcpy(addr.sun_path, getstringvalue(path), len);
285 *addr_ret = (struct sockaddr *) &addr;
286 *len_ret = len + sizeof addr.sun_family;
287 return 1;
288 }
289
Guido van Rossum30a685f1991-06-27 15:51:29 +0000290 case AF_INET:
291 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000292 static struct sockaddr_in addr;
293 object *host;
294 int port;
295 if (!getstrintarg(args, &host, &port))
296 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000297 if (setipaddr(getstringvalue(host), &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000298 return 0;
299 addr.sin_family = AF_INET;
300 addr.sin_port = htons(port);
301 *addr_ret = (struct sockaddr *) &addr;
302 *len_ret = sizeof addr;
303 return 1;
304 }
305
Guido van Rossum30a685f1991-06-27 15:51:29 +0000306 /* More cases here... */
307
308 default:
309 err_setstr(SocketError, "getsockaddrarg: bad family");
310 return 0;
311
312 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000313}
314
Guido van Rossum30a685f1991-06-27 15:51:29 +0000315
316/* s.accept() method */
317
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000318static object *
319sock_accept(s, args)
320 sockobject *s;
321 object *args;
322{
323 char addrbuf[256];
324 int addrlen, newfd;
325 object *res;
326 if (!getnoarg(args))
327 return NULL;
328 addrlen = sizeof addrbuf;
329 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
330 if (newfd < 0)
331 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000332 /* Create the new object with unspecified family,
333 to avoid calls to bind() etc. on it. */
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000334 res = makepair((object *) newsockobject(newfd,
335 s->sock_family,
336 s->sock_type,
337 s->sock_proto),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000338 makesockaddr((struct sockaddr *) addrbuf, addrlen));
339 if (res == NULL)
340 close(newfd);
341 return res;
342}
343
Guido van Rossum30a685f1991-06-27 15:51:29 +0000344
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000345/* s.allowbroadcast() method */
346
347static object *
348sock_allowbroadcast(s, args)
349 sockobject *s;
350 object *args;
351{
352 int flag;
353 int res;
354 if (!getintarg(args, &flag))
355 return NULL;
356 res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
357 &flag, sizeof flag);
358 if (res < 0)
359 return socket_error();
360 INCREF(None);
361 return None;
362}
363
364
Guido van Rossum81194471991-07-27 21:42:02 +0000365/* s.avail() method */
366
367static object *
368sock_avail(s, args)
369 sockobject *s;
370 object *args;
371{
372 struct timeval timeout;
373 fd_set readers;
374 int n;
375 timeout.tv_sec = 0;
376 timeout.tv_usec = 0;
377 FD_ZERO(&readers);
378 FD_SET(s->sock_fd, &readers);
379 n = select(s->sock_fd+1, &readers, (fd_set *)0, (fd_set *)0, &timeout);
380 if (n < 0)
381 return socket_error();
382 return newintobject((long) (n != 0));
383}
384
385
Guido van Rossum30a685f1991-06-27 15:51:29 +0000386/* s.bind(sockaddr) method */
387
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000388static object *
389sock_bind(s, args)
390 sockobject *s;
391 object *args;
392{
393 struct sockaddr *addr;
394 int addrlen;
395 if (!getsockaddrarg(s, args, &addr, &addrlen))
396 return NULL;
397 if (bind(s->sock_fd, addr, addrlen) < 0)
398 return socket_error();
399 INCREF(None);
400 return None;
401}
402
Guido van Rossum30a685f1991-06-27 15:51:29 +0000403
404/* s.close() method.
405 Set the file descriptor to -1 so operations tried subsequently
406 will surely fail. */
407
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000408static object *
409sock_close(s, args)
410 sockobject *s;
411 object *args;
412{
413 if (!getnoarg(args))
414 return NULL;
415 (void) close(s->sock_fd);
416 s->sock_fd = -1;
417 INCREF(None);
418 return None;
419}
420
Guido van Rossum30a685f1991-06-27 15:51:29 +0000421
422/* s.connect(sockaddr) method */
423
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000424static object *
425sock_connect(s, args)
426 sockobject *s;
427 object *args;
428{
429 struct sockaddr *addr;
430 int addrlen;
431 if (!getsockaddrarg(s, args, &addr, &addrlen))
432 return NULL;
433 if (connect(s->sock_fd, addr, addrlen) < 0)
434 return socket_error();
435 INCREF(None);
436 return None;
437}
438
Guido van Rossum30a685f1991-06-27 15:51:29 +0000439
440/* s.listen(n) method */
441
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000442static object *
443sock_listen(s, args)
444 sockobject *s;
445 object *args;
446{
447 int backlog;
448 if (!getintarg(args, &backlog))
449 return NULL;
450 if (listen(s->sock_fd, backlog) < 0)
451 return socket_error();
452 INCREF(None);
453 return None;
454}
455
Guido van Rossum30a685f1991-06-27 15:51:29 +0000456
457/* s.makefile(mode) method.
458 Create a new open file object referring to a dupped version of
459 the socket's file descriptor. (The dup() call is necessary so
460 that the open file and socket objects may be closed independent
461 of each other.)
462 The mode argument specifies 'r' or 'w' passed to fdopen(). */
463
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000464static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000465sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000466 sockobject *s;
467 object *args;
468{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000469 extern int fclose PROTO((FILE *));
470 object *mode;
471 int fd;
472 FILE *fp;
473 if (!getstrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000474 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000475 if ((fd = dup(s->sock_fd)) < 0 ||
476 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
477 return socket_error();
478 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
479}
480
481
482/* s.recv(nbytes) method */
483
484static object *
485sock_recv(s, args)
486 sockobject *s;
487 object *args;
488{
489 int len, n, flags;
490 object *buf;
491 if (!getintintarg(args, &len, &flags)) {
492 err_clear();
493 if (!getintarg(args, &len))
494 return NULL;
495 flags = 0;
496 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000497 buf = newsizedstringobject((char *) 0, len);
498 if (buf == NULL)
499 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000500 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000501 if (n < 0)
502 return socket_error();
503 if (resizestring(&buf, n) < 0)
504 return NULL;
505 return buf;
506}
507
Guido van Rossum30a685f1991-06-27 15:51:29 +0000508
509/* s.recvfrom(nbytes) method */
510
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000511static object *
512sock_recvfrom(s, args)
513 sockobject *s;
514 object *args;
515{
516 char addrbuf[256];
517 object *buf;
518 int addrlen, len, n;
519 if (!getintarg(args, &len))
520 return NULL;
521 buf = newsizedstringobject((char *) 0, len);
522 addrlen = sizeof addrbuf;
523 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
524 addrbuf, &addrlen);
525 if (n < 0)
526 return socket_error();
527 if (resizestring(&buf, n) < 0)
528 return NULL;
529 return makepair(buf, makesockaddr(addrbuf, addrlen));
530}
531
Guido van Rossum30a685f1991-06-27 15:51:29 +0000532
533/* s.send(data) method */
534
535static object *
536sock_send(s, args)
537 sockobject *s;
538 object *args;
539{
540 object *buf;
541 int len, n, flags;
542 if (!getstrintarg(args, &buf, &flags)) {
543 err_clear();
544 if (!getstrarg(args, &buf))
545 return NULL;
546 flags = 0;
547 }
548 len = getstringsize(buf);
549 n = send(s->sock_fd, getstringvalue(buf), len, flags);
550 if (n < 0)
551 return socket_error();
552 INCREF(None);
553 return None;
554}
555
556
557/* s.sendto(data, sockaddr) method */
558
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000559static object *
560sock_sendto(s, args)
561 sockobject *s;
562 object *args;
563{
564 object *buf;
565 struct sockaddr *addr;
566 int addrlen, len, n;
567 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
568 err_badarg();
569 return NULL;
570 }
571 if (!getstrarg(gettupleitem(args, 0), &buf) ||
572 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
573 return NULL;
574 len = getstringsize(buf);
575 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
576 addr, addrlen);
577 if (n < 0)
578 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000579 INCREF(None);
580 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000581}
582
Guido van Rossum30a685f1991-06-27 15:51:29 +0000583
584/* s.shutdown(how) method */
585
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000586static object *
587sock_shutdown(s, args)
588 sockobject *s;
589 object *args;
590{
591 int how;
592 if (!getintarg(args, &how))
593 return NULL;
594 if (shutdown(s->sock_fd, how) < 0)
595 return socket_error();
596 INCREF(None);
597 return None;
598}
599
Guido van Rossum30a685f1991-06-27 15:51:29 +0000600
601/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000602
603static struct methodlist sock_methods[] = {
604 {"accept", sock_accept},
Guido van Rossum81194471991-07-27 21:42:02 +0000605 {"avail", sock_avail},
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000606 {"allowbroadcast", sock_allowbroadcast},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000607 {"bind", sock_bind},
608 {"close", sock_close},
609 {"connect", sock_connect},
610 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000611 {"makefile", sock_makefile},
612 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000613 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000614 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000615 {"sendto", sock_sendto},
616 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000617 {NULL, NULL} /* sentinel */
618};
619
Guido van Rossum30a685f1991-06-27 15:51:29 +0000620
621/* Deallocate a socket object in response to the last DECREF().
622 First close the file description. */
623
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000624static void
625sock_dealloc(s)
626 sockobject *s;
627{
628 (void) close(s->sock_fd);
629 DEL(s);
630}
631
Guido van Rossum30a685f1991-06-27 15:51:29 +0000632
633/* Return a socket object's named attribute. */
634
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000635static object *
636sock_getattr(s, name)
637 sockobject *s;
638 char *name;
639{
640 return findmethod(sock_methods, (object *) s, name);
641}
642
Guido van Rossum30a685f1991-06-27 15:51:29 +0000643
644/* Type object for socket objects.
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000645 XXX This should be static, but some compilers don't grok the
646 XXX forward reference to it in that case... */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000647
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000648typeobject Socktype = {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000649 OB_HEAD_INIT(&Typetype)
650 0,
651 "socket",
652 sizeof(sockobject),
653 0,
654 sock_dealloc, /*tp_dealloc*/
655 0, /*tp_print*/
656 sock_getattr, /*tp_getattr*/
657 0, /*tp_setattr*/
658 0, /*tp_compare*/
659 0, /*tp_repr*/
660 0, /*tp_as_number*/
661 0, /*tp_as_sequence*/
662 0, /*tp_as_mapping*/
663};
664
Guido van Rossum30a685f1991-06-27 15:51:29 +0000665
Guido van Rossum81194471991-07-27 21:42:02 +0000666/* Python interface to gethostname(). */
667
668/*ARGSUSED*/
669static object *
670socket_gethostname(self, args)
671 object *self;
672 object *args;
673{
674 char buf[1024];
675 if (!getnoarg(args))
676 return NULL;
677 if (gethostname(buf, sizeof buf - 1) < 0)
678 return socket_error();
679 buf[sizeof buf - 1] = '\0';
680 return newstringobject(buf);
681}
Guido van Rossum30a685f1991-06-27 15:51:29 +0000682/* Python interface to gethostbyname(name). */
683
684/*ARGSUSED*/
685static object *
686socket_gethostbyname(self, args)
687 object *self;
688 object *args;
689{
690 object *name;
691 struct hostent *hp;
692 struct sockaddr_in addrbuf;
693 if (!getstrarg(args, &name))
694 return NULL;
695 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
696 return NULL;
697 return makeipaddr(&addrbuf);
698}
699
700
701/* Python interface to getservbyname(name).
702 This only returns the port number, since the other info is already
703 known or not useful (like the list of aliases). */
704
705/*ARGSUSED*/
706static object *
707socket_getservbyname(self, args)
708 object *self;
709 object *args;
710{
711 object *name, *proto;
712 struct servent *sp;
713 if (!getstrstrarg(args, &name, &proto))
714 return NULL;
715 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
716 if (sp == NULL) {
717 err_setstr(SocketError, "service/proto not found");
718 return NULL;
719 }
720 return newintobject((long) ntohs(sp->s_port));
721}
722
723
724/* Python interface to socket(family, type, proto).
725 The third (protocol) argument is optional.
726 Return a new socket object. */
727
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000728/*ARGSUSED*/
729static object *
730socket_socket(self, args)
731 object *self;
732 object *args;
733{
734 sockobject *s;
735 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000736 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000737 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000738 return NULL;
739 }
740 else {
741 if (!getintintarg(args, &family, &type))
742 return NULL;
743 proto = 0;
744 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000745 fd = socket(family, type, proto);
746 if (fd < 0)
747 return socket_error();
748 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000749 /* If the object can't be created, don't forget to close the
750 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000751 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000752 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000753 /* From now on, ignore SIGPIPE and let the error checking
754 do the work. */
755 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000756 return (object *) s;
757}
758
Guido van Rossum30a685f1991-06-27 15:51:29 +0000759
760/* List of functions exported by this module. */
761
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000762static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000763 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +0000764 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000765 {"getservbyname", socket_getservbyname},
766 {"socket", socket_socket},
767 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000768};
769
Guido van Rossum30a685f1991-06-27 15:51:29 +0000770
771/* Convenience routine to export an integer value.
772 For simplicity, errors (which are unlikely anyway) are ignored. */
773
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000774static void
775insint(d, name, value)
776 object *d;
777 char *name;
778 int value;
779{
780 object *v = newintobject((long) value);
781 if (v == NULL) {
782 /* Don't bother reporting this error */
783 err_clear();
784 }
785 else {
786 dictinsert(d, name, v);
787 DECREF(v);
788 }
789}
790
Guido van Rossum30a685f1991-06-27 15:51:29 +0000791
792/* Initialize this module.
793 This is called when the first 'import socket' is done,
794 via a table in config.c, if config.c is compiled with USE_SOCKET
795 defined. */
796
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000797void
798initsocket()
799{
800 object *m, *d;
801
802 m = initmodule("socket", socket_methods);
803 d = getmoduledict(m);
804 SocketError = newstringobject("socket.error");
805 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
806 fatal("can't define socket.error");
807 insint(d, "AF_INET", AF_INET);
808 insint(d, "AF_UNIX", AF_UNIX);
809 insint(d, "SOCK_STREAM", SOCK_STREAM);
810 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
811 insint(d, "SOCK_RAW", SOCK_RAW);
812 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
813 insint(d, "SOCK_RDM", SOCK_RDM);
814}