5106 lines · 126.3 KB · C
RawDownload
		{WSAEUSERS, "Too many users"},		{WSAEDQUOT, "Disc quota exceeded"},		{WSAESTALE, "Stale NFS file handle"},		{WSAEREMOTE, "Too many levels of remote in path"},		{WSASYSNOTREADY, "Network subsystem is unvailable"},		{WSAVERNOTSUPPORTED, "WinSock version is not supported"},		{WSANOTINITIALISED,		  "Successful WSAStartup() not yet performed"},		{WSAEDISCON, "Graceful shutdown in progress"},		/* Resolver errors */		{WSAHOST_NOT_FOUND, "No such host is known"},		{WSATRY_AGAIN, "Host not found, or server failed"},		{WSANO_RECOVERY, "Unexpected server error encountered"},		{WSANO_DATA, "Valid name without requested data"},		{WSANO_ADDRESS, "No address, look for MX record"},		{0, NULL}	};	if (err_no) {		PyObject *v;		const char *msg = "winsock error"; 		for (msgp = msgs; msgp->msg; msgp++) {			if (err_no == msgp->no) {				msg = msgp->msg;				break;			}		} 		v = Py_BuildValue("(is)", err_no, msg);		if (v != NULL) {			PyErr_SetObject(socket_error, v);			Py_DECREF(v);		}		return NULL;	}	else#endif #if defined(PYOS_OS2) && !defined(PYCC_GCC)	if (sock_errno() != NO_ERROR) {		APIRET rc;		ULONG  msglen;		char outbuf[100];		int myerrorcode = sock_errno(); 		/* Retrieve socket-related error message from MPTN.MSG file */		rc = DosGetMessage(NULL, 0, outbuf, sizeof(outbuf),				   myerrorcode - SOCBASEERR + 26,				   "mptn.msg",				   &msglen);		if (rc == NO_ERROR) {			PyObject *v; 			/* OS/2 doesn't guarantee a terminator */			outbuf[msglen] = '\0';			if (strlen(outbuf) > 0) {				/* If non-empty msg, trim CRLF */				char *lastc = &outbuf[ strlen(outbuf)-1 ];				while (lastc > outbuf &&				       isspace(Py_CHARMASK(*lastc))) {					/* Trim trailing whitespace (CRLF) */					*lastc-- = '\0';				}			}			v = Py_BuildValue("(is)", myerrorcode, outbuf);			if (v != NULL) {				PyErr_SetObject(socket_error, v);				Py_DECREF(v);			}			return NULL;		}	}#endif #if defined(RISCOS)	if (_inet_error.errnum != NULL) {		PyObject *v;		v = Py_BuildValue("(is)", errno, _inet_err());		if (v != NULL) {			PyErr_SetObject(socket_error, v);			Py_DECREF(v);		}		return NULL;	}#endif 	return PyErr_SetFromErrno(socket_error);}  static PyObject *set_herror(int h_error){	PyObject *v; #ifdef HAVE_HSTRERROR	v = Py_BuildValue("(is)", h_error, (char *)hstrerror(h_error));#else	v = Py_BuildValue("(is)", h_error, "host not found");#endif	if (v != NULL) {		PyErr_SetObject(socket_herror, v);		Py_DECREF(v);	} 	return NULL;}  static PyObject *set_gaierror(int error){	PyObject *v; #ifdef EAI_SYSTEM	/* EAI_SYSTEM is not available on Windows XP. */	if (error == EAI_SYSTEM)		return set_error();#endif #ifdef HAVE_GAI_STRERROR	v = Py_BuildValue("(is)", error, gai_strerror(error));#else	v = Py_BuildValue("(is)", error, "getaddrinfo failed");#endif	if (v != NULL) {		PyErr_SetObject(socket_gaierror, v);		Py_DECREF(v);	} 	return NULL;} #ifdef __VMS/* Function to send in segments */static intsendsegmented(int sock_fd, char *buf, int len, int flags){	int n = 0;	int remaining = len; 	while (remaining > 0) {		unsigned int segment; 		segment = (remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : remaining);		n = send(sock_fd, buf, segment, flags);		if (n < 0) {			return n;		}		remaining -= segment;		buf += segment;	} /* end while */ 	return len;}#endif /* Function to perform the setting of socket blocking mode   internally. block = (1 | 0). */static intinternal_setblocking(PySocketSockObject *s, int block){#ifndef RISCOS#ifndef MS_WINDOWS	int delay_flag;#endif#endif 	Py_BEGIN_ALLOW_THREADS#ifdef __BEOS__	block = !block;	setsockopt(s->sock_fd, SOL_SOCKET, SO_NONBLOCK,		   (void *)(&block), sizeof(int));#else#ifndef RISCOS#ifndef MS_WINDOWS#if defined(PYOS_OS2) && !defined(PYCC_GCC)	block = !block;	ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block));#elif defined(__VMS)	block = !block;	ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block);#else  /* !PYOS_OS2 && !__VMS */	delay_flag = fcntl(s->sock_fd, F_GETFL, 0);	if (block)		delay_flag &= (~O_NONBLOCK);	else		delay_flag |= O_NONBLOCK;	fcntl(s->sock_fd, F_SETFL, delay_flag);#endif /* !PYOS_OS2 */#else /* MS_WINDOWS */	block = !block;	ioctlsocket(s->sock_fd, FIONBIO, (u_long*)&block);#endif /* MS_WINDOWS */#else /* RISCOS */	block = !block;	socketioctl(s->sock_fd, FIONBIO, (u_long*)&block);#endif /* RISCOS */#endif /* __BEOS__ */	Py_END_ALLOW_THREADS 	/* Since these don't return anything */	return 1;} /* Do a select()/poll() on the socket, if necessary (sock_timeout > 0).   The argument writing indicates the direction.   This does not raise an exception; we'll let our caller do that   after they've reacquired the interpreter lock.   Returns 1 on timeout, -1 on error, 0 otherwise. */static intinternal_select(PySocketSockObject *s, int writing){	int n; 	/* Nothing to do unless we're in timeout mode (not non-blocking) */	if (s->sock_timeout <= 0.0)		return 0; 	/* Guard against closed socket */	if (s->sock_fd < 0)		return 0; 	/* Prefer poll, if available, since you can poll() any fd	 * which can't be done with select(). */#ifdef HAVE_POLL	{		struct pollfd pollfd;		int timeout; 		pollfd.fd = s->sock_fd;		pollfd.events = writing ? POLLOUT : POLLIN; 		/* s->sock_timeout is in seconds, timeout in ms */		timeout = (int)(s->sock_timeout * 1000 + 0.5); 		n = poll(&pollfd, 1, timeout);	}#else	{		/* Construct the arguments to select */		fd_set fds;		struct timeval tv;		tv.tv_sec = (int)s->sock_timeout;		tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);		FD_ZERO(&fds);		FD_SET(s->sock_fd, &fds); 		/* See if the socket is ready */		if (writing)			n = select(s->sock_fd+1, NULL, &fds, NULL, &tv);		else			n = select(s->sock_fd+1, &fds, NULL, NULL, &tv);	}#endif		if (n < 0)		return -1;	if (n == 0)		return 1;	return 0;} /* Initialize a new socket object. */ static double defaulttimeout = -1.0; /* Default timeout for new sockets */ PyMODINIT_FUNCinit_sockobject(PySocketSockObject *s,		SOCKET_T fd, int family, int type, int proto){#ifdef RISCOS	int block = 1;#endif	s->sock_fd = fd;	s->sock_family = family;	s->sock_type = type;	s->sock_proto = proto;	s->sock_timeout = defaulttimeout; 	s->errorhandler = &set_error; 	if (defaulttimeout >= 0.0)		internal_setblocking(s, 0); #ifdef RISCOS	if (taskwindow)		socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);#endif}  /* Create a new socket object.   This just creates the object and initializes it.   If the creation fails, return NULL and set an exception (implicit   in NEWOBJ()). */ static PySocketSockObject *new_sockobject(SOCKET_T fd, int family, int type, int proto){	PySocketSockObject *s;	s = (PySocketSockObject *)		PyType_GenericNew(&sock_type, NULL, NULL);	if (s != NULL)		init_sockobject(s, fd, family, type, proto);	return s;}  /* Lock to allow python interpreter to continue, but only allow one   thread to be in gethostbyname or getaddrinfo */#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)PyThread_type_lock netdb_lock;#endif  /* Convert a string specifying a host name or one of a few symbolic   names to a numeric IP address.  This usually calls gethostbyname()   to do the work; the names "" and "<broadcast>" are special.   Return the length (IPv4 should be 4 bytes), or negative if   an error occurred; then an exception is raised. */ static intsetipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af){	struct addrinfo hints, *res;	int error;	int d1, d2, d3, d4;	char ch; 	memset((void *) addr_ret, '\0', addr_ret_size);	if (name[0] == '\0') {		int siz;		memset(&hints, 0, sizeof(hints));		hints.ai_family = af;		hints.ai_socktype = SOCK_DGRAM;	/*dummy*/		hints.ai_flags = AI_PASSIVE;		Py_BEGIN_ALLOW_THREADS		ACQUIRE_GETADDRINFO_LOCK		error = getaddrinfo(NULL, "0", &hints, &res);		Py_END_ALLOW_THREADS		/* We assume that those thread-unsafe getaddrinfo() versions		   *are* safe regarding their return value, ie. that a		   subsequent call to getaddrinfo() does not destroy the		   outcome of the first call. */		RELEASE_GETADDRINFO_LOCK		if (error) {			set_gaierror(error);			return -1;		}		switch (res->ai_family) {		case AF_INET:			siz = 4;			break;#ifdef ENABLE_IPV6		case AF_INET6:			siz = 16;			break;#endif		default:			freeaddrinfo(res);			PyErr_SetString(socket_error,				"unsupported address family");			return -1;		}		if (res->ai_next) {			freeaddrinfo(res);			PyErr_SetString(socket_error,				"wildcard resolved to multiple address");			return -1;		}		if (res->ai_addrlen < addr_ret_size)			addr_ret_size = res->ai_addrlen;		memcpy(addr_ret, res->ai_addr, addr_ret_size);		freeaddrinfo(res);		return siz;	}	if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {		struct sockaddr_in *sin;		if (af != AF_INET && af != AF_UNSPEC) {			PyErr_SetString(socket_error,				"address family mismatched");			return -1;		}		sin = (struct sockaddr_in *)addr_ret;		memset((void *) sin, '\0', sizeof(*sin));		sin->sin_family = AF_INET;#ifdef HAVE_SOCKADDR_SA_LEN		sin->sin_len = sizeof(*sin);#endif		sin->sin_addr.s_addr = INADDR_BROADCAST;		return sizeof(sin->sin_addr);	}	if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&	    0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&	    0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {		struct sockaddr_in *sin;		sin = (struct sockaddr_in *)addr_ret;		sin->sin_addr.s_addr = htonl(			((long) d1 << 24) | ((long) d2 << 16) |			((long) d3 << 8) | ((long) d4 << 0));		sin->sin_family = AF_INET;#ifdef HAVE_SOCKADDR_SA_LEN		sin->sin_len = sizeof(*sin);#endif		return 4;	}	memset(&hints, 0, sizeof(hints));	hints.ai_family = af;	Py_BEGIN_ALLOW_THREADS	ACQUIRE_GETADDRINFO_LOCK	error = getaddrinfo(name, NULL, &hints, &res);#if defined(__digital__) && defined(__unix__)	if (error == EAI_NONAME && af == AF_UNSPEC) {		/* On Tru64 V5.1, numeric-to-addr conversion fails		   if no address family is given. Assume IPv4 for now.*/		hints.ai_family = AF_INET;		error = getaddrinfo(name, NULL, &hints, &res);	}#endif	Py_END_ALLOW_THREADS	RELEASE_GETADDRINFO_LOCK  /* see comment in setipaddr() */	if (error) {		set_gaierror(error);		return -1;	}	if (res->ai_addrlen < addr_ret_size)		addr_ret_size = res->ai_addrlen;	memcpy((char *) addr_ret, res->ai_addr, addr_ret_size);	freeaddrinfo(res);	switch (addr_ret->sa_family) {	case AF_INET:		return 4;#ifdef ENABLE_IPV6	case AF_INET6:		return 16;#endif	default:		PyErr_SetString(socket_error, "unknown address family");		return -1;	}}  /* Create a string object representing an IP address.   This is always a string of the form 'dd.dd.dd.dd' (with variable   size numbers). */ static PyObject *makeipaddr(struct sockaddr *addr, int addrlen){	char buf[NI_MAXHOST];	int error; 	error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,		NI_NUMERICHOST);	if (error) {		set_gaierror(error);		return NULL;	}	return PyString_FromString(buf);}  #ifdef USE_BLUETOOTH/* Convert a string representation of a Bluetooth address into a numeric   address.  Returns the length (6), or raises an exception and returns -1 if   an error occurred. */ static intsetbdaddr(char *name, bdaddr_t *bdaddr){	unsigned int b0, b1, b2, b3, b4, b5;	char ch;	int n; 	n = sscanf(name, "%X:%X:%X:%X:%X:%X%c",		   &b5, &b4, &b3, &b2, &b1, &b0, &ch);	if (n == 6 && (b0 | b1 | b2 | b3 | b4 | b5) < 256) {		bdaddr->b[0] = b0;		bdaddr->b[1] = b1;		bdaddr->b[2] = b2;		bdaddr->b[3] = b3;		bdaddr->b[4] = b4;		bdaddr->b[5] = b5;		return 6;	} else {		PyErr_SetString(socket_error, "bad bluetooth address");		return -1;	}} /* Create a string representation of the Bluetooth address.  This is always a   string of the form 'XX:XX:XX:XX:XX:XX' where XX is a two digit hexadecimal   value (zero padded if necessary). */ static PyObject *makebdaddr(bdaddr_t *bdaddr){	char buf[(6 * 2) + 5 + 1]; 

Lines 501–1000 of 5106. Previous lines