blob: b1ab96d717dc4f4051b6cb7f645901df755be647 [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
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 Rossum0e69587d1992-06-05 15:11:30 +000036- setsockopt() and getsockopt() only support integer options
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 Rossum0e69587d1992-06-05 15:11:30 +000056- s.setsockopt(level, optname, flag) --> None
57- s.getsockopt(level, optname) --> flag
Guido van Rossum30a685f1991-06-27 15:51:29 +000058- s.bind(sockaddr) --> None
59- s.connect(sockaddr) --> None
Guido van Rossum30a685f1991-06-27 15:51:29 +000060- s.listen(n) --> None
61- s.makefile(mode) --> file object
62- s.recv(nbytes) --> string
63- s.recvfrom(nbytes) --> string, sockaddr
64- s.send(string) --> None
65- s.sendto(string, sockaddr) --> None
66- s.shutdown(how) --> None
67- s.close() --> None
68
Guido van Rossum6574b3e1991-06-25 21:36:08 +000069*/
70
71#include "allobjects.h"
72#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000073#include "ceval.h"
Guido van Rossum6574b3e1991-06-25 21:36:08 +000074
Guido van Rossumed233a51992-06-23 09:07:03 +000075#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
76
Guido van Rossum81194471991-07-27 21:42:02 +000077#include <signal.h>
Guido van Rossum6574b3e1991-06-25 21:36:08 +000078#include <sys/socket.h>
79#include <netinet/in.h>
80#include <sys/un.h>
81#include <netdb.h>
82
Guido van Rossum30a685f1991-06-27 15:51:29 +000083
84/* Global variable holding the exception type for errors detected
85 by this module (but not argument type or memory errors, etc.). */
86
87static object *SocketError;
88
89
90/* Convenience function to raise an error according to errno
91 and return a NULL pointer from a function. */
Guido van Rossum6574b3e1991-06-25 21:36:08 +000092
93static object *
94socket_error()
95{
96 return err_errno(SocketError);
97}
98
Guido van Rossum30a685f1991-06-27 15:51:29 +000099
100/* The object holding a socket. It holds some extra information,
101 like the address family, which is used to decode socket address
102 arguments properly. */
103
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000104typedef struct {
105 OB_HEAD
Guido van Rossum30a685f1991-06-27 15:51:29 +0000106 int sock_fd; /* Socket file descriptor */
107 int sock_family; /* Address family, e.g., AF_INET */
108 int sock_type; /* Socket type, e.g., SOCK_STREAM */
109 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000110} sockobject;
111
Guido van Rossum30a685f1991-06-27 15:51:29 +0000112
113/* A forward reference to the Socktype type object.
114 The Socktype variable contains pointers to various functions,
115 some of which call newsocobject(), which uses Socktype, so
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000116 there has to be a circular reference. */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000117
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000118extern typeobject Socktype; /* Forward */
119
Guido van Rossum30a685f1991-06-27 15:51:29 +0000120
121/* Create a new socket object.
122 This just creates the object and initializes it.
123 If the creation fails, return NULL and set an exception (implicit
124 in NEWOBJ()). */
125
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000126static sockobject *
127newsockobject(fd, family, type, proto)
128 int fd, family, type, proto;
129{
130 sockobject *s;
131 s = NEWOBJ(sockobject, &Socktype);
132 if (s != NULL) {
133 s->sock_fd = fd;
134 s->sock_family = family;
135 s->sock_type = type;
136 s->sock_proto = proto;
137 }
138 return s;
139}
140
Guido van Rossum30a685f1991-06-27 15:51:29 +0000141
142/* Convert a string specifying a host name or one of a few symbolic
143 names to a numeric IP address. This usually calls gethostbyname()
144 to do the work; the names "" and "<broadcast>" are special.
145 Return the length (should always be 4 bytes), or negative if
146 an error occurred; then an exception is raised. */
147
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000148static int
Guido van Rossum30a685f1991-06-27 15:51:29 +0000149setipaddr(name, addr_ret)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000150 char *name;
151 struct sockaddr_in *addr_ret;
152{
153 struct hostent *hp;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000154 int d1, d2, d3, d4;
155 char ch;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000156
Guido van Rossum30a685f1991-06-27 15:51:29 +0000157 if (name[0] == '\0') {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000158 addr_ret->sin_addr.s_addr = INADDR_ANY;
159 return 4;
160 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000161 if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000162 addr_ret->sin_addr.s_addr = INADDR_BROADCAST;
163 return 4;
164 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000165 if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
166 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
167 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
168 addr_ret->sin_addr.s_addr = htonl(
169 ((long) d1 << 24) | ((long) d2 << 16) |
170 ((long) d3 << 8) | ((long) d4 << 0));
171 return 4;
172 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000173 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000174 hp = gethostbyname(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000175 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000176 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
Guido van Rossum30a685f1991-06-27 15:51:29 +0000185/* Create a string object representing an IP address.
186 This is always a string of the form 'dd.dd.dd.dd' (with variable
187 size numbers). */
188
189static object *
190makeipaddr(addr)
191 struct sockaddr_in *addr;
192{
193 long x = ntohl(addr->sin_addr.s_addr);
194 char buf[100];
195 sprintf(buf, "%d.%d.%d.%d",
196 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
197 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
198 return newstringobject(buf);
199}
200
201
202/* Create an object representing the given socket address,
203 suitable for passing it back to bind(), connect() etc.
204 The family field of the sockaddr structure is inspected
205 to determine what kind of address it really is. */
206
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000207/*ARGSUSED*/
208static object *
209makesockaddr(addr, addrlen)
210 struct sockaddr *addr;
211 int addrlen;
212{
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000213 if (addrlen == 0) {
214 /* No address -- may be recvfrom() from known socket */
215 INCREF(None);
216 return None;
217 }
218
Guido van Rossum30a685f1991-06-27 15:51:29 +0000219 switch (addr->sa_family) {
220
221 case AF_INET:
222 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000223 struct sockaddr_in *a = (struct sockaddr_in *) addr;
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000224 return mkvalue("Oi", makeipaddr(a), ntohs(a->sin_port));
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000225 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000226
227 case AF_UNIX:
228 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000229 struct sockaddr_un *a = (struct sockaddr_un *) addr;
230 return newstringobject(a->sun_path);
231 }
Guido van Rossum30a685f1991-06-27 15:51:29 +0000232
233 /* More cases here... */
234
235 default:
236 err_setstr(SocketError, "return unknown socket address type");
237 return NULL;
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000238
Guido van Rossum30a685f1991-06-27 15:51:29 +0000239 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000240}
241
Guido van Rossum30a685f1991-06-27 15:51:29 +0000242
243/* Parse a socket address argument according to the socket object's
244 address family. Return 1 if the address was in the proper format,
245 0 of not. The address is returned through addr_ret, its length
246 through len_ret. */
247
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000248static int
249getsockaddrarg(s, args, addr_ret, len_ret)
250 sockobject *s;
251 object *args;
252 struct sockaddr **addr_ret;
253 int *len_ret;
254{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000255 switch (s->sock_family) {
256
257 case AF_UNIX:
258 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000259 static struct sockaddr_un addr;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000260 char *path;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000261 int len;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000262 if (!getargs(args, "s#", &path, &len))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000263 return 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000264 if (len > sizeof addr.sun_path) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000265 err_setstr(SocketError, "AF_UNIX path too long");
266 return 0;
267 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000268 addr.sun_family = AF_UNIX;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000269 memcpy(addr.sun_path, path, len);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000270 *addr_ret = (struct sockaddr *) &addr;
271 *len_ret = len + sizeof addr.sun_family;
272 return 1;
273 }
274
Guido van Rossum30a685f1991-06-27 15:51:29 +0000275 case AF_INET:
276 {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000277 static struct sockaddr_in addr;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000278 char *host;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000279 int port;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000280 if (!getargs(args, "(si)", &host, &port))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000281 return 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000282 if (setipaddr(host, &addr) < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000283 return 0;
284 addr.sin_family = AF_INET;
285 addr.sin_port = htons(port);
286 *addr_ret = (struct sockaddr *) &addr;
287 *len_ret = sizeof addr;
288 return 1;
289 }
290
Guido van Rossum30a685f1991-06-27 15:51:29 +0000291 /* More cases here... */
292
293 default:
294 err_setstr(SocketError, "getsockaddrarg: bad family");
295 return 0;
296
297 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000298}
299
Guido van Rossum30a685f1991-06-27 15:51:29 +0000300
Guido van Rossum710e1df1992-06-12 10:39:36 +0000301/* Get the address length according to the socket object's address family.
302 Return 1 if the family is known, 0 otherwise. The length is returned
303 through len_ret. */
304
305static int
306getsockaddrlen(s, len_ret)
307 sockobject *s;
308 int *len_ret;
309{
310 switch (s->sock_family) {
311
312 case AF_UNIX:
313 {
314 *len_ret = sizeof (struct sockaddr_un);
315 return 1;
316 }
317
318 case AF_INET:
319 {
320 *len_ret = sizeof (struct sockaddr_in);
321 return 1;
322 }
323
324 /* More cases here... */
325
326 default:
327 err_setstr(SocketError, "getsockaddrarg: bad family");
328 return 0;
329
330 }
331}
332
333
Guido van Rossum30a685f1991-06-27 15:51:29 +0000334/* s.accept() method */
335
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000336static object *
337sock_accept(s, args)
338 sockobject *s;
339 object *args;
340{
341 char addrbuf[256];
342 int addrlen, newfd;
343 object *res;
344 if (!getnoarg(args))
345 return NULL;
Guido van Rossum710e1df1992-06-12 10:39:36 +0000346 if (!getsockaddrlen(s, &addrlen))
347 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000348 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000349 newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000350 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000351 if (newfd < 0)
352 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000353 /* Create the new object with unspecified family,
354 to avoid calls to bind() etc. on it. */
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000355 res = mkvalue("OO", (object *) newsockobject(newfd,
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000356 s->sock_family,
357 s->sock_type,
358 s->sock_proto),
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000359 makesockaddr((struct sockaddr *) addrbuf, addrlen));
360 if (res == NULL)
361 close(newfd);
362 return res;
363}
364
Guido van Rossum30a685f1991-06-27 15:51:29 +0000365
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000366/* s.allowbroadcast() method */
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000367/* XXX obsolete -- will disappear in next release */
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000368
369static object *
370sock_allowbroadcast(s, args)
371 sockobject *s;
372 object *args;
373{
374 int flag;
375 int res;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000376 if (!getargs(args, "i", &flag))
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000377 return NULL;
378 res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
379 &flag, sizeof flag);
380 if (res < 0)
381 return socket_error();
382 INCREF(None);
383 return None;
384}
385
386
Guido van Rossumaee08791992-09-08 09:05:33 +0000387/* s.setsockopt() method.
388 With an integer third argument, sets an integer option.
389 With a string third argument, sets an option from a buffer;
390 use optional built-in module 'struct' to encode the string. */
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000391
392static object *
393sock_setsockopt(s, args)
394 sockobject *s;
395 object *args;
396{
397 int level;
398 int optname;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000399 int res;
Guido van Rossumaee08791992-09-08 09:05:33 +0000400 char *buf;
401 int buflen;
402 int flag;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000403
Guido van Rossumaee08791992-09-08 09:05:33 +0000404 if (getargs(args, "(iii)", &level, &optname, &flag)) {
405 buf = (char *) &flag;
406 buflen = sizeof flag;
407 }
408 else {
409 err_clear();
410 if (!getargs(args, "(iis#)", &level, &optname, &buf, &buflen))
411 return NULL;
412 }
413 res = setsockopt(s->sock_fd, level, optname, buf, buflen);
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000414 if (res < 0)
415 return socket_error();
416 INCREF(None);
417 return None;
418}
419
420
Guido van Rossumaee08791992-09-08 09:05:33 +0000421/* s.getsockopt() method.
422 With two arguments, retrieves an integer option.
423 With a third integer argument, retrieves a string buffer of that size;
424 use optional built-in module 'struct' to decode the string. */
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000425
426static object *
427sock_getsockopt(s, args)
428 sockobject *s;
429 object *args;
430{
431 int level;
432 int optname;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000433 int res;
Guido van Rossumaee08791992-09-08 09:05:33 +0000434 object *buf;
435 int buflen;
436 int flag;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000437
Guido van Rossumaee08791992-09-08 09:05:33 +0000438 if (getargs(args, "(ii)", &level, &optname)) {
439 int flag = 0;
440 int flagsize = sizeof flag;
441 res = getsockopt(s->sock_fd, level, optname, &flag, &flagsize);
442 if (res < 0)
443 return socket_error();
444 return newintobject(flag);
445 }
446 err_clear();
447 if (!getargs(args, "(iii)", &level, &optname, &buflen))
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000448 return NULL;
Guido van Rossumaee08791992-09-08 09:05:33 +0000449 if (buflen <= 0 || buflen > 1024) {
450 err_setstr(SocketError, "getsockopt buflen out of range");
451 return NULL;
452 }
453 buf = newsizedstringobject((char *)NULL, buflen);
454 if (buf == NULL)
455 return NULL;
456 res = getsockopt(s->sock_fd, level, optname, getstringvalue(buf),
457 &buflen);
458 if (res < 0) {
459 DECREF(buf);
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000460 return socket_error();
Guido van Rossumaee08791992-09-08 09:05:33 +0000461 }
462 resizestring(&buf, buflen);
463 return buf;
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000464}
465
466
Guido van Rossum81194471991-07-27 21:42:02 +0000467/* s.avail() method */
468
469static object *
470sock_avail(s, args)
471 sockobject *s;
472 object *args;
473{
474 struct timeval timeout;
475 fd_set readers;
476 int n;
Guido van Rossumd15b7331992-03-27 17:22:00 +0000477 if (!getnoarg(args))
478 return NULL;
Guido van Rossum81194471991-07-27 21:42:02 +0000479 timeout.tv_sec = 0;
480 timeout.tv_usec = 0;
481 FD_ZERO(&readers);
482 FD_SET(s->sock_fd, &readers);
483 n = select(s->sock_fd+1, &readers, (fd_set *)0, (fd_set *)0, &timeout);
484 if (n < 0)
485 return socket_error();
486 return newintobject((long) (n != 0));
487}
488
489
Guido van Rossum30a685f1991-06-27 15:51:29 +0000490/* s.bind(sockaddr) method */
491
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000492static object *
493sock_bind(s, args)
494 sockobject *s;
495 object *args;
496{
497 struct sockaddr *addr;
498 int addrlen;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000499 int res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000500 if (!getsockaddrarg(s, args, &addr, &addrlen))
501 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000502 BGN_SAVE
503 res = bind(s->sock_fd, addr, addrlen);
504 END_SAVE
505 if (res < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000506 return socket_error();
507 INCREF(None);
508 return None;
509}
510
Guido van Rossum30a685f1991-06-27 15:51:29 +0000511
512/* s.close() method.
513 Set the file descriptor to -1 so operations tried subsequently
514 will surely fail. */
515
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000516static object *
517sock_close(s, args)
518 sockobject *s;
519 object *args;
520{
521 if (!getnoarg(args))
522 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000523 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000524 (void) close(s->sock_fd);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000525 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000526 s->sock_fd = -1;
527 INCREF(None);
528 return None;
529}
530
Guido van Rossum30a685f1991-06-27 15:51:29 +0000531
532/* s.connect(sockaddr) method */
533
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000534static object *
535sock_connect(s, args)
536 sockobject *s;
537 object *args;
538{
539 struct sockaddr *addr;
540 int addrlen;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000541 int res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000542 if (!getsockaddrarg(s, args, &addr, &addrlen))
543 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000544 BGN_SAVE
545 res = connect(s->sock_fd, addr, addrlen);
546 END_SAVE
547 if (res < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000548 return socket_error();
549 INCREF(None);
550 return None;
551}
552
Guido van Rossum30a685f1991-06-27 15:51:29 +0000553
Guido van Rossumed233a51992-06-23 09:07:03 +0000554/* s.fileno() method */
555
556static object *
557sock_fileno(s, args)
558 sockobject *s;
559 object *args;
560{
561 if (!getnoarg(args))
562 return NULL;
563 return newintobject((long) s->sock_fd);
564}
565
566
Guido van Rossum30a685f1991-06-27 15:51:29 +0000567/* s.listen(n) method */
568
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000569static object *
570sock_listen(s, args)
571 sockobject *s;
572 object *args;
573{
574 int backlog;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000575 int res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000576 if (!getintarg(args, &backlog))
577 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000578 BGN_SAVE
579 res = listen(s->sock_fd, backlog);
580 END_SAVE
581 if (res < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000582 return socket_error();
583 INCREF(None);
584 return None;
585}
586
Guido van Rossum30a685f1991-06-27 15:51:29 +0000587
588/* s.makefile(mode) method.
589 Create a new open file object referring to a dupped version of
590 the socket's file descriptor. (The dup() call is necessary so
591 that the open file and socket objects may be closed independent
592 of each other.)
593 The mode argument specifies 'r' or 'w' passed to fdopen(). */
594
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000595static object *
Guido van Rossum30a685f1991-06-27 15:51:29 +0000596sock_makefile(s, args)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000597 sockobject *s;
598 object *args;
599{
Guido van Rossum30a685f1991-06-27 15:51:29 +0000600 extern int fclose PROTO((FILE *));
Guido van Rossumff4949e1992-08-05 19:58:53 +0000601 char *mode;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000602 int fd;
603 FILE *fp;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000604 if (!getargs(args, "s", &mode))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000605 return NULL;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000606 if ((fd = dup(s->sock_fd)) < 0 ||
Guido van Rossumff4949e1992-08-05 19:58:53 +0000607 (fp = fdopen(fd, mode)) == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000608 return socket_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000609 return newopenfileobject(fp, "<socket>", mode, fclose);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000610}
611
612
613/* s.recv(nbytes) method */
614
615static object *
616sock_recv(s, args)
617 sockobject *s;
618 object *args;
619{
620 int len, n, flags;
621 object *buf;
622 if (!getintintarg(args, &len, &flags)) {
623 err_clear();
624 if (!getintarg(args, &len))
625 return NULL;
626 flags = 0;
627 }
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000628 buf = newsizedstringobject((char *) 0, len);
629 if (buf == NULL)
630 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000631 BGN_SAVE
Guido van Rossum30a685f1991-06-27 15:51:29 +0000632 n = recv(s->sock_fd, getstringvalue(buf), len, flags);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000633 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000634 if (n < 0)
635 return socket_error();
636 if (resizestring(&buf, n) < 0)
637 return NULL;
638 return buf;
639}
640
Guido van Rossum30a685f1991-06-27 15:51:29 +0000641
642/* s.recvfrom(nbytes) method */
643
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000644static object *
645sock_recvfrom(s, args)
646 sockobject *s;
647 object *args;
648{
649 char addrbuf[256];
650 object *buf;
651 int addrlen, len, n;
652 if (!getintarg(args, &len))
653 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000654 if (!getsockaddrlen(s, &addrlen))
655 return NULL;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000656 buf = newsizedstringobject((char *) 0, len);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000657 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000658 n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
659 addrbuf, &addrlen);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000660 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000661 if (n < 0)
662 return socket_error();
663 if (resizestring(&buf, n) < 0)
664 return NULL;
Guido van Rossum25bec8c1992-08-05 19:00:45 +0000665 return mkvalue("OO", buf,
Guido van Rossumd15b7331992-03-27 17:22:00 +0000666 makesockaddr((struct sockaddr *)addrbuf, addrlen));
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000667}
668
Guido van Rossum30a685f1991-06-27 15:51:29 +0000669
670/* s.send(data) method */
671
672static object *
673sock_send(s, args)
674 sockobject *s;
675 object *args;
676{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000677 char *buf;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000678 int len, n, flags;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000679 if (!getargs(args, "(s#i)", &buf, &len, &flags)) {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000680 err_clear();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000681 if (!getargs(args, "s#", &buf, &len))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000682 return NULL;
683 flags = 0;
684 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000685 BGN_SAVE
686 n = send(s->sock_fd, buf, len, flags);
687 END_SAVE
Guido van Rossum30a685f1991-06-27 15:51:29 +0000688 if (n < 0)
689 return socket_error();
690 INCREF(None);
691 return None;
692}
693
694
695/* s.sendto(data, sockaddr) method */
696
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000697static object *
698sock_sendto(s, args)
699 sockobject *s;
700 object *args;
701{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000702 object *addro;
703 char *buf;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000704 struct sockaddr *addr;
705 int addrlen, len, n;
706 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
707 err_badarg();
708 return NULL;
709 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000710 if (!getargs(args, "(s#O)", &buf, &len, &addro) ||
711 !getsockaddrarg(s, addro, &addr, &addrlen))
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000712 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000713 BGN_SAVE
714 n = sendto(s->sock_fd, buf, len, 0, addr, addrlen);
715 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000716 if (n < 0)
717 return socket_error();
Guido van Rossum30a685f1991-06-27 15:51:29 +0000718 INCREF(None);
719 return None;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000720}
721
Guido van Rossum30a685f1991-06-27 15:51:29 +0000722
723/* s.shutdown(how) method */
724
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000725static object *
726sock_shutdown(s, args)
727 sockobject *s;
728 object *args;
729{
730 int how;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000731 int res;
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000732 if (!getintarg(args, &how))
733 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000734 BGN_SAVE
735 res = shutdown(s->sock_fd, how);
736 END_SAVE
737 if (res < 0)
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000738 return socket_error();
739 INCREF(None);
740 return None;
741}
742
Guido van Rossum30a685f1991-06-27 15:51:29 +0000743
744/* List of methods for socket objects */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000745
746static struct methodlist sock_methods[] = {
747 {"accept", sock_accept},
Guido van Rossum81194471991-07-27 21:42:02 +0000748 {"avail", sock_avail},
Guido van Rossume0e5edc1991-10-20 20:22:28 +0000749 {"allowbroadcast", sock_allowbroadcast},
Guido van Rossum0e69587d1992-06-05 15:11:30 +0000750 {"setsockopt", sock_setsockopt},
751 {"getsockopt", sock_getsockopt},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000752 {"bind", sock_bind},
753 {"close", sock_close},
754 {"connect", sock_connect},
Guido van Rossumed233a51992-06-23 09:07:03 +0000755 {"fileno", sock_fileno},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000756 {"listen", sock_listen},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000757 {"makefile", sock_makefile},
758 {"recv", sock_recv},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000759 {"recvfrom", sock_recvfrom},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000760 {"send", sock_send},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000761 {"sendto", sock_sendto},
762 {"shutdown", sock_shutdown},
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000763 {NULL, NULL} /* sentinel */
764};
765
Guido van Rossum30a685f1991-06-27 15:51:29 +0000766
767/* Deallocate a socket object in response to the last DECREF().
768 First close the file description. */
769
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000770static void
771sock_dealloc(s)
772 sockobject *s;
773{
774 (void) close(s->sock_fd);
775 DEL(s);
776}
777
Guido van Rossum30a685f1991-06-27 15:51:29 +0000778
779/* Return a socket object's named attribute. */
780
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000781static object *
782sock_getattr(s, name)
783 sockobject *s;
784 char *name;
785{
786 return findmethod(sock_methods, (object *) s, name);
787}
788
Guido van Rossum30a685f1991-06-27 15:51:29 +0000789
790/* Type object for socket objects.
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000791 XXX This should be static, but some compilers don't grok the
792 XXX forward reference to it in that case... */
Guido van Rossum30a685f1991-06-27 15:51:29 +0000793
Guido van Rossum54ba21b1991-09-10 14:57:12 +0000794typeobject Socktype = {
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000795 OB_HEAD_INIT(&Typetype)
796 0,
797 "socket",
798 sizeof(sockobject),
799 0,
800 sock_dealloc, /*tp_dealloc*/
801 0, /*tp_print*/
802 sock_getattr, /*tp_getattr*/
803 0, /*tp_setattr*/
804 0, /*tp_compare*/
805 0, /*tp_repr*/
806 0, /*tp_as_number*/
807 0, /*tp_as_sequence*/
808 0, /*tp_as_mapping*/
809};
810
Guido van Rossum30a685f1991-06-27 15:51:29 +0000811
Guido van Rossum81194471991-07-27 21:42:02 +0000812/* Python interface to gethostname(). */
813
814/*ARGSUSED*/
815static object *
816socket_gethostname(self, args)
817 object *self;
818 object *args;
819{
820 char buf[1024];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000821 int res;
Guido van Rossum81194471991-07-27 21:42:02 +0000822 if (!getnoarg(args))
823 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000824 BGN_SAVE
825 res = gethostname(buf, (int) sizeof buf - 1);
826 END_SAVE
827 if (res < 0)
Guido van Rossum81194471991-07-27 21:42:02 +0000828 return socket_error();
829 buf[sizeof buf - 1] = '\0';
830 return newstringobject(buf);
831}
Guido van Rossumff4949e1992-08-05 19:58:53 +0000832
833
Guido van Rossum30a685f1991-06-27 15:51:29 +0000834/* Python interface to gethostbyname(name). */
835
836/*ARGSUSED*/
837static object *
838socket_gethostbyname(self, args)
839 object *self;
840 object *args;
841{
842 object *name;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000843 struct sockaddr_in addrbuf;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000844 if (!getargs(args, "s", &name))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000845 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000846 if (setipaddr(name, &addrbuf) < 0)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000847 return NULL;
848 return makeipaddr(&addrbuf);
849}
850
851
852/* Python interface to getservbyname(name).
853 This only returns the port number, since the other info is already
854 known or not useful (like the list of aliases). */
855
856/*ARGSUSED*/
857static object *
858socket_getservbyname(self, args)
859 object *self;
860 object *args;
861{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000862 char *name, *proto;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000863 struct servent *sp;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000864 if (!getargs(args, "(ss)", &name, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000865 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000866 BGN_SAVE
867 sp = getservbyname(name, proto);
868 END_SAVE
Guido van Rossum30a685f1991-06-27 15:51:29 +0000869 if (sp == NULL) {
870 err_setstr(SocketError, "service/proto not found");
871 return NULL;
872 }
873 return newintobject((long) ntohs(sp->s_port));
874}
875
876
877/* Python interface to socket(family, type, proto).
878 The third (protocol) argument is optional.
879 Return a new socket object. */
880
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000881/*ARGSUSED*/
882static object *
883socket_socket(self, args)
884 object *self;
885 object *args;
886{
887 sockobject *s;
888 int family, type, proto, fd;
Guido van Rossum30a685f1991-06-27 15:51:29 +0000889 if (args != NULL && is_tupleobject(args) && gettuplesize(args) == 3) {
Guido van Rossum4dd2a7e1991-07-01 18:51:33 +0000890 if (!getintintintarg(args, &family, &type, &proto))
Guido van Rossum30a685f1991-06-27 15:51:29 +0000891 return NULL;
892 }
893 else {
894 if (!getintintarg(args, &family, &type))
895 return NULL;
896 proto = 0;
897 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000898 BGN_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000899 fd = socket(family, type, proto);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000900 END_SAVE
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000901 if (fd < 0)
902 return socket_error();
903 s = newsockobject(fd, family, type, proto);
Guido van Rossum30a685f1991-06-27 15:51:29 +0000904 /* If the object can't be created, don't forget to close the
905 file descriptor again! */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000906 if (s == NULL)
Guido van Rossum30a685f1991-06-27 15:51:29 +0000907 (void) close(fd);
Guido van Rossum81194471991-07-27 21:42:02 +0000908 /* From now on, ignore SIGPIPE and let the error checking
909 do the work. */
910 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000911 return (object *) s;
912}
913
Guido van Rossum30a685f1991-06-27 15:51:29 +0000914
915/* List of functions exported by this module. */
916
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000917static struct methodlist socket_methods[] = {
Guido van Rossum30a685f1991-06-27 15:51:29 +0000918 {"gethostbyname", socket_gethostbyname},
Guido van Rossum81194471991-07-27 21:42:02 +0000919 {"gethostname", socket_gethostname},
Guido van Rossum30a685f1991-06-27 15:51:29 +0000920 {"getservbyname", socket_getservbyname},
921 {"socket", socket_socket},
922 {NULL, NULL} /* Sentinel */
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000923};
924
Guido van Rossum30a685f1991-06-27 15:51:29 +0000925
926/* Convenience routine to export an integer value.
927 For simplicity, errors (which are unlikely anyway) are ignored. */
928
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000929static void
930insint(d, name, value)
931 object *d;
932 char *name;
933 int value;
934{
935 object *v = newintobject((long) value);
936 if (v == NULL) {
937 /* Don't bother reporting this error */
938 err_clear();
939 }
940 else {
941 dictinsert(d, name, v);
942 DECREF(v);
943 }
944}
945
Guido van Rossum30a685f1991-06-27 15:51:29 +0000946
947/* Initialize this module.
948 This is called when the first 'import socket' is done,
949 via a table in config.c, if config.c is compiled with USE_SOCKET
950 defined. */
951
Guido van Rossum6574b3e1991-06-25 21:36:08 +0000952void
953initsocket()
954{
955 object *m, *d;
956
957 m = initmodule("socket", socket_methods);
958 d = getmoduledict(m);
959 SocketError = newstringobject("socket.error");
960 if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0)
961 fatal("can't define socket.error");
962 insint(d, "AF_INET", AF_INET);
963 insint(d, "AF_UNIX", AF_UNIX);
964 insint(d, "SOCK_STREAM", SOCK_STREAM);
965 insint(d, "SOCK_DGRAM", SOCK_DGRAM);
966 insint(d, "SOCK_RAW", SOCK_RAW);
967 insint(d, "SOCK_SEQPACKET", SOCK_SEQPACKET);
968 insint(d, "SOCK_RDM", SOCK_RDM);
969}