mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Patch #1516912: improve Modules support for OpenVMS.
This commit is contained in:
		
							parent
							
								
									4a5fbda66d
								
							
						
					
					
						commit
						2a30cd0ef0
					
				
					 9 changed files with 154 additions and 63 deletions
				
			
		| 
						 | 
				
			
			@ -108,6 +108,8 @@ Extension Modules
 | 
			
		|||
- Bug #1296433: parsing XML with a non-default encoding and
 | 
			
		||||
  a CharacterDataHandler could crash the interpreter in pyexpat.
 | 
			
		||||
 | 
			
		||||
- Patch #1516912: improve Modules support for OpenVMS.
 | 
			
		||||
 | 
			
		||||
Build
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1311,7 +1311,11 @@ BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
 | 
			
		|||
				break;
 | 
			
		||||
 | 
			
		||||
			case 'U':
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
				self->f_univ_newline = 0;
 | 
			
		||||
#else
 | 
			
		||||
				self->f_univ_newline = 1;
 | 
			
		||||
#endif
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,9 @@
 | 
			
		|||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
#include <openssl/des.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Module crypt */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +15,9 @@
 | 
			
		|||
static PyObject *crypt_crypt(PyObject *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	char *word, *salt; 
 | 
			
		||||
#ifndef __VMS
 | 
			
		||||
	extern char * crypt(const char *, const char *);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!PyArg_ParseTuple(args, "ss:crypt", &word, &salt)) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,10 @@
 | 
			
		|||
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef RTLD_LAZY
 | 
			
		||||
#define RTLD_LAZY 1
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -186,6 +190,24 @@ dl_open(PyObject *self, PyObject *args)
 | 
			
		|||
		PyErr_SetString(Dlerror, dlerror());
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
	/*   Under OpenVMS dlopen doesn't do any check, just save the name
 | 
			
		||||
	 * for later use, so we have to check if the file is readable,
 | 
			
		||||
	 * the name can be a logical or a file from SYS$SHARE.
 | 
			
		||||
	 */
 | 
			
		||||
	if (access(name, R_OK)) {
 | 
			
		||||
		char fname[strlen(name) + 20];
 | 
			
		||||
		strcpy(fname, "SYS$SHARE:");
 | 
			
		||||
		strcat(fname, name);
 | 
			
		||||
		strcat(fname, ".EXE");
 | 
			
		||||
		if (access(fname, R_OK)) {
 | 
			
		||||
			dlclose(handle);
 | 
			
		||||
			PyErr_SetString(Dlerror,
 | 
			
		||||
				"File not found or protection violation");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	return newdlobject(handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,6 +70,10 @@ extern "C" {
 | 
			
		|||
 | 
			
		||||
#if defined(__FreeBSD__)
 | 
			
		||||
#  include <ieeefp.h>
 | 
			
		||||
#elif defined(__VMS)
 | 
			
		||||
#define __NEW_STARLET
 | 
			
		||||
#include <starlet.h>
 | 
			
		||||
#include <ieeedef.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef WANT_SIGFPE_HANDLER
 | 
			
		||||
| 
						 | 
				
			
			@ -190,6 +194,19 @@ static void fpe_reset(Sigfunc *handler)
 | 
			
		|||
 | 
			
		||||
/*-- DEC ALPHA VMS --------------------------------------------------------*/
 | 
			
		||||
#elif defined(__ALPHA) && defined(__VMS)
 | 
			
		||||
	IEEE clrmsk;
 | 
			
		||||
	IEEE setmsk;
 | 
			
		||||
	clrmsk.ieee$q_flags =
 | 
			
		||||
		IEEE$M_TRAP_ENABLE_UNF |  IEEE$M_TRAP_ENABLE_INE |
 | 
			
		||||
		 IEEE$M_MAP_UMZ;
 | 
			
		||||
	setmsk.ieee$q_flags =
 | 
			
		||||
		IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE |
 | 
			
		||||
		IEEE$M_TRAP_ENABLE_OVF;
 | 
			
		||||
	sys$ieee_set_fp_control(&clrmsk, &setmsk, 0);
 | 
			
		||||
	PyOS_setsig(SIGFPE, handler);
 | 
			
		||||
 | 
			
		||||
/*-- HP IA64 VMS --------------------------------------------------------*/
 | 
			
		||||
#elif defined(__ia64) && defined(__VMS)
 | 
			
		||||
    PyOS_setsig(SIGFPE, handler);
 | 
			
		||||
 | 
			
		||||
/*-- Cray Unicos ----------------------------------------------------------*/
 | 
			
		||||
| 
						 | 
				
			
			@ -244,6 +261,14 @@ static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
 | 
			
		|||
#ifdef __FreeBSD__
 | 
			
		||||
    fpresetsticky(fpgetsticky());
 | 
			
		||||
    fpsetmask(0);
 | 
			
		||||
#elif defined(__VMS)
 | 
			
		||||
	IEEE clrmsk;
 | 
			
		||||
	 clrmsk.ieee$q_flags =
 | 
			
		||||
		IEEE$M_TRAP_ENABLE_UNF |  IEEE$M_TRAP_ENABLE_INE |
 | 
			
		||||
		IEEE$M_MAP_UMZ | IEEE$M_TRAP_ENABLE_INV |
 | 
			
		||||
		IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF |
 | 
			
		||||
		IEEE$M_INHERIT;
 | 
			
		||||
	sys$ieee_set_fp_control(&clrmsk, 0, 0);
 | 
			
		||||
#else
 | 
			
		||||
    fputs("Operation not implemented\n", stderr);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,19 +97,19 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
#ifndef VERSION
 | 
			
		||||
#if defined(__VMS)
 | 
			
		||||
#define VERSION "2_1"
 | 
			
		||||
#else
 | 
			
		||||
#define VERSION "2.1"
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef VPATH
 | 
			
		||||
#define VPATH "."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef PREFIX
 | 
			
		||||
#define PREFIX "/usr/local"
 | 
			
		||||
#  ifdef __VMS
 | 
			
		||||
#    define PREFIX ""
 | 
			
		||||
#  else
 | 
			
		||||
#    define PREFIX "/usr/local"
 | 
			
		||||
#  endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EXEC_PREFIX
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7882,6 +7882,42 @@ win32_urandom(PyObject *self, PyObject *args)
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
/* Use openssl random routine */
 | 
			
		||||
#include <openssl/rand.h>
 | 
			
		||||
PyDoc_STRVAR(vms_urandom__doc__,
 | 
			
		||||
"urandom(n) -> str\n\n\
 | 
			
		||||
Return a string of n random bytes suitable for cryptographic use.");
 | 
			
		||||
 | 
			
		||||
static PyObject*
 | 
			
		||||
vms_urandom(PyObject *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	int howMany;
 | 
			
		||||
	PyObject* result;
 | 
			
		||||
 | 
			
		||||
	/* Read arguments */
 | 
			
		||||
	if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
 | 
			
		||||
		return NULL;
 | 
			
		||||
	if (howMany < 0)
 | 
			
		||||
		return PyErr_Format(PyExc_ValueError,
 | 
			
		||||
				    "negative argument not allowed");
 | 
			
		||||
 | 
			
		||||
	/* Allocate bytes */
 | 
			
		||||
	result = PyString_FromStringAndSize(NULL, howMany);
 | 
			
		||||
	if (result != NULL) {
 | 
			
		||||
		/* Get random data */
 | 
			
		||||
		if (RAND_pseudo_bytes((unsigned char*)
 | 
			
		||||
				      PyString_AS_STRING(result),
 | 
			
		||||
				      howMany) < 0) {
 | 
			
		||||
			Py_DECREF(result);
 | 
			
		||||
			return PyErr_Format(PyExc_ValueError,
 | 
			
		||||
					    "RAND_pseudo_bytes");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static PyMethodDef posix_methods[] = {
 | 
			
		||||
	{"access",	posix_access, METH_VARARGS, posix_access__doc__},
 | 
			
		||||
#ifdef HAVE_TTYNAME
 | 
			
		||||
| 
						 | 
				
			
			@ -8174,6 +8210,9 @@ static PyMethodDef posix_methods[] = {
 | 
			
		|||
#endif
 | 
			
		||||
 #ifdef MS_WINDOWS
 | 
			
		||||
 	{"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
 | 
			
		||||
 #endif
 | 
			
		||||
 #ifdef __VMS
 | 
			
		||||
 	{"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
 | 
			
		||||
 #endif
 | 
			
		||||
	{NULL,		NULL}		 /* Sentinel */
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,14 +46,14 @@ extern void bzero(void *, int);
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MS_WINDOWS
 | 
			
		||||
#include <winsock.h>
 | 
			
		||||
#  include <winsock.h>
 | 
			
		||||
#else
 | 
			
		||||
#ifdef __BEOS__
 | 
			
		||||
#include <net/socket.h>
 | 
			
		||||
#define SOCKET int
 | 
			
		||||
#else
 | 
			
		||||
#define SOCKET int
 | 
			
		||||
#endif
 | 
			
		||||
#  define SOCKET int
 | 
			
		||||
#  ifdef __BEOS__
 | 
			
		||||
#    include <net/socket.h>
 | 
			
		||||
#  elif defined(__VMS)
 | 
			
		||||
#    include <socket.h>
 | 
			
		||||
#  endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -668,7 +668,7 @@ arguments; each contains the subset of the corresponding file descriptors\n\
 | 
			
		|||
that are ready.\n\
 | 
			
		||||
\n\
 | 
			
		||||
*** IMPORTANT NOTICE ***\n\
 | 
			
		||||
On Windows, only sockets are supported; on Unix, all file descriptors.");
 | 
			
		||||
On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
 | 
			
		||||
 | 
			
		||||
static PyMethodDef select_methods[] = {
 | 
			
		||||
    {"select",	select_select, METH_VARARGS, select_doc},
 | 
			
		||||
| 
						 | 
				
			
			@ -682,7 +682,7 @@ PyDoc_STRVAR(module_doc,
 | 
			
		|||
"This module supports asynchronous I/O on multiple file descriptors.\n\
 | 
			
		||||
\n\
 | 
			
		||||
*** IMPORTANT NOTICE ***\n\
 | 
			
		||||
On Windows, only sockets are supported; on Unix, all file descriptors.");
 | 
			
		||||
On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
 | 
			
		||||
 | 
			
		||||
PyMODINIT_FUNC
 | 
			
		||||
initselect(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -161,7 +161,8 @@ shutdown(how) -- shut down traffic in one or both directions\n\
 | 
			
		|||
   (this includes the getaddrinfo emulation) protect access with a lock. */
 | 
			
		||||
#if defined(WITH_THREAD) && (defined(__APPLE__) || \
 | 
			
		||||
    (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \
 | 
			
		||||
    defined(__OpenBSD__) || defined(__NetBSD__) || !defined(HAVE_GETADDRINFO))
 | 
			
		||||
    defined(__OpenBSD__) || defined(__NetBSD__) || \
 | 
			
		||||
    defined(__VMS) || !defined(HAVE_GETADDRINFO))
 | 
			
		||||
#define USE_GETADDRINFO_LOCK
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -186,15 +187,8 @@ shutdown(how) -- shut down traffic in one or both directions\n\
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__VMS)
 | 
			
		||||
#if ! defined(_SOCKADDR_LEN)
 | 
			
		||||
#   ifdef getaddrinfo
 | 
			
		||||
#      undef getaddrinfo
 | 
			
		||||
#   endif
 | 
			
		||||
#  include "TCPIP_IOCTL_ROUTINE"
 | 
			
		||||
#else
 | 
			
		||||
#  include <ioctl.h>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(PYOS_OS2)
 | 
			
		||||
# define  INCL_DOS
 | 
			
		||||
| 
						 | 
				
			
			@ -363,11 +357,6 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
 | 
			
		|||
#define SOCKETCLOSE close
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
/* TCP/IP Services for VMS uses a maximum send/revc buffer length of 65535 */
 | 
			
		||||
#define SEGMENT_SIZE 65535
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)
 | 
			
		||||
#define USE_BLUETOOTH 1
 | 
			
		||||
#if defined(__FreeBSD__)
 | 
			
		||||
| 
						 | 
				
			
			@ -386,6 +375,11 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
 | 
			
		|||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
/* TCP/IP Services for VMS uses a maximum send/recv buffer length */
 | 
			
		||||
#define SEGMENT_SIZE (32 * 1024 -1)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Constants for getnameinfo()
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -620,6 +614,30 @@ set_gaierror(int error)
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
/* Function to send in segments */
 | 
			
		||||
static int
 | 
			
		||||
sendsegmented(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 int
 | 
			
		||||
| 
						 | 
				
			
			@ -644,8 +662,8 @@ internal_setblocking(PySocketSockObject *s, int block)
 | 
			
		|||
	ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block));
 | 
			
		||||
#elif defined(__VMS)
 | 
			
		||||
	block = !block;
 | 
			
		||||
	ioctl(s->sock_fd, FIONBIO, (char *)&block);
 | 
			
		||||
#else  /* !PYOS_OS2 && !_VMS */
 | 
			
		||||
	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);
 | 
			
		||||
| 
						 | 
				
			
			@ -1725,6 +1743,8 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args)
 | 
			
		|||
		return PyInt_FromLong(flag);
 | 
			
		||||
	}
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
	/* socklen_t is unsigned so no negative test is needed,
 | 
			
		||||
	   test buflen == 0 is previously done */
 | 
			
		||||
	if (buflen > 1024) {
 | 
			
		||||
#else
 | 
			
		||||
	if (buflen <= 0 || buflen > 1024) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2498,9 +2518,6 @@ sock_send(PySocketSockObject *s, PyObject *args)
 | 
			
		|||
{
 | 
			
		||||
	char *buf;
 | 
			
		||||
	int len, n = 0, flags = 0, timeout;
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
	int send_length;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags))
 | 
			
		||||
		return NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -2508,11 +2525,14 @@ sock_send(PySocketSockObject *s, PyObject *args)
 | 
			
		|||
	if (!IS_SELECTABLE(s))
 | 
			
		||||
		return select_error();
 | 
			
		||||
 | 
			
		||||
#ifndef __VMS
 | 
			
		||||
	Py_BEGIN_ALLOW_THREADS
 | 
			
		||||
	timeout = internal_select(s, 1);
 | 
			
		||||
	if (!timeout)
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
		n = sendsegmented(s->sock_fd, buf, len, flags);
 | 
			
		||||
#else
 | 
			
		||||
		n = send(s->sock_fd, buf, len, flags);
 | 
			
		||||
#endif
 | 
			
		||||
	Py_END_ALLOW_THREADS
 | 
			
		||||
 | 
			
		||||
	if (timeout) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2521,36 +2541,6 @@ sock_send(PySocketSockObject *s, PyObject *args)
 | 
			
		|||
	}
 | 
			
		||||
	if (n < 0)
 | 
			
		||||
		return s->errorhandler();
 | 
			
		||||
#else
 | 
			
		||||
	/* Divide packet into smaller segments for	*/
 | 
			
		||||
	/*  TCP/IP Services for OpenVMS			*/
 | 
			
		||||
	send_length = len;
 | 
			
		||||
	while (send_length != 0) {
 | 
			
		||||
		unsigned int segment;
 | 
			
		||||
 | 
			
		||||
		segment = send_length / SEGMENT_SIZE;
 | 
			
		||||
		if (segment != 0) {
 | 
			
		||||
			segment = SEGMENT_SIZE;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			segment = send_length;
 | 
			
		||||
		}
 | 
			
		||||
		Py_BEGIN_ALLOW_THREADS
 | 
			
		||||
		timeout = internal_select(s, 1);
 | 
			
		||||
		if (!timeout)
 | 
			
		||||
			n = send(s->sock_fd, buf, segment, flags);
 | 
			
		||||
		Py_END_ALLOW_THREADS
 | 
			
		||||
		if (timeout) {
 | 
			
		||||
			PyErr_SetString(socket_timeout, "timed out");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (n < 0) {
 | 
			
		||||
			return s->errorhandler();
 | 
			
		||||
		}
 | 
			
		||||
		send_length -= segment;
 | 
			
		||||
		buf += segment;
 | 
			
		||||
	} /* end while */
 | 
			
		||||
#endif /* !__VMS */
 | 
			
		||||
	return PyInt_FromLong((long)n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2581,7 +2571,11 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
 | 
			
		|||
		timeout = internal_select(s, 1);
 | 
			
		||||
		if (timeout)
 | 
			
		||||
			break;
 | 
			
		||||
#ifdef __VMS
 | 
			
		||||
		n = sendsegmented(s->sock_fd, buf, len, flags);
 | 
			
		||||
#else
 | 
			
		||||
		n = send(s->sock_fd, buf, len, flags);
 | 
			
		||||
#endif
 | 
			
		||||
		if (n < 0)
 | 
			
		||||
			break;
 | 
			
		||||
		buf += n;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue