You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							67 lines
						
					
					
						
							2.2 KiB
						
					
					
				
			
		
		
	
	
							67 lines
						
					
					
						
							2.2 KiB
						
					
					
				| # -*- coding: utf-8 -
 | |
| #
 | |
| # This file is part of gunicorn released under the MIT license.
 | |
| # See the NOTICE for more information.
 | |
| 
 | |
| import errno
 | |
| import os
 | |
| import sys
 | |
| 
 | |
| try:
 | |
|     import ctypes
 | |
|     import ctypes.util
 | |
| except MemoryError:
 | |
|     # selinux execmem denial
 | |
|     # https://bugzilla.redhat.com/show_bug.cgi?id=488396
 | |
|     raise ImportError
 | |
| 
 | |
| SUPPORTED_PLATFORMS = (
 | |
|     'darwin',
 | |
|     'freebsd',
 | |
|     'dragonfly',
 | |
|     'linux2')
 | |
| 
 | |
| if sys.platform not in SUPPORTED_PLATFORMS:
 | |
|     raise ImportError("sendfile isn't supported on this platform")
 | |
| 
 | |
| _libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
 | |
| _sendfile = _libc.sendfile
 | |
| 
 | |
| 
 | |
| def sendfile(fdout, fdin, offset, nbytes):
 | |
|     if sys.platform == 'darwin':
 | |
|         _sendfile.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_uint64,
 | |
|                               ctypes.POINTER(ctypes.c_uint64), ctypes.c_voidp,
 | |
|                               ctypes.c_int]
 | |
|         _nbytes = ctypes.c_uint64(nbytes)
 | |
|         result = _sendfile(fdin, fdout, offset, _nbytes, None, 0)
 | |
| 
 | |
|         if result == -1:
 | |
|             e = ctypes.get_errno()
 | |
|             if e == errno.EAGAIN and _nbytes.value is not None:
 | |
|                 return _nbytes.value
 | |
|             raise OSError(e, os.strerror(e))
 | |
|         return _nbytes.value
 | |
|     elif sys.platform in ('freebsd', 'dragonfly',):
 | |
|         _sendfile.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_uint64,
 | |
|                               ctypes.c_uint64, ctypes.c_voidp,
 | |
|                               ctypes.POINTER(ctypes.c_uint64), ctypes.c_int]
 | |
|         _sbytes = ctypes.c_uint64()
 | |
|         result = _sendfile(fdin, fdout, offset, nbytes, None, _sbytes, 0)
 | |
|         if result == -1:
 | |
|             e = ctypes.get_errno()
 | |
|             if e == errno.EAGAIN and _sbytes.value is not None:
 | |
|                 return _sbytes.value
 | |
|             raise OSError(e, os.strerror(e))
 | |
|         return _sbytes.value
 | |
| 
 | |
|     else:
 | |
|         _sendfile.argtypes = [ctypes.c_int, ctypes.c_int,
 | |
|                 ctypes.POINTER(ctypes.c_uint64), ctypes.c_size_t]
 | |
| 
 | |
|         _offset = ctypes.c_uint64(offset)
 | |
|         sent = _sendfile(fdout, fdin, _offset, nbytes)
 | |
|         if sent == -1:
 | |
|             e = ctypes.get_errno()
 | |
|             raise OSError(e, os.strerror(e))
 | |
|         return sent
 | |
| 
 |