blob: de38d6dbc1624ad4bef136e8d9e82e5e5a2d5f9c [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 */
Guido van Rossum0bb1a511991-11-27 14:55:18 +000081/* AIX defines fd_set in a separate file. Sigh... */
82#include <sys/select.h>
Guido van Rossum81194471991-07-27 21:42:02 +000083#endif
Guido van Rossum6574b3e1991-06-25 21:36:08 +000084
Guido van Rossum30a685f1991-06-27 15:51:29 +000085
86/* Global variable holding the exception type for errors detected
87 by this module (but not argument type or memory errors, etc.). */
88
89static object *SocketError;
90
91
92/* Convenience function to raise an error according to errno
93 and return a NULL pointer from a function. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000094
95static object *
96socket_error()
97{
98 return err_errno(SocketError);
99}
100
Guido van Rossum30a685f1991-06-27 15:51:29 +0000101
102/* The object holding a socket. It holds some extra information,
103 like the address family, which is used to decode socket address
104 arguments properly. */
105
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000106typedef struct {
107 OB_HEAD
Guido van Rossum30a685f1991-06-27 15:51:29 +0000108 int sock_fd; /* Socket file descriptor */
109 int sock_family; /* Address family, e.g., AF_INET */
110 int sock_type; /* Socket type, e.g., SOCK_STREAM */
111 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000112} sockobject;
113
Guido van Rossum30a685f1991-06-27 15:51:29 +0000114
115/* A forward reference to the Socktype type object.
116 The Socktype variable contains pointers to various functions,
117 some of which call newsocobject(), which uses Socktype, so
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000118 there has to be a circular reference. */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000119
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000120extern typeobject Socktype; /* Forward */
121
Guido van Rossum30a685f1991-06-27 15:51:29 +0000122
123/* Create a new socket object.
124 This just creates the object and initializes it.
125 If the creation fails, return NULL and set an exception (implicit
126 in NEWOBJ()). */
127
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000128static sockobject *
129newsockobject(fd, family, type, proto)
130 int fd, family, type, proto;
131{
132 sockobject *s;
133 s = NEWOBJ(sockobject, &Socktype);
134 if (s != NULL) {
135 s->sock_fd = fd;
136 s->sock_family = family;
137 s->sock_type = type;
138 s->sock_proto = proto;
139 }
140 return s;
141}
142
Guido van Rossum30a685f1991-06-27 15:51:29 +0000143
144/* Convert a string specifying a host name or one of a few symbolic
145 names to a numeric IP address. This usually calls gethostbyname()
146 to do the work; the names "" and "<broadcast>" are special.
147 Return the length (should always be 4 bytes), or negative if
148 an error occurred; then an exception is raised. */
149
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000150static int
Guido van Rossum30a685f1991-06-27 15:51:29 +0000151setipaddr(name, addr_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000152 char *name;
153 struct sockaddr_in *addr_ret;
154{
155 struct hostent *hp;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000156 int d1, d2, d3, d4;
157 char ch;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000158
Guido van Rossum30a685f1991-06-27 15:51:29 +0000159 if (name[0] == '\0') {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000160 addr_ret->sin_addr.s_addr = INADDR_ANY;
161 return 4;
162 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000163 if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000164 addr_ret->sin_addr.s_addr = INADDR_BROADCAST;
165 return 4;
166 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000167 if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
168 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
169 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
170 addr_ret->sin_addr.s_addr = htonl(
171 ((long) d1 << 24) | ((long) d2 << 16) |
172 ((long) d3 << 8) | ((long) d4 << 0));
173 return 4;
174 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000175 hp = gethostbyname(name);
176 if (hp == NULL) {
177 err_setstr(SocketError, "host not found");
178 return -1;
179 }
180 memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
181 return hp->h_length;
182}
183
Guido van Rossum30a685f1991-06-27 15:51:29 +0000184
185/* Generally useful convenience function to create a tuple from two
186 objects. This eats references to the objects; if either is NULL
187 it destroys the other and returns NULL without raising an exception
188 (assuming the function that was called to create the argument must
189 have raised an exception and returned NULL). */
190
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000191static object *
192makepair(a, b)
193 object *a, *b;
194{
195 object *pair = NULL;
196 if (a == NULL || b == NULL || (pair = newtupleobject(2)) == NULL) {
197 XDECREF(a);
198 XDECREF(b);
199 return NULL;
200 }
201 settupleitem(pair, 0, a);
202 settupleitem(pair, 1, b);
203 return pair;
204}
205
Guido van Rossum30a685f1991-06-27 15:51:29 +0000206
207/* Create a string object representing an IP address.
208 This is always a string of the form 'dd.dd.dd.dd' (with variable
209 size numbers). */
210
211static object *
212makeipaddr(addr)
213 struct sockaddr_in *addr;
214{
215 long x = ntohl(addr->sin_addr.s_addr);
216 char buf[100];
217 sprintf(buf, "%d.%d.%d.%d",
218 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
219 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
220 return newstringobject(buf);
221}
222
223
224/* Create an object representing the given socket address,
225 suitable for passing it back to bind(), connect() etc.
226 The family field of the sockaddr structure is inspected
227 to determine what kind of address it really is. */
228
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000229/*ARGSUSED*/
230static object *
231makesockaddr(addr, addrlen)
232 struct sockaddr *addr;
233 int addrlen;
234{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000235 switch (addr->sa_family) {
236
237 case AF_INET:
238 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000239 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000240 return makepair(makeipaddr(a),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000241 newintobject((long) ntohs(a->sin_port)));
242 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000243
244 case AF_UNIX:
245 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000246 struct sockaddr_un *a = (struct sockaddr_un *) addr;
247 return newstringobject(a->sun_path);
248 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000249
250 /* More cases here... */
251
252 default:
253 err_setstr(SocketError, "return unknown socket address type");
254 return NULL;
255 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000256}
257
Guido van Rossum30a685f1991-06-27 15:51:29 +0000258
259/* Parse a socket address argument according to the socket object's
260 address family. Return 1 if the address was in the proper format,
261 0 of not. The address is returned through addr_ret, its length
262 through len_ret. */
263
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000264static int
265getsockaddrarg(s, args, addr_ret, len_ret)
266 sockobject *s;
267 object *args;
268 struct sockaddr **addr_ret;
269 int *len_ret;
270{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000271 switch (s->sock_family) {
272
273 case AF_UNIX:
274 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000275 static struct sockaddr_un addr;
276 object *path;
277 int len;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000278 if (!getstrarg(args, &path))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000279 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000280 if ((len = getstringsize(path)) > sizeof addr.sun_path) {
281 err_setstr(SocketError, "AF_UNIX path too long");
282 return 0;
283 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000284 addr.sun_family = AF_UNIX;
285 memcpy(addr.sun_path, getstringvalue(path), len);
286 *addr_ret = (struct sockaddr *) &addr;
287 *len_ret = len + sizeof addr.sun_family;
288 return 1;
289 }
290
Guido van Rossum30a685f1991-06-27 15:51:29 +0000291 case AF_INET:
292 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000293 static struct sockaddr_in addr;
294 object *host;
295 int port;
296 if (!getstrintarg(args, &host, &port))
297 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000298 if (setipaddr(getstringvalue(host), &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000299 return 0;
300 addr.sin_family = AF_INET;
301 addr.sin_port = htons(port);
302 *addr_ret = (struct sockaddr *) &addr;
303 *len_ret = sizeof addr;
304 return 1;
305 }
306
Guido van Rossum30a685f1991-06-27 15:51:29 +0000307 /* More cases here... */
308
309 default:
310 err_setstr(SocketError, "getsockaddrarg: bad family");
311 return 0;
312
313 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000314}
315
Guido van Rossum30a685f1991-06-27 15:51:29 +0000316
317/* s.accept() method */
318
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000319static object *
320sock_accept(s, args)
321 sockobject *s;
322 object *args;
323{
324 char addrbuf[256];
325 int addrlen, newfd;
326 object *res;
327 if (!getnoarg(args))
328 return NULL;
329 addrlen = sizeof addrbuf;
330 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
331 if (newfd < 0)
332 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000333 /* Create the new object with unspecified family,
334 to avoid calls to bind() etc. on it. */
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000335 res = makepair((object *) newsockobject(newfd,
336 s->sock_family,
337 s->sock_type,
338 s->sock_proto),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000339 makesockaddr((struct sockaddr *) addrbuf, addrlen));
340 if (res == NULL)
341 close(newfd);
342 return res;
343}
344
Guido van Rossum30a685f1991-06-27 15:51:29 +0000345
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000346/* s.allowbroadcast() method */
347
348static object *
349sock_allowbroadcast(s, args)
350 sockobject *s;
351 object *args;
352{
353 int flag;
354 int res;
355 if (!getintarg(args, &flag))
356 return NULL;
357 res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
358 &flag, sizeof flag);
359 if (res < 0)
360 return socket_error();
361 INCREF(None);
362 return None;
363}
364
365
Guido van Rossum81194471991-07-27 21:42:02 +0000366/* s.avail() method */
367
368static object *
369sock_avail(s, args)
370 sockobject *s;
371 object *args;
372{
373 struct timeval timeout;
374 fd_set readers;
375 int n;
376 timeout.tv_sec = 0;
377 timeout.tv_usec = 0;
378 FD_ZERO(&readers);
379 FD_SET(s->sock_fd, &readers);
380 n = select(s->sock_fd+1, &readers, (fd_set *)0, (fd_set *)0, &timeout);
381 if (n < 0)
382 return socket_error();
383 return newintobject((long) (n != 0));
384}
385
386
Guido van Rossum30a685f1991-06-27 15:51:29 +0000387/* s.bind(sockaddr) method */
388
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000389static object *
390sock_bind(s, args)
391 sockobject *s;
392 object *args;
393{
394 struct sockaddr *addr;
395 int addrlen;
396 if (!getsockaddrarg(s, args, &addr, &addrlen))
397 return NULL;
398 if (bind(s->sock_fd, addr, addrlen) < 0)
399 return socket_error();
400 INCREF(None);
401 return None;
402}
403
Guido van Rossum30a685f1991-06-27 15:51:29 +0000404
405/* s.close() method.
406 Set the file descriptor to -1 so operations tried subsequently
407 will surely fail. */
408
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000409static object *
410sock_close(s, args)
411 sockobject *s;
412 object *args;
413{
414 if (!getnoarg(args))
415 return NULL;
416 (void) close(s->sock_fd);
417 s->sock_fd = -1;
418 INCREF(None);
419 return None;
420}
421
Guido van Rossum30a685f1991-06-27 15:51:29 +0000422
423/* s.connect(sockaddr) method */
424
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000425static object *
426sock_connect(s, args)
427 sockobject *s;
428 object *args;
429{
430 struct sockaddr *addr;
431 int addrlen;
432 if (!getsockaddrarg(s, args, &addr, &addrlen))
433 return NULL;
434 if (connect(s->sock_fd, addr, addrlen) < 0)
435 return socket_error();
436 INCREF(None);
437 return None;
438}
439
Guido van Rossum30a685f1991-06-27 15:51:29 +0000440
441/* s.listen(n) method */
442
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000443static object *
444sock_listen(s, args)
445 sockobject *s;
446 object *args;
447{
448 int backlog;
449 if (!getintarg(args, &backlog))
450 return NULL;
451 if (listen(s->sock_fd, backlog) < 0)
452 return socket_error();
453 INCREF(None);
454 return None;
455}
456
Guido van Rossum30a685f1991-06-27 15:51:29 +0000457
458/* s.makefile(mode) method.
459 Create a new open file object referring to a dupped version of
460 the socket's file descriptor. (The dup() call is necessary so
461 that the open file and socket objects may be closed independent
462 of each other.)
463 The mode argument specifies 'r' or 'w' passed to fdopen(). */
464
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000465static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000466sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000467 sockobject *s;
468 object *args;
469{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000470 extern int fclose PROTO((FILE *));
471 object *mode;
472 int fd;
473 FILE *fp;
474 if (!getstrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000475 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000476 if ((fd = dup(s->sock_fd)) < 0 ||
477 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
478 return socket_error();
479 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
480}
481
482
483/* s.recv(nbytes) method */
484
485static object *
486sock_recv(s, args)
487 sockobject *s;
488 object *args;
489{
490 int len, n, flags;
491 object *buf;
492 if (!getintintarg(args, &len, &flags)) {
493 err_clear();
494 if (!getintarg(args, &len))
495 return NULL;
496 flags = 0;
497 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000498 buf = newsizedstringobject((char *) 0, len);
499 if (buf == NULL)
500 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000501 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000502 if (n < 0)
503 return socket_error();
504 if (resizestring(&buf, n) < 0)
505 return NULL;
506 return buf;
507}
508
Guido van Rossum30a685f1991-06-27 15:51:29 +0000509
510/* s.recvfrom(nbytes) method */
511
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000512static object *
513sock_recvfrom(s, args)
514 sockobject *s;
515 object *args;
516{
517 char addrbuf[256];
518 object *buf;
519 int addrlen, len, n;
520 if (!getintarg(args, &len))
521 return NULL;
522 buf = newsizedstringobject((char *) 0, len);
523 addrlen = sizeof addrbuf;
524 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
525 addrbuf, &addrlen);
526 if (n < 0)
527 return socket_error();
528 if (resizestring(&buf, n) < 0)
529 return NULL;
530 return makepair(buf, makesockaddr(addrbuf, addrlen));
531}
532
Guido van Rossum30a685f1991-06-27 15:51:29 +0000533
534/* s.send(data) method */
535
536static object *
537sock_send(s, args)
538 sockobject *s;
539 object *args;
540{
541 object *buf;
542 int len, n, flags;
543 if (!getstrintarg(args, &buf, &flags)) {
544 err_clear();
545 if (!getstrarg(args, &buf))
546 return NULL;
547 flags = 0;
548 }
549 len = getstringsize(buf);
550 n = send(s->sock_fd, getstringvalue(buf), len, flags);
551 if (n < 0)
552 return socket_error();
553 INCREF(None);
554 return None;
555}
556
557
558/* s.sendto(data, sockaddr) method */
559
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000560static object *
561sock_sendto(s, args)
562 sockobject *s;
563 object *args;
564{
565 object *buf;
566 struct sockaddr *addr;
567 int addrlen, len, n;
568 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
569 err_badarg();
570 return NULL;
571 }
572 if (!getstrarg(gettupleitem(args, 0), &buf) ||
573 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
574 return NULL;
575 len = getstringsize(buf);
576 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
577 addr, addrlen);
578 if (n < 0)
579 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000580 INCREF(None);
581 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000582}
583
Guido van Rossum30a685f1991-06-27 15:51:29 +0000584
585/* s.shutdown(how) method */
586
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000587static object *
588sock_shutdown(s, args)
589 sockobject *s;
590 object *args;
591{
592 int how;
593 if (!getintarg(args, &how))
594 return NULL;
595 if (shutdown(s->sock_fd, how) < 0)
596 return socket_error();
597 INCREF(None);
598 return None;
599}
600
Guido van Rossum30a685f1991-06-27 15:51:29 +0000601
602/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000603
604static struct methodlist sock_methods[] = {
605 {"accept", sock_accept},
Guido van Rossum81194471991-07-27 21:42:02 +0000606 {"avail", sock_avail},
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000607 {"allowbroadcast", sock_allowbroadcast},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000608 {"bind", sock_bind},
609 {"close", sock_close},
610 {"connect", sock_connect},
611 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000612 {"makefile", sock_makefile},
613 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000614 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000615 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000616 {"sendto", sock_sendto},
617 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000618 {NULL, NULL} /* sentinel */
619};
620
Guido van Rossum30a685f1991-06-27 15:51:29 +0000621
622/* Deallocate a socket object in response to the last DECREF().
623 First close the file description. */
624
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000625static void
626sock_dealloc(s)
627 sockobject *s;
628{
629 (void) close(s->sock_fd);
630 DEL(s);
631}
632
Guido van Rossum30a685f1991-06-27 15:51:29 +0000633
634/* Return a socket object's named attribute. */
635
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000636static object *
637sock_getattr(s, name)
638 sockobject *s;
639 char *name;
640{
641 return findmethod(sock_methods, (object *) s, name);
642}
643
Guido van Rossum30a685f1991-06-27 15:51:29 +0000644
645/* Type object for socket objects.
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000646 XXX This should be static, but some compilers don't grok the
647 XXX forward reference to it in that case... */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000648
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000649typeobject Socktype = {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000650 OB_HEAD_INIT(&Typetype)
651 0,
652 "socket",
653 sizeof(sockobject),
654 0,
655 sock_dealloc, /*tp_dealloc*/
656 0, /*tp_print*/
657 sock_getattr, /*tp_getattr*/
658 0, /*tp_setattr*/
659 0, /*tp_compare*/
660 0, /*tp_repr*/
661 0, /*tp_as_number*/
662 0, /*tp_as_sequence*/
663 0, /*tp_as_mapping*/
664};
665
Guido van Rossum30a685f1991-06-27 15:51:29 +0000666
Guido van Rossum81194471991-07-27 21:42:02 +0000667/* Python interface to gethostname(). */
668
669/*ARGSUSED*/
670static object *
671socket_gethostname(self, args)
672 object *self;
673 object *args;
674{
675 char buf[1024];
676 if (!getnoarg(args))
677 return NULL;
678 if (gethostname(buf, sizeof buf - 1) < 0)
679 return socket_error();
680 buf[sizeof buf - 1] = '\0';
681 return newstringobject(buf);
682}
Guido van Rossum30a685f1991-06-27 15:51:29 +0000683/* Python interface to gethostbyname(name). */
684
685/*ARGSUSED*/
686static object *
687socket_gethostbyname(self, args)
688 object *self;
689 object *args;
690{
691 object *name;
692 struct hostent *hp;
693 struct sockaddr_in addrbuf;
694 if (!getstrarg(args, &name))
695 return NULL;
696 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
697 return NULL;
698 return makeipaddr(&addrbuf);
699}
700
701
702/* Python interface to getservbyname(name).
703 This only returns the port number, since the other info is already
704 known or not useful (like the list of aliases). */
705
706/*ARGSUSED*/
707static object *
708socket_getservbyname(self, args)
709 object *self;
710 object *args;
711{
712 object *name, *proto;
713 struct servent *sp;
714 if (!getstrstrarg(args, &name, &proto))
715 return NULL;
716 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
717 if (sp == NULL) {
718 err_setstr(SocketError, "service/proto not found");
719 return NULL;
720 }
721 return newintobject((long) ntohs(sp->s_port));
722}
723
724
725/* Python interface to socket(family, type, proto).
726 The third (protocol) argument is optional.
727 Return a new socket object. */
728
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000729/*ARGSUSED*/
730static object *
731socket_socket(self, args)
732 object *self;
733 object *args;
734{
735 sockobject *s;
736 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000737 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000738 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000739 return NULL;
740 }
741 else {
742 if (!getintintarg(args, &family, &type))
743 return NULL;
744 proto = 0;
745 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000746 fd = socket(family, type, proto);
747 if (fd < 0)
748 return socket_error();
749 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000750 /* If the object can't be created, don't forget to close the
751 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000752 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000753 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000754 /* From now on, ignore SIGPIPE and let the error checking
755 do the work. */
756 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000757 return (object *) s;
758}
759
Guido van Rossum30a685f1991-06-27 15:51:29 +0000760
761/* List of functions exported by this module. */
762
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000763static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000764 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +0000765 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000766 {"getservbyname", socket_getservbyname},
767 {"socket", socket_socket},
768 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000769};
770
Guido van Rossum30a685f1991-06-27 15:51:29 +0000771
772/* Convenience routine to export an integer value.
773 For simplicity, errors (which are unlikely anyway) are ignored. */
774
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000775static void
776insint(d, name, value)
777 object *d;
778 char *name;
779 int value;
780{
781 object *v = newintobject((long) value);
782 if (v == NULL) {
783 /* Don't bother reporting this error */
784 err_clear();
785 }
786 else {
787 dictinsert(d, name, v);
788 DECREF(v);
789 }
790}
791
Guido van Rossum30a685f1991-06-27 15:51:29 +0000792
793/* Initialize this module.
794 This is called when the first 'import socket' is done,
795 via a table in config.c, if config.c is compiled with USE_SOCKET
796 defined. */
797
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000798void
799initsocket()
800{
801 object *m, *d;
802
803 m = initmodule("socket", socket_methods);
804 d = getmoduledict(m);
805 SocketError = newstringobject("socket.error");
806 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
807 fatal("can't define socket.error");
808 insint(d, "AF_INET", AF_INET);
809 insint(d, "AF_UNIX", AF_UNIX);
810 insint(d, "SOCK_STREAM", SOCK_STREAM);
811 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
812 insint(d, "SOCK_RAW", SOCK_RAW);
813 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
814 insint(d, "SOCK_RDM", SOCK_RDM);
815}