blob: 839d46e5a348fe7b467f762a4e534e2068531e49 [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 Rossumed233a51992-06-23 09:07:03 +000076#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
77
Guido van Rossum81194471991-07-27 21:42:02 +000078#include <signal.h>
Guido van Rossum6574b3e1991-06-25 21:36:08 +000079#include <sys/socket.h>
80#include <netinet/in.h>
81#include <sys/un.h>
82#include <netdb.h>
83
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
Guido van Rossum30a685f1991-06-27 15:51:29 +0000184/* Create a string object representing an IP address.
185 This is always a string of the form 'dd.dd.dd.dd' (with variable
186 size numbers). */
187
188static object *
189makeipaddr(addr)
190 struct sockaddr_in *addr;
191{
192 long x = ntohl(addr->sin_addr.s_addr);
193 char buf[100];
194 sprintf(buf, "%d.%d.%d.%d",
195 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
196 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
197 return newstringobject(buf);
198}
199
200
201/* Create an object representing the given socket address,
202 suitable for passing it back to bind(), connect() etc.
203 The family field of the sockaddr structure is inspected
204 to determine what kind of address it really is. */
205
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000206/*ARGSUSED*/
207static object *
208makesockaddr(addr, addrlen)
209 struct sockaddr *addr;
210 int addrlen;
211{
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000212 if (addrlen == 0) {
213 /* No address -- may be recvfrom() from known socket */
214 INCREF(None);
215 return None;
216 }
217
Guido van Rossum30a685f1991-06-27 15:51:29 +0000218 switch (addr->sa_family) {
219
220 case AF_INET:
221 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000222 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000223 return mkvalue("Oi", makeipaddr(a), ntohs(a->sin_port));
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000224 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000225
226 case AF_UNIX:
227 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000228 struct sockaddr_un *a = (struct sockaddr_un *) addr;
229 return newstringobject(a->sun_path);
230 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000231
232 /* More cases here... */
233
234 default:
235 err_setstr(SocketError, "return unknown socket address type");
236 return NULL;
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000237
Guido van Rossum30a685f1991-06-27 15:51:29 +0000238 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000239}
240
Guido van Rossum30a685f1991-06-27 15:51:29 +0000241
242/* Parse a socket address argument according to the socket object's
243 address family. Return 1 if the address was in the proper format,
244 0 of not. The address is returned through addr_ret, its length
245 through len_ret. */
246
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000247static int
248getsockaddrarg(s, args, addr_ret, len_ret)
249 sockobject *s;
250 object *args;
251 struct sockaddr **addr_ret;
252 int *len_ret;
253{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000254 switch (s->sock_family) {
255
256 case AF_UNIX:
257 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000258 static struct sockaddr_un addr;
259 object *path;
260 int len;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000261 if (!getStrarg(args, &path))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000262 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000263 if ((len = getstringsize(path)) > sizeof addr.sun_path) {
264 err_setstr(SocketError, "AF_UNIX path too long");
265 return 0;
266 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000267 addr.sun_family = AF_UNIX;
268 memcpy(addr.sun_path, getstringvalue(path), len);
269 *addr_ret = (struct sockaddr *) &addr;
270 *len_ret = len + sizeof addr.sun_family;
271 return 1;
272 }
273
Guido van Rossum30a685f1991-06-27 15:51:29 +0000274 case AF_INET:
275 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000276 static struct sockaddr_in addr;
277 object *host;
278 int port;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000279 if (!getStrintarg(args, &host, &port))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000280 return 0;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000281 if (setipaddr(getstringvalue(host), &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000282 return 0;
283 addr.sin_family = AF_INET;
284 addr.sin_port = htons(port);
285 *addr_ret = (struct sockaddr *) &addr;
286 *len_ret = sizeof addr;
287 return 1;
288 }
289
Guido van Rossum30a685f1991-06-27 15:51:29 +0000290 /* More cases here... */
291
292 default:
293 err_setstr(SocketError, "getsockaddrarg: bad family");
294 return 0;
295
296 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000297}
298
Guido van Rossum30a685f1991-06-27 15:51:29 +0000299
Guido van Rossum710e1df1992-06-12 10:39:36 +0000300/* Get the address length according to the socket object's address family.
301 Return 1 if the family is known, 0 otherwise. The length is returned
302 through len_ret. */
303
304static int
305getsockaddrlen(s, len_ret)
306 sockobject *s;
307 int *len_ret;
308{
309 switch (s->sock_family) {
310
311 case AF_UNIX:
312 {
313 *len_ret = sizeof (struct sockaddr_un);
314 return 1;
315 }
316
317 case AF_INET:
318 {
319 *len_ret = sizeof (struct sockaddr_in);
320 return 1;
321 }
322
323 /* More cases here... */
324
325 default:
326 err_setstr(SocketError, "getsockaddrarg: bad family");
327 return 0;
328
329 }
330}
331
332
Guido van Rossum30a685f1991-06-27 15:51:29 +0000333/* s.accept() method */
334
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000335static object *
336sock_accept(s, args)
337 sockobject *s;
338 object *args;
339{
340 char addrbuf[256];
341 int addrlen, newfd;
342 object *res;
343 if (!getnoarg(args))
344 return NULL;
Guido van Rossum710e1df1992-06-12 10:39:36 +0000345 if (!getsockaddrlen(s, &addrlen))
346 return NULL;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000347 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
348 if (newfd < 0)
349 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000350 /* Create the new object with unspecified family,
351 to avoid calls to bind() etc. on it. */
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000352 res = mkvalue("OO", (object *) newsockobject(newfd,
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000353 s->sock_family,
354 s->sock_type,
355 s->sock_proto),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000356 makesockaddr((struct sockaddr *) addrbuf, addrlen));
357 if (res == NULL)
358 close(newfd);
359 return res;
360}
361
Guido van Rossum30a685f1991-06-27 15:51:29 +0000362
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000363/* s.allowbroadcast() method */
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000364/* XXX obsolete -- will disappear in next release */
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000365
366static object *
367sock_allowbroadcast(s, args)
368 sockobject *s;
369 object *args;
370{
371 int flag;
372 int res;
373 if (!getintarg(args, &flag))
374 return NULL;
375 res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
376 &flag, sizeof flag);
377 if (res < 0)
378 return socket_error();
379 INCREF(None);
380 return None;
381}
382
383
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000384/* s.setsockopt() method */
385/* XXX this works for integer flags only */
386
387static object *
388sock_setsockopt(s, args)
389 sockobject *s;
390 object *args;
391{
392 int level;
393 int optname;
394 int flag;
395 int res;
396
397 if (!getargs(args, "(iii)", &level, &optname, &flag))
398 return NULL;
399 res = setsockopt(s->sock_fd, level, optname, &flag, sizeof flag);
400 if (res < 0)
401 return socket_error();
402 INCREF(None);
403 return None;
404}
405
406
407/* s.getsockopt() method */
408/* XXX this works for integer flags only */
409
410static object *
411sock_getsockopt(s, args)
412 sockobject *s;
413 object *args;
414{
415 int level;
416 int optname;
417 int flag;
418 int flagsize;
419 int res;
420
421 if (!getargs(args, "(ii)", &level, &optname))
422 return NULL;
423 flagsize = sizeof flag;
424 flag = 0;
425 res = getsockopt(s->sock_fd, level, optname, &flag, &flagsize);
426 if (res < 0)
427 return socket_error();
428 return newintobject(flag);
429}
430
431
Guido van Rossum81194471991-07-27 21:42:02 +0000432/* s.avail() method */
433
434static object *
435sock_avail(s, args)
436 sockobject *s;
437 object *args;
438{
439 struct timeval timeout;
440 fd_set readers;
441 int n;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000442 if (!getnoarg(args))
443 return NULL;
Guido van Rossum81194471991-07-27 21:42:02 +0000444 timeout.tv_sec = 0;
445 timeout.tv_usec = 0;
446 FD_ZERO(&readers);
447 FD_SET(s->sock_fd, &readers);
448 n = select(s->sock_fd+1, &readers, (fd_set *)0, (fd_set *)0, &timeout);
449 if (n < 0)
450 return socket_error();
451 return newintobject((long) (n != 0));
452}
453
454
Guido van Rossum30a685f1991-06-27 15:51:29 +0000455/* s.bind(sockaddr) method */
456
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000457static object *
458sock_bind(s, args)
459 sockobject *s;
460 object *args;
461{
462 struct sockaddr *addr;
463 int addrlen;
464 if (!getsockaddrarg(s, args, &addr, &addrlen))
465 return NULL;
466 if (bind(s->sock_fd, addr, addrlen) < 0)
467 return socket_error();
468 INCREF(None);
469 return None;
470}
471
Guido van Rossum30a685f1991-06-27 15:51:29 +0000472
473/* s.close() method.
474 Set the file descriptor to -1 so operations tried subsequently
475 will surely fail. */
476
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000477static object *
478sock_close(s, args)
479 sockobject *s;
480 object *args;
481{
482 if (!getnoarg(args))
483 return NULL;
484 (void) close(s->sock_fd);
485 s->sock_fd = -1;
486 INCREF(None);
487 return None;
488}
489
Guido van Rossum30a685f1991-06-27 15:51:29 +0000490
491/* s.connect(sockaddr) method */
492
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000493static object *
494sock_connect(s, args)
495 sockobject *s;
496 object *args;
497{
498 struct sockaddr *addr;
499 int addrlen;
500 if (!getsockaddrarg(s, args, &addr, &addrlen))
501 return NULL;
502 if (connect(s->sock_fd, addr, addrlen) < 0)
503 return socket_error();
504 INCREF(None);
505 return None;
506}
507
Guido van Rossum30a685f1991-06-27 15:51:29 +0000508
Guido van Rossumed233a51992-06-23 09:07:03 +0000509/* s.fileno() method */
510
511static object *
512sock_fileno(s, args)
513 sockobject *s;
514 object *args;
515{
516 if (!getnoarg(args))
517 return NULL;
518 return newintobject((long) s->sock_fd);
519}
520
521
Guido van Rossum30a685f1991-06-27 15:51:29 +0000522/* s.listen(n) method */
523
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000524static object *
525sock_listen(s, args)
526 sockobject *s;
527 object *args;
528{
529 int backlog;
530 if (!getintarg(args, &backlog))
531 return NULL;
532 if (listen(s->sock_fd, backlog) < 0)
533 return socket_error();
534 INCREF(None);
535 return None;
536}
537
Guido van Rossum30a685f1991-06-27 15:51:29 +0000538
539/* s.makefile(mode) method.
540 Create a new open file object referring to a dupped version of
541 the socket's file descriptor. (The dup() call is necessary so
542 that the open file and socket objects may be closed independent
543 of each other.)
544 The mode argument specifies 'r' or 'w' passed to fdopen(). */
545
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000546static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000547sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000548 sockobject *s;
549 object *args;
550{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000551 extern int fclose PROTO((FILE *));
552 object *mode;
553 int fd;
554 FILE *fp;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000555 if (!getStrarg(args, &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000556 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000557 if ((fd = dup(s->sock_fd)) < 0 ||
558 (fp = fdopen(fd, getstringvalue(mode))) == NULL)
559 return socket_error();
560 return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
561}
562
563
564/* s.recv(nbytes) method */
565
566static object *
567sock_recv(s, args)
568 sockobject *s;
569 object *args;
570{
571 int len, n, flags;
572 object *buf;
573 if (!getintintarg(args, &len, &flags)) {
574 err_clear();
575 if (!getintarg(args, &len))
576 return NULL;
577 flags = 0;
578 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000579 buf = newsizedstringobject((char *) 0, len);
580 if (buf == NULL)
581 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000582 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000583 if (n < 0)
584 return socket_error();
585 if (resizestring(&buf, n) < 0)
586 return NULL;
587 return buf;
588}
589
Guido van Rossum30a685f1991-06-27 15:51:29 +0000590
591/* s.recvfrom(nbytes) method */
592
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000593static object *
594sock_recvfrom(s, args)
595 sockobject *s;
596 object *args;
597{
598 char addrbuf[256];
599 object *buf;
600 int addrlen, len, n;
601 if (!getintarg(args, &len))
602 return NULL;
603 buf = newsizedstringobject((char *) 0, len);
604 addrlen = sizeof addrbuf;
605 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
606 addrbuf, &addrlen);
607 if (n < 0)
608 return socket_error();
609 if (resizestring(&buf, n) < 0)
610 return NULL;
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000611 return mkvalue("OO", buf,
Guido van Rossumd15b7331992-03-27 17:22:00 +0000612 makesockaddr((struct sockaddr *)addrbuf, addrlen));
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000613}
614
Guido van Rossum30a685f1991-06-27 15:51:29 +0000615
616/* s.send(data) method */
617
618static object *
619sock_send(s, args)
620 sockobject *s;
621 object *args;
622{
623 object *buf;
624 int len, n, flags;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000625 if (!getStrintarg(args, &buf, &flags)) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000626 err_clear();
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000627 if (!getStrarg(args, &buf))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000628 return NULL;
629 flags = 0;
630 }
631 len = getstringsize(buf);
632 n = send(s->sock_fd, getstringvalue(buf), len, flags);
633 if (n < 0)
634 return socket_error();
635 INCREF(None);
636 return None;
637}
638
639
640/* s.sendto(data, sockaddr) method */
641
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000642static object *
643sock_sendto(s, args)
644 sockobject *s;
645 object *args;
646{
647 object *buf;
648 struct sockaddr *addr;
649 int addrlen, len, n;
650 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
651 err_badarg();
652 return NULL;
653 }
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000654 if (!getStrarg(gettupleitem(args, 0), &buf) ||
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000655 !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
656 return NULL;
657 len = getstringsize(buf);
658 n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
659 addr, addrlen);
660 if (n < 0)
661 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000662 INCREF(None);
663 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000664}
665
Guido van Rossum30a685f1991-06-27 15:51:29 +0000666
667/* s.shutdown(how) method */
668
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000669static object *
670sock_shutdown(s, args)
671 sockobject *s;
672 object *args;
673{
674 int how;
675 if (!getintarg(args, &how))
676 return NULL;
677 if (shutdown(s->sock_fd, how) < 0)
678 return socket_error();
679 INCREF(None);
680 return None;
681}
682
Guido van Rossum30a685f1991-06-27 15:51:29 +0000683
684/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000685
686static struct methodlist sock_methods[] = {
687 {"accept", sock_accept},
Guido van Rossum81194471991-07-27 21:42:02 +0000688 {"avail", sock_avail},
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000689 {"allowbroadcast", sock_allowbroadcast},
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000690 {"setsockopt", sock_setsockopt},
691 {"getsockopt", sock_getsockopt},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000692 {"bind", sock_bind},
693 {"close", sock_close},
694 {"connect", sock_connect},
Guido van Rossumed233a51992-06-23 09:07:03 +0000695 {"fileno", sock_fileno},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000696 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000697 {"makefile", sock_makefile},
698 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000699 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000700 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000701 {"sendto", sock_sendto},
702 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000703 {NULL, NULL} /* sentinel */
704};
705
Guido van Rossum30a685f1991-06-27 15:51:29 +0000706
707/* Deallocate a socket object in response to the last DECREF().
708 First close the file description. */
709
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000710static void
711sock_dealloc(s)
712 sockobject *s;
713{
714 (void) close(s->sock_fd);
715 DEL(s);
716}
717
Guido van Rossum30a685f1991-06-27 15:51:29 +0000718
719/* Return a socket object's named attribute. */
720
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000721static object *
722sock_getattr(s, name)
723 sockobject *s;
724 char *name;
725{
726 return findmethod(sock_methods, (object *) s, name);
727}
728
Guido van Rossum30a685f1991-06-27 15:51:29 +0000729
730/* Type object for socket objects.
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000731 XXX This should be static, but some compilers don't grok the
732 XXX forward reference to it in that case... */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000733
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000734typeobject Socktype = {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000735 OB_HEAD_INIT(&Typetype)
736 0,
737 "socket",
738 sizeof(sockobject),
739 0,
740 sock_dealloc, /*tp_dealloc*/
741 0, /*tp_print*/
742 sock_getattr, /*tp_getattr*/
743 0, /*tp_setattr*/
744 0, /*tp_compare*/
745 0, /*tp_repr*/
746 0, /*tp_as_number*/
747 0, /*tp_as_sequence*/
748 0, /*tp_as_mapping*/
749};
750
Guido van Rossum30a685f1991-06-27 15:51:29 +0000751
Guido van Rossum81194471991-07-27 21:42:02 +0000752/* Python interface to gethostname(). */
753
754/*ARGSUSED*/
755static object *
756socket_gethostname(self, args)
757 object *self;
758 object *args;
759{
760 char buf[1024];
761 if (!getnoarg(args))
762 return NULL;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000763 if (gethostname(buf, (int) sizeof buf - 1) < 0)
Guido van Rossum81194471991-07-27 21:42:02 +0000764 return socket_error();
765 buf[sizeof buf - 1] = '\0';
766 return newstringobject(buf);
767}
Guido van Rossum30a685f1991-06-27 15:51:29 +0000768/* Python interface to gethostbyname(name). */
769
770/*ARGSUSED*/
771static object *
772socket_gethostbyname(self, args)
773 object *self;
774 object *args;
775{
776 object *name;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000777 struct sockaddr_in addrbuf;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000778 if (!getStrarg(args, &name))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000779 return NULL;
780 if (setipaddr(getstringvalue(name), &addrbuf) < 0)
781 return NULL;
782 return makeipaddr(&addrbuf);
783}
784
785
786/* Python interface to getservbyname(name).
787 This only returns the port number, since the other info is already
788 known or not useful (like the list of aliases). */
789
790/*ARGSUSED*/
791static object *
792socket_getservbyname(self, args)
793 object *self;
794 object *args;
795{
796 object *name, *proto;
797 struct servent *sp;
Guido van Rossum9c16d7f1992-01-27 16:49:54 +0000798 if (!getStrStrarg(args, &name, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000799 return NULL;
800 sp = getservbyname(getstringvalue(name), getstringvalue(proto));
801 if (sp == NULL) {
802 err_setstr(SocketError, "service/proto not found");
803 return NULL;
804 }
805 return newintobject((long) ntohs(sp->s_port));
806}
807
808
809/* Python interface to socket(family, type, proto).
810 The third (protocol) argument is optional.
811 Return a new socket object. */
812
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000813/*ARGSUSED*/
814static object *
815socket_socket(self, args)
816 object *self;
817 object *args;
818{
819 sockobject *s;
820 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000821 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000822 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000823 return NULL;
824 }
825 else {
826 if (!getintintarg(args, &family, &type))
827 return NULL;
828 proto = 0;
829 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000830 fd = socket(family, type, proto);
831 if (fd < 0)
832 return socket_error();
833 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000834 /* If the object can't be created, don't forget to close the
835 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000836 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000837 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000838 /* From now on, ignore SIGPIPE and let the error checking
839 do the work. */
840 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000841 return (object *) s;
842}
843
Guido van Rossum30a685f1991-06-27 15:51:29 +0000844
845/* List of functions exported by this module. */
846
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000847static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000848 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +0000849 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000850 {"getservbyname", socket_getservbyname},
851 {"socket", socket_socket},
852 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000853};
854
Guido van Rossum30a685f1991-06-27 15:51:29 +0000855
856/* Convenience routine to export an integer value.
857 For simplicity, errors (which are unlikely anyway) are ignored. */
858
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000859static void
860insint(d, name, value)
861 object *d;
862 char *name;
863 int value;
864{
865 object *v = newintobject((long) value);
866 if (v == NULL) {
867 /* Don't bother reporting this error */
868 err_clear();
869 }
870 else {
871 dictinsert(d, name, v);
872 DECREF(v);
873 }
874}
875
Guido van Rossum30a685f1991-06-27 15:51:29 +0000876
877/* Initialize this module.
878 This is called when the first 'import socket' is done,
879 via a table in config.c, if config.c is compiled with USE_SOCKET
880 defined. */
881
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000882void
883initsocket()
884{
885 object *m, *d;
886
887 m = initmodule("socket", socket_methods);
888 d = getmoduledict(m);
889 SocketError = newstringobject("socket.error");
890 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
891 fatal("can't define socket.error");
892 insint(d, "AF_INET", AF_INET);
893 insint(d, "AF_UNIX", AF_UNIX);
894 insint(d, "SOCK_STREAM", SOCK_STREAM);
895 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
896 insint(d, "SOCK_RAW", SOCK_RAW);
897 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
898 insint(d, "SOCK_RDM", SOCK_RDM);
899}